c# - 为什么在使用 SHFileInfo 时出现错误的 SpecialFolder 图标?

标签 c# winapi

我正在使用 SHFileInfo 检索文件和文件夹的系统图标,但是我发现特殊文件夹没有返回正确的文件夹图标。

例如,桌面文件夹将返回与常规文件夹相同的文件夹图标,而不是桌面图标,我的电脑图标看起来像旧的 Windows 98 图标,而不是我预期的 Windows 7 我的电脑图标。

为什么我得到的特殊文件夹的图标是错误的?如何使用 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);

我得到的图标看起来像这样

enter image description here

而不是这个

enter image description here

enter image description here

enter image description here

最佳答案

根据 MSDN , SHGFI_USEFILEATTRIBUTES 标志:

Indicates that the function should not attempt to access the file specified by pszPath. Rather, it should act as if the file specified by pszPath exists with the file attributes passed in dwFileAttributes.

我以为Raymond Chen's comment不过提供了一个更容易理解的解释:

You passed SHGFI_USEFILEATTRIBUTES which means "Ignore what the file actually is and just pretend that it is what I tell you." And your pretend file attributes are FILE_ATTRIBUTE_DIRECTORY which means "just a plain boring directory."

因此,为了解决我的问题,我只需要在想要获取特定于文件夹的图标时删除 SHGFI_USEFILEATTRIBUTES 标志即可。

Eric Brown's comment还提供了一种使用 PIDL 执行此操作的有用替代方法。可以找到一个代码示例 here .

关于c# - 为什么在使用 SHFileInfo 时出现错误的 SpecialFolder 图标?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18746318/

相关文章:

c# - 使用 Microsoft Cognitive 进行实时说话人识别

c# - X-Frame-Options:ALLOW-FROM HTTP 和 HTTPS

c# - 将二维数组传递给函数时,Mono Develop 调试器崩溃

c - 如果在注册窗口类时已经提供了 hInstance,为什么 CreateWindow() 将 hInstance 作为参数?

c - 将字符串发送到另一个应用程序的最简单方法是什么? (赢得API)

c - GetDiskFreeSpace 函数返回 ERROR_INVALID_FUNCTION

winapi - C++/CLI : Use LoadLibrary + GetProcAddress with an exe

c++ - 我怎么知道一个目录是VB6中的回收站?

c# - 将 postgres box 转换为 .Net NpgsqlBox

c# - 我可以在 C# 中解析带有 'GetServices(typeof(IEmpty<>))' 的开放类型泛型服务集合吗?