You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PowerShell中使用SHGetStockIconInfo获取文件夹图标?

在PowerShell中使用SHGetStockIconInfo获取文件夹图标

错误原因

你碰到的The type or namespace name 'Icon' could not be found错误,是因为代码里用到的Icon类型属于System.Drawing命名空间,但你的Add-Type代码既没引用对应的程序集,也没添加命名空间引用。

修正后的完整代码

需要在Add-Type命令里加上-AssemblyName System.Drawing参数,同时在成员定义中引入System.Drawing命名空间。以下是可直接运行的完整代码:

Add-Type -Namespace WinAPI -Name DefaultIcons -AssemblyName System.Drawing -MemberDefinition @'
using System.Drawing;
using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct SHSTOCKICONINFO {
    public uint cbSize;
    public IntPtr hIcon;
    public int iSysIconIndex;
    public int iIcon;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
    public string szPath;
}

[DllImport("shell32.dll")]
public static extern int SHGetStockIconInfo(uint siid, uint uFlags, ref SHSTOCKICONINFO psii);

[DllImport("user32.dll")]
public static extern bool DestroyIcon(IntPtr handle);

private const uint SHSIID_FOLDER = 0x3;
private const uint SHGSI_ICON = 0x100;
private const uint SHGSI_LARGEICON = 0x0;
private const uint SHGSI_SMALLICON = 0x1;

public static Icon GetFolderIcon(bool isLarge) {
    SHSTOCKICONINFO iconInfo = new SHSTOCKICONINFO();
    // 必须设置结构体大小,否则函数调用会失败
    iconInfo.cbSize = (uint)Marshal.SizeOf(typeof(SHSTOCKICONINFO));
    
    uint flags = SHGSI_ICON | (isLarge ? SHGSI_LARGEICON : SHGSI_SMALLICON);
    int result = SHGetStockIconInfo(SHSIID_FOLDER, flags, ref iconInfo);
    
    if (result != 0) {
        throw new System.ComponentModel.Win32Exception(result);
    }
    
    // 将句柄转换为Icon对象
    Icon folderIcon = Icon.FromHandle(iconInfo.hIcon);
    // 注意:不要立即销毁句柄,Icon对象还在使用它,Dispose时会自动释放
    
    return folderIcon;
}
'@

在WinForm ListView中使用的示例

# 加载WinForms程序集
Add-Type -AssemblyName System.Windows.Forms

# 初始化ListView和ImageList
$listView = New-Object System.Windows.Forms.ListView
$listView.View = [System.Windows.Forms.View]::LargeIcon
$listView.Dock = [System.Windows.Forms.DockStyle]::Fill

$largeImageList = New-Object System.Windows.Forms.ImageList
$largeImageList.ImageSize = New-Object System.Drawing.Size(32,32)
$listView.LargeImageList = $largeImageList

# 获取大文件夹图标并添加到ImageList
$largeFolderIcon = [WinAPI.DefaultIcons]::GetFolderIcon($true)
$imageIndex = $largeImageList.Images.Add($largeFolderIcon)

# 添加带图标的ListView项
$item = New-Object System.Windows.Forms.ListViewItem("测试文件夹")
$item.ImageIndex = $imageIndex
$listView.Items.Add($item)

# 创建并显示窗体
$form = New-Object System.Windows.Forms.Form
$form.Text = "文件夹图标示例"
$form.Size = New-Object System.Drawing.Size(400,300)
$form.Controls.Add($listView)
$form.ShowDialog()

# 手动释放资源,避免内存泄漏
$largeFolderIcon.Dispose()
$largeImageList.Dispose()
$form.Dispose()

注意事项

  • 图标使用完毕后必须调用Dispose()方法释放资源,防止内存泄漏
  • 如果需要获取小图标,只需调用[WinAPI.DefaultIcons]::GetFolderIcon($false)即可

内容的提问来源于stack exchange,提问作者therks

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 01:25:29