根据文件扩展名获取默认的巨型系统图标

解决了! 有关工作代码,请参阅编辑2。

基于此站点的代码和freundblase在同一站点中所做的评论,我有以下类来获取基于文件扩展名的jumbo默认图标:

// Original bad code removed 

我试图以下列方式使用该类:

 preview.ImageSource = IconManager.GetIcon(".pdf", true); 

其中预览是一个ImageBrush对象。

但我得到以下图像:

得到了图标

是的,我尝试使用pdf文件等注册文件类型。

怎么了?

TIA

编辑1:

我认为该图标用于未注册的文件类型。

如果我使用实际文件,我会得到一个FileNotFoundException。

编辑2:

在发布此问题之前,我使用ReSharper进行了代码清理。

我根据站点代码和freundblase评论重新上课,现在它正在运行!

我必须仔细分析ReSharper所做的更改。 代码清理从来没有给我任何问题。

对于后代,以下代码有效:

 public class IconManager { // Constants that we need in the function call private const int SHGFI_ICON = 0x100; private const int SHGFI_LARGEICON = 0x0; private const int SHGFI_SMALLICON = 0x1; private const int SHIL_EXTRALARGE = 0x2; private const int SHIL_JUMBO = 0x4; private const int WM_CLOSE = 0x0010; // This structure will contain information about the file public struct SHFILEINFO { // Handle to the icon representing the file public IntPtr hIcon; // Index of the icon within the image list public int iIcon; // Various attributes of the file public uint dwAttributes; // Path to the file [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string szDisplayName; // File type [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)] public string szTypeName; }; [DllImport("Kernel32.dll")] public static extern Boolean CloseHandle(IntPtr handle); private struct IMAGELISTDRAWPARAMS { public int cbSize; public IntPtr himl; public int i; public IntPtr hdcDst; public int x; public int y; public int cx; public int cy; public int xBitmap; // x offest from the upperleft of bitmap public int yBitmap; // y offset from the upperleft of bitmap public int rgbBk; public int rgbFg; public int fStyle; public int dwRop; public int fState; public int Frame; public int crEffect; } [DllImport("user32")] private static extern IntPtr SendMessage( IntPtr handle, int Msg, IntPtr wParam, IntPtr lParam ); [StructLayout(LayoutKind.Sequential)] private struct IMAGEINFO { private readonly IntPtr hbmImage; private readonly IntPtr hbmMask; private readonly int Unused1; private readonly int Unused2; private readonly RECT rcImage; } #region Private ImageList COM Interop (XP) [ComImport] [Guid("46EB5926-582E-4017-9FDF-E8998DAA0950")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] //helpstring("Image List"), private interface IImageList { [PreserveSig] int Add( IntPtr hbmImage, IntPtr hbmMask, ref int pi); [PreserveSig] int ReplaceIcon( int i, IntPtr hicon, ref int pi); [PreserveSig] int SetOverlayImage( int iImage, int iOverlay); [PreserveSig] int Replace( int i, IntPtr hbmImage, IntPtr hbmMask); [PreserveSig] int AddMasked( IntPtr hbmImage, int crMask, ref int pi); [PreserveSig] int Draw( ref IMAGELISTDRAWPARAMS pimldp); [PreserveSig] int Remove( int i); [PreserveSig] int GetIcon( int i, int flags, ref IntPtr picon); [PreserveSig] int GetImageInfo( int i, ref IMAGEINFO pImageInfo); [PreserveSig] int Copy( int iDst, IImageList punkSrc, int iSrc, int uFlags); [PreserveSig] int Merge( int i1, IImageList punk2, int i2, int dx, int dy, ref Guid riid, ref IntPtr ppv); [PreserveSig] int Clone( ref Guid riid, ref IntPtr ppv); [PreserveSig] int GetImageRect( int i, ref RECT prc); [PreserveSig] int GetIconSize( ref int cx, ref int cy); [PreserveSig] int SetIconSize( int cx, int cy); [PreserveSig] int GetImageCount( ref int pi); [PreserveSig] int SetImageCount( int uNewCount); [PreserveSig] int SetBkColor( int clrBk, ref int pclr); [PreserveSig] int GetBkColor( ref int pclr); [PreserveSig] int BeginDrag( int iTrack, int dxHotspot, int dyHotspot); [PreserveSig] int EndDrag(); [PreserveSig] int DragEnter( IntPtr hwndLock, int x, int y); [PreserveSig] int DragLeave( IntPtr hwndLock); [PreserveSig] int DragMove( int x, int y); [PreserveSig] int SetDragCursorImage( ref IImageList punk, int iDrag, int dxHotspot, int dyHotspot); [PreserveSig] int DragShowNolock( int fShow); [PreserveSig] int GetDragImage( ref POINT ppt, ref POINT pptHotspot, ref Guid riid, ref IntPtr ppv); [PreserveSig] int GetItemFlags( int i, ref int dwFlags); [PreserveSig] int GetOverlayImage( int iOverlay, ref int piIndex); }; #endregion /// /// SHGetImageList is not exported correctly in XP. See KB316931 /// http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q316931 /// Apparently (and hopefully) ordinal 727 isn't going to change. /// [DllImport("shell32.dll", EntryPoint = "#727")] private static extern int SHGetImageList( int iImageList, ref Guid riid, out IImageList ppv ); // The signature of SHGetFileInfo (located in Shell32.dll) [DllImport("Shell32.dll")] public static extern int SHGetFileInfo(string pszPath, int dwFileAttributes, ref SHFILEINFO psfi, int cbFileInfo, uint uFlags); [DllImport("Shell32.dll")] public static extern int SHGetFileInfo(IntPtr pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, int cbFileInfo, uint uFlags); [DllImport("shell32.dll", SetLastError = true)] private static extern int SHGetSpecialFolderLocation(IntPtr hwndOwner, Int32 nFolder, ref IntPtr ppidl); [DllImport("user32")] public static extern int DestroyIcon(IntPtr hIcon); public struct pair { public Icon icon { get; set; } public IntPtr iconHandleToDestroy { set; get; } } public static int DestroyIcon2(IntPtr hIcon) { return DestroyIcon(hIcon); } private static BitmapSource IconSource(Icon ic) { var ic2 = Imaging.CreateBitmapSourceFromHIcon(ic.Handle, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); ic2.Freeze(); return ic2; } public static BitmapSource IconPath(string FileName, bool small, bool checkDisk, bool addOverlay) { var shinfo = new SHFILEINFO(); const uint SHGFI_USEFILEATTRIBUTES = 0x000000010; const uint SHGFI_LINKOVERLAY = 0x000008000; uint flags; if (small) flags = SHGFI_ICON | SHGFI_SMALLICON; else flags = SHGFI_ICON | SHGFI_LARGEICON; if (!checkDisk) flags |= SHGFI_USEFILEATTRIBUTES; if (addOverlay) flags |= SHGFI_LINKOVERLAY; var res = SHGetFileInfo(FileName, 0, ref shinfo, Marshal.SizeOf(shinfo), flags); if (res == 0) throw (new FileNotFoundException()); var myIcon = Icon.FromHandle(shinfo.hIcon); var bs = IconSource(myIcon); myIcon.Dispose(); bs.Freeze(); // importantissimo se no fa memory leak DestroyIcon(shinfo.hIcon); CloseHandle(shinfo.hIcon); return bs; } public static BitmapSource GetLargeIcon(string FileName, bool jumbo, bool checkDisk) { var shinfo = new SHFILEINFO(); const uint SHGFI_USEFILEATTRIBUTES = 0x000000010; const uint SHGFI_SYSICONINDEX = 0x4000; const int FILE_ATTRIBUTE_NORMAL = 0x80; var flags = SHGFI_SYSICONINDEX; if (!checkDisk) // This does not seem to work. If I try it, a folder icon is always returned. flags |= SHGFI_USEFILEATTRIBUTES; var res = SHGetFileInfo(FileName, FILE_ATTRIBUTE_NORMAL, ref shinfo, Marshal.SizeOf(shinfo), flags); if (res == 0) throw (new FileNotFoundException()); var iconIndex = shinfo.iIcon; // Get the System IImageList object from the Shell: var iidImageList = new Guid("46EB5926-582E-4017-9FDF-E8998DAA0950"); IImageList iml; var size = jumbo ? SHIL_JUMBO : SHIL_EXTRALARGE; SHGetImageList(size, ref iidImageList, out iml); var hIcon = IntPtr.Zero; const int ILD_TRANSPARENT = 1; iml.GetIcon(iconIndex, ILD_TRANSPARENT, ref hIcon); var myIcon = Icon.FromHandle(hIcon); var bs = IconSource(myIcon); myIcon.Dispose(); bs.Freeze(); // very important to avoid memory leak DestroyIcon(hIcon); SendMessage(hIcon, WM_CLOSE, IntPtr.Zero, IntPtr.Zero); return bs; } [StructLayout(LayoutKind.Sequential)] public struct RECT { private readonly int _Left; private readonly int _Top; private readonly int _Right; private readonly int _Bottom; } [StructLayout(LayoutKind.Sequential)] public struct POINT { public int X; public int Y; public POINT(int x, int y) { X = x; Y = y; } public static implicit operator Point(POINT p) { return new Point(pX, pY); } public static implicit operator POINT(Point p) { return new POINT(pX, pY); } } }