如何获取Windows资源管理器显示的文件类型图标?

第一个问题在这里 我正在开发一个用C#(.NET 3.5)编写的程序,它在listview中显示文件。 我想让“大图标”视图显示Windows资源管理器用于该文件类型的图标,否则我将不得不使用这样的现有代码:

private int getFileTypeIconIndex(string fileName) { string fileLocation = Application.StartupPath + "\\Quarantine\\" + fileName; FileInfo fi = new FileInfo(fileLocation); switch (fi.Extension) { case ".pdf": return 1; case ".doc": case ".docx": case ".docm": case ".dotx":case ".dotm": case ".dot":case ".wpd": case ".wps": return 2; default: return 0; } } 

上面的代码返回一个整数,用于从我填充了一些常用图标的图像列表中选择一个图标。 它工作正常,但我需要在阳光下添加每个扩展! 有没有更好的办法? 谢谢!

您可能会发现使用Icon.ExtractAssociatedIcon比使用SHGetFileInfo更简单(一种托管)方法。 但请注意:具有相同扩展名的两个文件可能具有不同的图标。

文件图标保存在注册表中。 这有点令人费解,但它有点像

  • 获取文件扩展名并查找其注册表项,例如.DOC获取该注册表设置的默认值“Word.Document.8”
  • 现在在注册表中查找该值。
  • 查看“默认图标”注册表项的默认值,在本例中为C:\ Windows \ Installer {91120000-002E-0000-0000-0000000FF1CE} \ wordicon.exe,1
  • 打开文件并使用逗号之后的任何数字作为索引器获取图标。

CodeProject上有一些示例代码

我在最近的一个项目中使用了codeproject中的以下解决方案

在C#中使用SHGetFileInfo获取(和管理)文件和文件夹图标

演示项目非常自我解释,但基本上你只需要做:

 private System.Windows.Forms.ListView FileView; private ImageList _SmallImageList = new ImageList(); private ImageList _LargeImageList = new ImageList(); private IconListManager _IconListManager; 

在构造函数中:

 _SmallImageList.ColorDepth = ColorDepth.Depth32Bit; _LargeImageList.ColorDepth = ColorDepth.Depth32Bit; _SmallImageList.ImageSize = new System.Drawing.Size(16, 16); _LargeImageList.ImageSize = new System.Drawing.Size(32, 32); _IconListManager = new IconListManager(_SmallImageList, _LargeImageList); FileView.SmallImageList = _SmallImageList; FileView.LargeImageList = _LargeImageList; 

然后在创建ListViewItem时最后:

 ListViewItem item = new ListViewItem(file.Name, _IconListManager.AddFileIcon(file.FullName)); 

对我来说很棒。

编辑: 这是没有PInvoke的版本。

 [StructLayout(LayoutKind.Sequential)] public struct SHFILEINFO { public IntPtr hIcon; public IntPtr iIcon; public uint dwAttributes; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string szDisplayName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)] public string szTypeName; }; public const uint SHGFI_ICON = 0x100; public const uint SHGFI_LARGEICON = 0x0; // 'Large icon public const uint SHGFI_SMALLICON = 0x1; // 'Small icon [DllImport("shell32.dll")] public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags); [DllImport("User32.dll")] public static extern int DestroyIcon(IntPtr hIcon); public static System.Drawing.Icon GetSystemIcon(string sFilename) { //Use this to get the small Icon IntPtr hImgSmall; //the handle to the system image list //IntPtr hImgLarge; //the handle to the system image list APIFuncs.SHFILEINFO shinfo = new APIFuncs.SHFILEINFO(); hImgSmall = APIFuncs.SHGetFileInfo(sFilename, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), APIFuncs.SHGFI_ICON | APIFuncs.SHGFI_SMALLICON); //Use this to get the large Icon //hImgLarge = SHGetFileInfo(fName, 0, // ref shinfo, (uint)Marshal.SizeOf(shinfo), // Win32.SHGFI_ICON | Win32.SHGFI_LARGEICON); //The icon is returned in the hIcon member of the shinfo struct System.Drawing.Icon myIcon = (System.Drawing.Icon)System.Drawing.Icon.FromHandle(shinfo.hIcon).Clone(); DestroyIcon(shinfo.hIcon); // Cleanup return myIcon; }