【问题标题】:How do you get the icons out of shell32.dll?如何从 shell32.dll 中获取图标?
【发布时间】:2008-08-12 03:26:38
【问题描述】:

我希望将 Tree 图标用于本地应用程序。有谁知道如何将图像提取为 .icon 文件?我想要 16x16 和 32x32,或者我只是截屏。

【问题讨论】:

  • 请注意,这样做违反了许可证。 “在软件运行时,您可以使用但不能共享其图标、图像、声音和媒体。”

标签: windows icons


【解决方案1】:

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

【讨论】:

  • 是的,我非常喜欢使用 7-Zip 的“打开存档”功能。
  • 没有 7Zip,但在 WinRAR 中尝试过,它说没有要打开的存档。
  • 重命名为 shell32.7z 然后尝试使用 7-zip、Peazip 或其他您喜欢的压缩工具打开它
  • 这应该是公认的答案,因为它既简单又有效。
【解决方案2】:

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

要保存图标,您可以右键单击文件夹树中的图标并选择“导出”。

【讨论】:

  • 当我使用它时,我只有这个文件夹树和列出的所有图标,但没有预览,而且标题没有那么有用(1、10、1001、..)有没有办法获得预览还是我真的必须打开所有图标?
  • @MickyD 无法确认 - 在 VS Community 2017 (15.8.3) 中,导出图标对我来说就像一种魅力 - 正如在这个答案中所写的那样。菜单可能发生了一些变化——现在是“文件”-->“打开”-->“文件...”。 (我将 shell32.dll 复制到我的桌面进行测试)
  • @RicoBrassers 好尴尬,现在可以了。我一定是做了什么傻事。谢谢哥们:)
  • 从Windows\System32文件夹中打开shell32.dll文件很重要,否则没有“Icon”文件夹。
【解决方案3】:

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

【讨论】:

  • 我尝试使用 Resource Hacker,但每个图标都有 12 个重复项(大小不一)。
  • @HighTechProgramming15 这不是你想要的吗?
【解决方案4】:

我需要从 shell32.dll 中提取图标 #238 并且不想下载 Visual Studio 或 Resourcehacker,因此我从 Technet 找到了几个 PowerShell 脚本(感谢 John Grenfell 和 #https://social.technet.microsoft.com/Forums/windowsserver/en-US/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 下方,而不是在其右侧。在我的 Windows 7 x64 机器上,图标索引 #5 位于第二列的顶部。

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

#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"

【讨论】:

  • 比其他答案更有帮助。
  • 很好的方法,但对我不起作用。我在 Windows 7x64 上,脚本似乎已被确认可以工作。但是我得到System.Drawing.IconSystem.Drawing.BitmapTypeNotFound 错误。我第一次尝试运行 PS 脚本,所以也许我做错了什么?
  • 好的,我只需要先执行Add-Type -AssemblyName System.Drawing
  • 完美工作,无需添加任何程序集
【解决方案5】:

Resources Extract 是另一个工具,它可以从大量 DLL 中递归查找图标,非常方便 IMO。

【讨论】:

  • 虽然该工具可以很好地提取资源,但他们也有一个工具 IconsExtract nirsoft.net/utils/iconsext.html 在大多数情况下我发现它更方便,因为我可以浏览图标并简单地链接到系统文件我想要 Office 中嵌入/链接文档中的图标。
【解决方案6】:

只需使用 IrfanView 打开 DLL 并将结果保存为 .gif 或 .jpg。

我知道这个问题已经过时了,但这是谷歌第二次点击“从 dll 中提取图标”,我想避免在我的工作站上安装任何东西,我记得我使用的是 IrfanView。

【讨论】:

    【解决方案7】:

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

    1. 打开您希望从中查找图标的任何 dll 文件。
    2. 浏览文件夹以查找特定图标。
    3. 从菜单栏中选择“操作”,然后选择“保存”。
    4. 选择 .ico 文件的目标位置。

    参考:http://techsultan.com/how-to-extract-icons-from-windows-7/

    【讨论】:

      【解决方案8】:

      这是上述解决方案的更新版本。 我添加了一个隐藏在链接中的缺失程序集。 新手不会理解的。 此示例无需修改即可运行。

          <#
      .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]"
      

      【讨论】:

      • 我必须删除这一行才能让它工作: $form = New-Object System.Windows.Forms.Form 并且输出图标质量很差,比如 256 色(甚至 16 )。也许脚本必须以某种方式进行调整?我在 Windows 10 上
      • 抱歉,您的代码抛出了多个错误,从“路径中的非法字符”到“提取 ico 文件时出错”。您尝试改进的代码立即对我有用。
      【解决方案9】:

      还有一个可用的资源,即 Visual Studio 图像库,“可用于创建在视觉上与 Microsoft 软件一致的应用程序”,大概受底部给出的许可限制。 https://www.microsoft.com/en-ca/download/details.aspx?id=35825

      【讨论】:

        【解决方案10】:

        这个问题在这里已经有了答案,但是对于任何想知道如何做到这一点的新人,我使用 7Zip 并导航到 %SystemRoot%\system32\SHELL32.dll\.rsrc\ICON,然后将所有文件复制到所需的位置。

        如果您想要预解压目录,可以download the ZIP here

        注意:我在安装 Windows 8.1 时提取了这些文件,因此它们可能与其他 Windows 版本上的不同。

        【讨论】:

        • 我不知道你可以用 7ZIP 打开这些!
        【解决方案11】:

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

        这篇博文有一个screenshot and brief explanation

        【讨论】:

          【解决方案12】:

          不确定我是否 100% 正确,但根据我的测试,上述使用 7Zip 或 VS 的选项不适用于 Windows 10 / 11 版本的 imageres.dll 或 shell32.dll。 这是我看到的内容:

          [shell32.dll]
          .rsrc\MANIFEST\124
          .rsrc\MUI\1
          .rsrc\TYPELIB\1
          .rsrc\version.txt
          .data
          .didat
          .pdata
          .rdata
          .reloc
          .text
          CERTIFICATE
          

          更新:我想我找到了原因。链接到我找到的一篇文章。 (对不起,域外)。 您可以在以下位置的文件中找到资源:

          "C:\Windows\SystemResources\shell32.dll.mun"
          "C:\Windows\SystemResources\imageres.dll.mun"
          

          Icons no longer in imageres.dll in Windows 10 1903 - 4kb file (superuser.com)

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-12-08
            • 1970-01-01
            • 1970-01-01
            • 2013-01-10
            相关资源
            最近更新 更多