Files
better-genshin-impact/Build/MicaSetup/Natives/Shell/Dialogs/KnownFolders/KnownFolderHelper.cs

119 lines
3.9 KiB
C#

using System;
using System.Diagnostics;
namespace MicaSetup.Shell.Dialogs;
public static class KnownFolderHelper
{
public static IKnownFolder FromCanonicalName(string canonicalName)
{
var knownFolderManager = (IKnownFolderManager)new KnownFolderManagerClass();
knownFolderManager.GetFolderByName(canonicalName, out var knownFolderNative);
var kf = KnownFolderHelper.GetKnownFolder(knownFolderNative);
return kf ?? throw new ArgumentException(LocalizedMessages.ShellInvalidCanonicalName, "canonicalName");
}
public static IKnownFolder FromKnownFolderId(Guid knownFolderId)
{
var knownFolderManager = new KnownFolderManagerClass();
var hr = knownFolderManager.GetFolder(knownFolderId, out var knownFolderNative);
if (hr != HResult.Ok) { throw new ShellException(hr); }
var kf = GetKnownFolder(knownFolderNative);
return kf ?? throw new ArgumentException(LocalizedMessages.KnownFolderInvalidGuid, "knownFolderId");
}
public static IKnownFolder FromParsingName(string parsingName)
{
if (parsingName == null)
{
throw new ArgumentNullException("parsingName");
}
nint pidl = 0;
nint pidl2 = 0;
try
{
pidl = ShellHelper.PidlFromParsingName(parsingName);
if (pidl == 0)
{
throw new ArgumentException(LocalizedMessages.KnownFolderParsingName, "parsingName");
}
var knownFolderNative = KnownFolderHelper.FromPIDL(pidl);
if (knownFolderNative != null)
{
var kf = KnownFolderHelper.GetKnownFolder(knownFolderNative);
return kf ?? throw new ArgumentException(LocalizedMessages.KnownFolderParsingName, "parsingName");
}
pidl2 = ShellHelper.PidlFromParsingName(parsingName.PadRight(1, '\0'));
if (pidl2 == 0)
{
throw new ArgumentException(LocalizedMessages.KnownFolderParsingName, "parsingName");
}
var kf2 = KnownFolderHelper.GetKnownFolder(KnownFolderHelper.FromPIDL(pidl));
return kf2 ?? throw new ArgumentException(LocalizedMessages.KnownFolderParsingName, "parsingName");
}
finally
{
Shell32.ILFree(pidl);
Shell32.ILFree(pidl2);
}
}
public static IKnownFolder FromPath(string path) => KnownFolderHelper.FromParsingName(path);
internal static IKnownFolder FromKnownFolderIdInternal(Guid knownFolderId)
{
var knownFolderManager = (IKnownFolderManager)new KnownFolderManagerClass();
var hr = knownFolderManager.GetFolder(knownFolderId, out var knownFolderNative);
return (hr == HResult.Ok) ? GetKnownFolder(knownFolderNative) : null!;
}
internal static IKnownFolderNative FromPIDL(nint pidl)
{
var knownFolderManager = new KnownFolderManagerClass();
var hr = knownFolderManager.FindFolderFromIDList(pidl, out var knownFolder);
return (hr == HResult.Ok) ? knownFolder : null!;
}
private static IKnownFolder GetKnownFolder(IKnownFolderNative knownFolderNative)
{
Debug.Assert(knownFolderNative != null, "Native IKnownFolder should not be null.");
var guid = new Guid(ShellIIDGuid.IShellItem2);
HResult hr = knownFolderNative!.GetShellItem(0, ref guid, out var shellItem);
if (!CoreErrorHelper.Succeeded(hr)) { return null!; }
var isFileSystem = false;
if (shellItem != null)
{
shellItem.GetAttributes(ShellFileGetAttributesOptions.FileSystem, out var sfgao);
isFileSystem = (sfgao & ShellFileGetAttributesOptions.FileSystem) != 0;
}
if (isFileSystem)
{
var kf = new FileSystemKnownFolder(knownFolderNative);
return kf;
}
var knownFsFolder = new NonFileSystemKnownFolder(knownFolderNative);
return knownFsFolder;
}
}