Использование Win32 API для получения значков файлов / папок в C# - это тривиальный процесс, который был задокументирован бесчисленное количество раз, начиная с самого начала. Net.
Каждый документированный Решение - это всего лишь вариант того же подхода: P / Invoking SHGetFileInfo (), передавая соответствующие атрибуты / флаги.
Я занимаюсь Windows 10, который, я полагаю, использует Shell32.dll v6.1 - - та же версия, которая поставлялась с Windows 7, и последняя, выпущенная в соответствии с документацией Microsoft . Версия, отображаемая на вкладке «Сведения» окна «Свойства» в проводнике моей системы разработки для C: \ Windows \ system32 \ shell32.dll, - «10.0.18362.719».
Моя цель - использовать этот подход сгенерировать иконку «generi c» FOLDER. Мне нужно, чтобы он был МАЛЫЙ (против большого) и находился в состоянии ОТКРЫТО (против закрытого).
Что я заметил, так это то, что если кто-то запрашивает небольшой общий значок папки c из SHGetFileInfo (), результат всегда появляется в закрытом состоянии.
И наоборот, если кто-то запрашивает большой общий значок папки c из SHGetFileInfo (), результат всегда появляется в открытом состоянии.
Следующий код представляет собой простейшую возможную демонстрацию этого. Для большого значка измените флаг SmallIcon на LargeIcon. Для закрытого значка удалите флаг OpenIcon.
public static Icon GetMyIcon()
{
var flags = (uint)(ShellAttribute.Icon | ShellAttribute.SmallIcon | ShellAttribute.OpenIcon);
var fileInfo = new ShellFileInfo();
var size = (uint)Marshal.SizeOf(fileInfo);
var result = Interop.SHGetFileInfo(string.Empty, (uint)FileAttribute.Directory, out fileInfo, size, flags);
if (result == IntPtr.Zero)
throw Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error());
try
{
return (Icon)Icon.FromHandle(fileInfo.hIcon).Clone();
}
finally
{
Interop.DestroyIcon(fileInfo.hIcon);
}
}
С методами взаимодействия, объявленными следующим образом:
public static class Interop
{
[DllImport("shell32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SHGetFileInfo(string path,
uint attributes,
out ShellFileInfo fileInfo,
uint size,
uint flags);
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DestroyIcon(IntPtr pointer);
}
Существует ли какая-то черная магия c, необходимая для получения обобщенного c значок папки, который является либо маленьким и открытым, либо большим и закрытым?
Я также могу использовать Windows API Code Pack в моем проекте, поэтому, если есть возможность обойти Win32 API и достичь желаемого результата, используя только эту библиотеку, это удовлетворит.
ОБНОВЛЕНИЕ: По предложению Иана Х я попытался использовать API SHGetStockIconInfo, но результат, к сожалению, был таким же:
private static Icon GetStockIcon()
{
SHSTOCKICONINFO sii = new SHSTOCKICONINFO();
sii.cbSize = (UInt32)Marshal.SizeOf(typeof(SHSTOCKICONINFO));
Marshal.ThrowExceptionForHR(SHGetStockIconInfo(SHSTOCKICONID.SIID_FOLDEROPEN,
SHGSI.SHGSI_ICON | SHGSI.SHGSI_SMALLICON,
ref sii));
return Icon.FromHandle(sii.hIcon);
}