关于Windows:如何从shell32.dll中获取图标?

关于Windows:如何从shell32.dll中获取图标?

How do you get the icons out of shell32.dll?

我想将"树"图标用于本地应用。 有谁知道如何将图像提取为.icon文件? 我想同时使用16x16和32x32,或者只做屏幕截图。


如果有人在寻找简单的方法,只需使用7zip解压缩shell32.dll并查找文件夹.src / ICON /


在Visual Studio中,选择"文件打开...",然后选择"文件..."。然后选择Shell32.dll。应该打开一个文件夹树,您将在"图标"文件夹中找到图标。

要保存图标,可以右键单击文件夹树中的图标,然后选择"导出"。


另一种选择是使用诸如ResourceHacker之类的工具。它不仅处理图标,还处理更多方式。干杯!


我需要从shell32.dll中提取图标#238,并且不想下载Visual Studio或Resourcehacker,所以我从Technet找到了几个PowerShell脚本(感谢John Grenfell和#https://social.technet.microsoft。 com / Forums / windowsserver / zh-CN / 16444c7a-ad61-44a7-8c6f-b8d619381a27 / using-icons-in-powershell-scripts?forum = winserverpowershell)做了类似的操作,并创建了一个新脚本(如下所示)来满足我的需求。

我输入的参数是(源DLL路径,目标图标文件名和DLL文件中的图标索引):

C:\ Windows \ System32 \ shell32.dll

C:\ Temp \ restart.ico

238

通过临时创建一个新的快捷方式,我通过反复试验发现我需要的图标索引是#238(右键单击您的桌面,然后选择"新建->快捷方式",然后键入calc并按Enter键两次)。然后右键单击新的快捷方式,然后选择"属性",然后在"快捷方式"选项卡中单击"更改图标"按钮。粘贴在路径C:\ Windows \ System32 \ shell32.dll中,然后单击"确定"。找到您要使用的图标并计算其索引。注意:索引2在索引1以下,而不是在其右边。图标索引#5在Windows 7 x64计算机上第二列的顶部。

如果有人有一个更好的方法可以类似地工作,但是获得了更高质量的图标,那么我很想听听它。谢谢,肖恩

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#Windows PowerShell Code###########################################################################
# http://gallery.technet.microsoft.com/scriptcenter/Icon-Exporter-e372fe70
#
# AUTHOR: John Grenfell
#
###########################################################################

<#
.SYNOPSIS
   Exports an ico and bmp file from a given source to a given destination
.Description
   You need to set the Source and Destination locations. First version of a script, I found other examples but all I wanted to do as grab and ico file from an exe but found getting a bmp useful. Others might find useful
   No error checking I'm afraid so make sure your source and destination locations exist!
.EXAMPLE
    .\\Icon_Exporter.ps1
.Notes
        Version HISTORY:
        1.1 2012.03.8
#>
Param ( [parameter(Mandatory = $true)][string] $SourceEXEFilePath,
        [parameter(Mandatory = $true)][string] $TargetIconFilePath
)
CLS
#"shell32.dll" 238
If ($SourceEXEFilePath.ToLower().Contains(".dll")) {
    $IconIndexNo = Read-Host"Enter the icon index:"
    $Icon = [System.IconExtractor]::Extract($SourceEXEFilePath, $IconIndexNo, $true)    
} Else {
    [void][Reflection.Assembly]::LoadWithPartialName("System.Drawing")
    [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
    $image = [System.Drawing.Icon]::ExtractAssociatedIcon("$($SourceEXEFilePath)").ToBitmap()
    $bitmap = new-object System.Drawing.Bitmap $image
    $bitmap.SetResolution(72,72)
    $icon = [System.Drawing.Icon]::FromHandle($bitmap.GetHicon())
}
$stream = [System.IO.File]::OpenWrite("$($TargetIconFilePath)")
$icon.save($stream)
$stream.close()
Write-Host"Icon file can be found at $TargetIconFilePath"

Resources Extract是另一个工具,可以从很多DLL中递归地找到图标,非常方便的IMO。


这是上述解决方案的更新版本。
我添加了一个丢失的程序集,该程序集埋在链接中。
新手不会理解。
此示例将运行而无需修改。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
    <#
.SYNOPSIS
    Exports an ico and bmp file from a given source to a given destination
.Description
    You need to set the Source and Destination locations. First version of a script, I found other examples
    but all I wanted to do as grab and ico file from an exe but found getting a bmp useful. Others might find useful
.EXAMPLE
    This will run but will nag you for input
    .\\Icon_Exporter.ps1
.EXAMPLE
    this will default to shell32.dll automatically for -SourceEXEFilePath
    .\\Icon_Exporter.ps1 -TargetIconFilePath 'C:\\temp\\Myicon.ico' -IconIndexNo 238
.EXAMPLE
    This will give you a green tree icon (press F5 for windows to refresh Windows explorer)
    .\\Icon_Exporter.ps1 -SourceEXEFilePath 'C:/Windows/system32/shell32.dll' -TargetIconFilePath 'C:\\temp\\Myicon.ico' -IconIndexNo 41

.Notes
    Based on http://stackoverflow.com/questions/8435/how-do-you-get-the-icons-out-of-shell32-dll Version 1.1 2012.03.8
    New version: Version 1.2 2015.11.20 (Added missing custom assembly and some error checking for novices)
#>
Param (
    [parameter(Mandatory = $true)]
    [string] $SourceEXEFilePath = 'C:/Windows/system32/shell32.dll',
    [parameter(Mandatory = $true)]
    [string] $TargetIconFilePath,
    [parameter(Mandatory = $False)]
    [Int32]$IconIndexNo = 0
)

#https://social.technet.microsoft.com/Forums/windowsserver/en-US/16444c7a-ad61-44a7-8c6f-b8d619381a27/using-icons-in-powershell-scripts?forum=winserverpowershell
$code = @"
using System;
using System.Drawing;
using System.Runtime.InteropServices;

namespace System
{
    public class IconExtractor
    {

     public static Icon Extract(string file, int number, bool largeIcon)
     {
      IntPtr large;
      IntPtr small;
      ExtractIconEx(file, number, out large, out small, 1);
      try
      {
       return Icon.FromHandle(largeIcon ? large : small);
      }
      catch
      {
       return null;
      }

     }
     [DllImport("Shell32.dll", EntryPoint ="ExtractIconExW", CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
     private static extern int ExtractIconEx(string sFile, int iIndex, out IntPtr piLargeVersion, out IntPtr piSmallVersion, int amountIcons);

    }
}
"@

If  (-not (Test-path -Path $SourceEXEFilePath -ErrorAction SilentlyContinue ) ) {
    Throw"Source file [$SourceEXEFilePath] does not exist!"
}

[String]$TargetIconFilefolder = [System.IO.Path]::GetDirectoryName($TargetIconFilePath)
If  (-not (Test-path -Path $TargetIconFilefolder -ErrorAction SilentlyContinue ) ) {
    Throw"Target folder [$TargetIconFilefolder] does not exist!"
}

Try {
    If ($SourceEXEFilePath.ToLower().Contains(".dll")) {
        Add-Type -TypeDefinition $code -ReferencedAssemblies System.Drawing
        $form = New-Object System.Windows.Forms.Form
        $Icon = [System.IconExtractor]::Extract($SourceEXEFilePath, $IconIndexNo, $true)    
    } Else {
        [void][Reflection.Assembly]::LoadWithPartialName("System.Drawing")
        [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
        $image = [System.Drawing.Icon]::ExtractAssociatedIcon("$($SourceEXEFilePath)").ToBitmap()
        $bitmap = new-object System.Drawing.Bitmap $image
        $bitmap.SetResolution(72,72)
        $icon = [System.Drawing.Icon]::FromHandle($bitmap.GetHicon())
    }
} Catch {
    Throw"Error extracting ICO file"
}

Try {
    $stream = [System.IO.File]::OpenWrite("$($TargetIconFilePath)")
    $icon.save($stream)
    $stream.close()
} Catch {
    Throw"Error saving ICO file [$TargetIconFilePath]"
}
Write-Host"Icon file can be found at [$TargetIconFilePath]"

您可以下载免费软件Resource Hacker,然后按照以下说明进行操作:

  • 打开任何您要从中查找图标的dll文件。
  • 浏览文件夹以查找特定的图标。
  • 从菜单栏中,选择"操作",然后选择"保存"。
  • 选择.ico文件的目标。
  • 参考:http://techsultan.com/how-to-extract-icons-from-windows-7/


    只需使用IrfanView打开DLL,然后将结果另存为.webp或.webp。

    我知道这个问题很旧,但这是"从dll提取图标"中的第二个Google匹配,我想避免在工作站上安装任何东西,并且记得我使用了IrfanView。


    还有可用的资源,Visual Studio图像库,"可以用来创建在外观上与Microsoft软件保持一致的应用程序",这大概受底部授予的许可的约束。
    https://www.microsoft.com/zh-cn/download/details.aspx?id=35825


    如果您使用的是Linux,则可以使用gExtractWinIcons从Windows DLL中提取图标。
    它可以在Ubuntu和Debian的gextractwinicons软件包中使用。

    此博客文章具有屏幕截图和简要说明。


    推荐阅读