我正在使用SHFileInfo
检索文件和文件夹的系统图标,但是我发现特殊文件夹没有返回正确的文件夹图标。
例如,桌面文件夹将返回与常规文件夹相同的文件夹图标而不是桌面图标,并且MyComputer图标看起来像旧的Windows 98图标,而不是我期望的Windows 7 MyComputer图标。
为什么我的特殊文件夹图标错误,如何使用SHFileInfo
检索特殊文件夹的正确系统图标?
我的原始代码来自this codeproject article,但它已被修改了一下。执行的实际代码仍然非常相似,如下所示:
public static System.Drawing.Icon GetFolderIcon(string folderPath, IconSize size, FolderType folderType)
{
try
{
// Need to add size check, although errors generated at present!
Int64 flags = WinApi.SHGFI_ICON | WinApi.SHGFI_USEFILEATTRIBUTES;
if (FolderType.Open == folderType)
flags |= WinApi.SHGFI_OPENICON;
if (IconSize.Small == size)
flags |= WinApi.SHGFI_SMALLICON;
else
flags |= WinApi.SHGFI_LARGEICON;
// Get the folder icon
WinApi.SHFILEINFO shfi = new WinApi.SHFILEINFO();
WinApi.SHGetFileInfo(folderPath,
WinApi.FILE_ATTRIBUTE_DIRECTORY,
ref shfi,
(Int32)System.Runtime.InteropServices.Marshal.SizeOf(shfi),
flags);
if (shfi.hIcon == IntPtr.Zero)
return null;
// Now clone the icon, so that it can be successfully stored in an ImageList
System.Drawing.Icon icon = (System.Drawing.Icon)System.Drawing.Icon.FromHandle(shfi.hIcon).Clone();
WinApi.DestroyIcon(shfi.hIcon); // Cleanup
return icon;
}
catch (Exception ex)
{
// Log Error
}
return null;
}
调用它看起来像这样:
var icon = IconUtil.GetFolderIcon(
Environment.GetFolderPath(Environment.SpecialFolder.Desktop),
IconUtil.IconSize.Large, IconUtil.FolderType.Closed);
我得到的图标看起来像这样
而不是
答案 0 :(得分:6)
根据MSDN,SHGFI_USEFILEATTRIBUTES
标志:
表示该函数不应尝试访问该文件 由pszPath指定。相反,它应该像指定文件一样 通过pszPath存在,并在dwFileAttributes中传递文件属性。
我认为Raymond Chen's comment提供了一个更容易理解的解释:
您通过了
SHGFI_USEFILEATTRIBUTES
,这意味着“忽略文件的内容 实际上是,只是假装这是我告诉你的。“而你的 假装文件属性为FILE_ATTRIBUTE_DIRECTORY
,这意味着“只是 一个简单无聊的目录。“
因此,为了解决我的问题,我只需要在获取特定于文件夹的图标时删除SHGFI_USEFILEATTRIBUTES
标记。
Eric Brown's comment还提供了使用PIDL执行此操作的有用替代方法。可以找到代码的示例here。