2011-05-15 28 views
12

我正在制作一个类似于应用程序的浏览器来浏览存储在我的计算机上的文件。我的应用程序将在“图标”视图。问题是:如何显示exe文件的图标?获取程序图标

回答

19

有几种方法可以做到这一点。最简单的可能是添加引用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

+6

OMG存在。 – 2011-05-15 13:22:10

+0

此功能是否存在于WPF? – Cobold 2011-05-15 13:28:26

+0

哪个功能? Icon.ExtractAssociatedIcon?它不是WPF本身的一部分,但它在.NET Framework中。 System.Drawing只是GDI的包装 – 2011-05-15 13:33:35

相关问题