首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 調用 Shell API 獲取文件圖標完整指南:SHGetFileInfo 實戰

     編輯:關於C語言

核心 API:SHGetFileInfo

通過 P/Invoke 調用 shell32.dll 獲取文件圖標、顯示名、類型名等信息。

必要結構體與枚舉定義

SHFILEINFO 結構


[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public 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;
}

標誌枚舉


[Flags]
public enum SHGFI : uint
{
    ICON = 0x100, DISPLAYNAME = 0x200, TYPENAME = 0x400,
    ATTRIBUTES = 0x800, ICONLOCATION = 0x1000,
    EXETYPE = 0x2000, SYSICONINDEX = 0x4000,
    LINKOVERLAY = 0x8000, SELECTED = 0x10000,
    ATTR_SPECIFIED = 0x20000, LARGEICON = 0x0,
    SMALLICON = 0x1, OPENICON = 0x2, SHELLICONSIZE = 0x4,
    PIDL = 0x8, USEFILEATTRIBUTES = 0x10,
    ADDOVERLAYS = 0x20, OVERLAYINDEX = 0x40
}

P/Invoke 簽名


[DllImport("shell32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SHGetFileInfo(
    string pszPath, uint dwFileAttributes,
    ref SHFILEINFO psfi, uint cbFileInfo, SHGFI uFlags);

封裝方法:獲取大/小圖標


public static Icon GetLargeIcon(string filePath)
{
    var info = new SHFILEINFO();
    SHGetFileInfo(filePath, 0, ref info, (uint)Marshal.SizeOf(info), 
        SHGFI.ICON | SHGFI.LARGEICON);
    try { return Icon.FromHandle(info.hIcon); }
    catch { return null; }
}

public static Icon GetSmallIcon(string filePath)
{
    var info = new SHFILEINFO();
    SHGetFileInfo(filePath, 0, ref info, (uint)Marshal.SizeOf(info),
        SHGFI.ICON | SHGFI.SMALLICON);
    try { return Icon.FromHandle(info.hIcon); }
    catch { return null; }
}

使用示例


var large = ShellHelper.GetLargeIcon(@"C:\Windows\notepad.exe");
var small = ShellHelper.GetSmallIcon(@"C:\Windows\notepad.exe");
pictureBoxLarge.Image = large?.ToBitmap();
pictureBoxSmall.Image = small?.ToBitmap();

已知問題與優化

  • TreeView/ListView 直接綁定圖標顯示效果差 → 建議使用 ImageList + 系統圖標索引 (SHGFI.SYSICONINDEX)
  • 大量文件重複提取圖標性能低 → 緩存 Icon 或使用系統圖標索引
  • 圖標句柄需及時銷毀 → Icon.FromHandle 返回的 Icon 需 Dispose

總結

SHGetFileInfo 是獲取系統文件圖標的標準途徑。掌握結構體佈局、標誌組合、P/Invoke 簽名、句柄管理,即可在 WinForms/WPF 中實現原生級文件圖標顯示。生產環境建議配合 ImageList 使用系統圖標索引模式,兼顧性能與顯示質量。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved