wpf - 获取程序图标

标签 wpf vb.net

我正在制作一个像浏览器一样的应用程序来浏览存储在我电脑上的文件。我的应用程序将处于“图标” View 中。问题是:如何显示exe文件的图标?

最佳答案

有几种方法可以做到这一点。最简单的可能是添加对 System.Drawing 的引用并利用 Icon.ExtractAssociatedIcon方法:

public static ImageSource GetIcon(string fileName)
{
    Icon icon = Icon.ExtractAssociatedIcon(fileName);
    return System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(
                icon.Handle, 
                new Int32Rect(icon.Width, icon.Height),
                BitmapSizeOptions.FromEmptyOptions());
}

另一种选择,如果您不想使用 System.Drawing , 是从SHGetFileInfo 中获取图标API。这更困难,但也更灵活;例如,您可以根据扩展名获取不存在的文件的图标(当然对于可执行文件来说它不是很有用,因为它会返回可执行文件的默认图标)。

public static ImageSource GetIcon(string path, bool smallIcon, bool isDirectory)
{
    // SHGFI_USEFILEATTRIBUTES takes the file name and attributes into account if it doesn't exist
    uint flags = SHGFI_ICON | SHGFI_USEFILEATTRIBUTES;
    if (smallIcon)
        flags |= SHGFI_SMALLICON;

    uint attributes = FILE_ATTRIBUTE_NORMAL;
    if (isDirectory)
        attributes |= FILE_ATTRIBUTE_DIRECTORY;

    SHFILEINFO shfi;
    if (0 != SHGetFileInfo(
                path,
                attributes,
                out shfi,
                (uint)Marshal.SizeOf(typeof(SHFILEINFO)),
                flags))
    {
        return System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(
                    shfi.hIcon, 
                    Int32Rect.Empty,
                    BitmapSizeOptions.FromEmptyOptions());
    }
    return null;
}

[StructLayout(LayoutKind.Sequential)]
private struct SHFILEINFO
{
    public IntPtr hIcon;
    public int iIcon;
    public uint dwAttributes;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
    public string szDisplayName;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
    public string szTypeName;
}

    [DllImport("shell32")]
    private static extern int SHGetFileInfo(string pszPath, uint dwFileAttributes, out SHFILEINFO psfi, uint cbFileInfo, uint flags);

private const uint FILE_ATTRIBUTE_READONLY = 0x00000001;
private const uint FILE_ATTRIBUTE_HIDDEN = 0x00000002;
private const uint FILE_ATTRIBUTE_SYSTEM = 0x00000004;
private const uint FILE_ATTRIBUTE_DIRECTORY = 0x00000010;
private const uint FILE_ATTRIBUTE_ARCHIVE = 0x00000020;
private const uint FILE_ATTRIBUTE_DEVICE = 0x00000040;
private const uint FILE_ATTRIBUTE_NORMAL = 0x00000080;
private const uint FILE_ATTRIBUTE_TEMPORARY = 0x00000100;
private const uint FILE_ATTRIBUTE_SPARSE_FILE = 0x00000200;
private const uint FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400;
private const uint FILE_ATTRIBUTE_COMPRESSED = 0x00000800;
private const uint FILE_ATTRIBUTE_OFFLINE = 0x00001000;
private const uint FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x00002000;
private const uint FILE_ATTRIBUTE_ENCRYPTED = 0x00004000;
private const uint FILE_ATTRIBUTE_VIRTUAL = 0x00010000;

private const uint SHGFI_ICON = 0x000000100;     // get icon
private const uint SHGFI_DISPLAYNAME = 0x000000200;     // get display name
private const uint SHGFI_TYPENAME = 0x000000400;     // get type name
private const uint SHGFI_ATTRIBUTES = 0x000000800;     // get attributes
private const uint SHGFI_ICONLOCATION = 0x000001000;     // get icon location
private const uint SHGFI_EXETYPE = 0x000002000;     // return exe type
private const uint SHGFI_SYSICONINDEX = 0x000004000;     // get system icon index
private const uint SHGFI_LINKOVERLAY = 0x000008000;     // put a link overlay on icon
private const uint SHGFI_SELECTED = 0x000010000;     // show icon in selected state
private const uint SHGFI_ATTR_SPECIFIED = 0x000020000;     // get only specified attributes
private const uint SHGFI_LARGEICON = 0x000000000;     // get large icon
private const uint SHGFI_SMALLICON = 0x000000001;     // get small icon
private const uint SHGFI_OPENICON = 0x000000002;     // get open icon
private const uint SHGFI_SHELLICONSIZE = 0x000000004;     // get shell size icon
private const uint SHGFI_PIDL = 0x000000008;     // pszPath is a pidl
private const uint SHGFI_USEFILEATTRIBUTES = 0x000000010;     // use passed dwFileAttribute

这种方法的另一个优点是它还可以获得目录的图标(参见代码中的最后编辑),这在 Icon.ExtractAssociatedIcon 中是不可能的。

关于wpf - 获取程序图标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6008600/

相关文章:

.net - TableAdapter 向导未生成 INSERT 方法 - UPDATE 和 DELETE 正常

vb.net - 枚举成员列表以数字开头

c# - SqlConnection 和 SqlConnectionStringBuilder 的区别

c# - 动态加载用户控件的订阅事件

c# - 未显示单例 ViewModel 的 View

wpf - MVVM 中 ViewModel 的真正目的是什么?

.net - 关于改变与 Crystal 报表的连接

c# - 转换为计算/绝对位置

c# - 文本框内容垂直拉伸(stretch)到可用大小

WPF 应用程序在 Dispatcher 上调用时死锁