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