如何在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
相关产品推荐
相关产品推荐

