mirror of
https://github.com/babalae/better-genshin-impact.git
synced 2026-04-13 15:43:35 +08:00
119 lines
3.9 KiB
C#
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;
|
|
}
|
|
}
|