2

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

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

为什么我得到了错误的特殊文件夹图标,如何使用 检索特殊文件夹的正确系统图标SHFileInfo

我的原始代码来自这个 codeproject 文章,但是它被修改了一点。不过,实际执行的代码仍然非常相似,如下所示:

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);

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

在此处输入图像描述

而不是这个

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

4

1 回答 1

6

根据MSDNSHGFI_USEFILEATTRIBUTES标志:

指示该函数不应尝试访问由 pszPath 指定的文件。相反,它应该表现得好像由 pszPath 指定的文件存在,并带有在 dwFileAttributes 中传递的文件属性。

我认为Raymond Chen 的评论提供了一个更容易理解的解释:

你通过了SHGFI_USEFILEATTRIBUTES这意味着“忽略文件实际上是什么,只是假装它是我告诉你的。” 而你的伪装文件属性FILE_ATTRIBUTE_DIRECTORY意味着“只是一个普通的无聊目录”。

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

Eric Brown 的评论还提供了一种使用 PIDL 的有用替代方法。可以在这里找到一个代码示例。

于 2013-09-11T18:18:06.113 回答