C# 如何获取 Windows 资源管理器显示的文件类型图标?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/108005/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I get the filetype icon that Windows Explorer shows?
提问by Paul Beesley
first question here. I'm developing a program in C# (.NET 3.5) that displays files in a listview. I'd like to have the "large icon" view display the icon that Windows Explorer uses for that filetype, otherwise I'll have to use some existing code like this:
第一个问题在这里。我正在用 C# (.NET 3.5) 开发一个在列表视图中显示文件的程序。我想让“大图标”视图显示 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;
}
}
The above code returns an integer that is used to select an icon from an imagelist that I populated with some common icons. It works fine but I'd need to add every extension under the sun! Is there a better way? Thanks!
上面的代码返回一个整数,用于从我填充了一些常用图标的图像列表中选择一个图标。它工作正常,但我需要在阳光下添加每个扩展!有没有更好的办法?谢谢!
采纳答案by Martin Plante
You might find the use of Icon.ExtractAssociatedIcona much simpler (an managed) approach than using SHGetFileInfo. But watch out: two files with the same extension may have different icons.
您可能会发现使用Icon.ExtractAssociatedIcon比使用 SHGetFileInfo 更简单(托管)方法。但请注意:具有相同扩展名的两个文件可能具有不同的图标。
回答by blowdart
The file icons are held in the registry. It's a little convoluted but it works something like
文件图标保存在注册表中。这有点令人费解,但它的工作原理类似于
- Take the file extension and lookup the registry entry for it, for example .DOC Get the default value for that registry setting, "Word.Document.8"
- Now lookup that value in the registry.
- Look at the default value for the "Default Icon" registry key, in this case, C:\Windows\Installer{91120000-002E-0000-0000-0000000FF1CE}\wordicon.exe,1
- Open the file and get the icon, using any number after the comma as the indexer.
- 获取文件扩展名并为其查找注册表项,例如 .DOC 获取该注册表设置的默认值“Word.Document.8”
- 现在在注册表中查找该值。
- 查看“默认图标”注册表项的默认值,在本例中为 C:\Windows\Installer{91120000-002E-0000-0000-0000000FF1CE}\wordicon.exe,1
- 打开文件并获取图标,使用逗号后的任意数字作为索引器。
There is some sample code at on CodeProject
CodeProject上有一些示例代码
回答by eric
I used the following solution from codeproject in one of recent my projects
我在最近的一个项目中使用了来自 codeproject 的以下解决方案
Obtaining (and managing) file and folder icons using SHGetFileInfo in C#
在 C# 中使用 SHGetFileInfo 获取(和管理)文件和文件夹图标
The demo project is pretty self explanatory but basically you just have to do:
演示项目是不言自明的,但基本上你只需要做:
private System.Windows.Forms.ListView FileView;
private ImageList _SmallImageList = new ImageList();
private ImageList _LargeImageList = new ImageList();
private IconListManager _IconListManager;
in the constructor:
在构造函数中:
_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;
and then finally when you create the ListViewItem:
然后最后当你创建 ListViewItem 时:
ListViewItem item = new ListViewItem(file.Name, _IconListManager.AddFileIcon(file.FullName));
Worked great for me.
对我很有用。
回答by dummy
Edit: Hereis a version without PInvoke.
编辑:这是一个没有 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;
}