在.Net(C#或VB:不关心)中,给定真实文件的文件路径字符串,FileInfo结构或FileSystemInfo结构,如何确定shell(资源管理器)使用的图标文件?
我目前没有计划将它用于任何事情,但是当我看到这个问题时,我对如何做到这一点感到好奇,我认为在SO上存档是有用的.
Imports System.Drawing Module Module1 Sub Main() Dim filePath As String = "C:\myfile.exe" Dim TheIcon As Icon = IconFromFilePath(filePath) If TheIcon IsNot Nothing Then ''#Save it to disk, or do whatever you want with it. Using stream As New System.IO.FileStream("c:\myfile.ico", IO.FileMode.CreateNew) TheIcon.Save(stream) End Using End If End Sub Public Function IconFromFilePath(filePath As String) As Icon Dim result As Icon = Nothing Try result = Icon.ExtractAssociatedIcon(filePath) Catch ''# swallow and return nothing. You could supply a default Icon here as well End Try Return result End Function End Module
请忽略每个人告诉您使用注册表!注册表不是API.您想要的API是带有SHGFI_ICON的SHGetFileInfo.您可以在此处获得P/Invoke签名:
http://www.pinvoke.net/default.aspx/shell32.SHGetFileInfo
你应该使用SHGetFileInfo.
在大多数情况下,Icon.ExtractAssociatedIcon与SHGetFileInfo的工作方式一样,但SHGetFileInfo可以使用UNC路径(例如"\\ ComputerName\SharedFolder \"之类的网络路径),而Icon.ExtractAssociatedIcon则不能.如果您需要或可能需要使用UNC路径,最好使用SHGetFileInfo而不是Icon.ExtractAssociatedIcon.
这是关于如何使用SHGetFileInfo的好CodeProject文章.
只不过是Stefan的答案的C#版本.
using System.Drawing; class Class1 { public static void Main() { var filePath = @"C:\myfile.exe"; var theIcon = IconFromFilePath(filePath); if (theIcon != null) { // Save it to disk, or do whatever you want with it. using (var stream = new System.IO.FileStream(@"c:\myfile.ico", System.IO.FileMode.CreateNew)) { theIcon.Save(stream); } } } public static Icon IconFromFilePath(string filePath) { var result = (Icon)null; try { result = Icon.ExtractAssociatedIcon(filePath); } catch (System.Exception) { // swallow and return nothing. You could supply a default Icon here as well } return result; } }