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

如何通过PowerShell从shell32.dll获取指定索引的图标?

从shell32.dll提取指定索引图标的解决方法

问题描述

我编写了一段从shell32.dll提取图标的PowerShell代码:

$iconPath = "$env:SystemRoot\system32\shell32.dll"  # Path to the shell32.dll library
$iconIndex = 4  # Index of the folder icon in the library
$icon = [System.Drawing.Icon]::ExtractAssociatedIcon($iconPath)
$icon = [System.Drawing.Icon]::new($icon, 16, 16)

这段代码能从shell32.dll中获取图标,但未引用$iconIndex变量,无法获取索引为4的图标。尝试给ExtractAssociatedIcon添加第二个参数时出现报错,请问如何修改代码以获取指定索引的图标?

解决方案

.NET自带的ExtractAssociatedIcon方法只能提取文件关联的默认图标(通常是资源里的第一个图标),不支持指定索引。要提取特定索引的图标,需要调用Windows原生API ExtractIconEx,以下是修改后的代码:

Add-Type -TypeDefinition @"
using System;
using System.Drawing;
using System.Runtime.InteropServices;

public class IconExtractor {
    [DllImport("shell32.dll", CharSet = CharSet.Auto)]
    private static extern uint ExtractIconEx(string lpszFile, int nIconIndex, IntPtr[] phiconLarge, IntPtr[] phiconSmall, uint nIcons);

    [DllImport("user32.dll")]
    private static extern bool DestroyIcon(IntPtr hIcon);

    public static Icon ExtractIcon(string filePath, int iconIndex, bool isLargeIcon = false) {
        IntPtr[] iconHandles = new IntPtr[1];
        uint extractedCount = ExtractIconEx(filePath, iconIndex, isLargeIcon ? iconHandles : null, isLargeIcon ? null : iconHandles, 1);
        
        if (extractedCount == 0 || iconHandles[0] == IntPtr.Zero) {
            throw new Exception("Failed to extract icon.");
        }

        try {
            return Icon.FromHandle(iconHandles[0]);
        } finally {
            DestroyIcon(iconHandles[0]);
        }
    }
}
"@

$iconPath = "$env:SystemRoot\system32\shell32.dll"
$iconIndex = 4
$targetSize = 16

# 提取指定索引的小图标(要大图标就把最后一个参数改成$true)
$rawIcon = [IconExtractor]::ExtractIcon($iconPath, $iconIndex, $false)
# 调整到目标尺寸
$finalIcon = New-Object System.Drawing.Icon($rawIcon, $targetSize, $targetSize)

# 示例:保存图标到文件
# $finalIcon.Save("C:\your_path\target_icon.ico")

# 释放资源,避免内存泄漏
$rawIcon.Dispose()
$finalIcon.Dispose()

代码说明

  • 通过Add-Type定义了IconExtractor类,封装了两个Win32 API调用:
    • ExtractIconEx:从指定DLL文件中提取对应索引的图标,支持区分大、小图标。
    • DestroyIcon:释放图标句柄,防止内存泄漏。
  • ExtractIcon方法返回提取到的Icon对象,之后可以通过System.Drawing.Icon的构造函数调整图标尺寸。
  • 最后必须调用Dispose()释放图标资源,避免持续占用内存。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 15:03:27