I'd like to get the Tree icon to use for a homegrown app. Does anyone know how to extract the images out as .icon files? I'd like both the 16x16 and 32x32, or I'd just do a screen capture.
-
11Note that doing this is a violation of the license. "While the software is running, you may use but not share its icons, images, sounds, and media." – Raymond Chen Mar 29 '13 at 22:45
13 Answers
If anyone is seeking an easy way, just use 7zip to unzip the shell32.dll and look for the folder .src/ICON/

- 789
- 5
- 2
-
1rename to shell32.7z then try to open it up with 7-zip, Peazip, or your other fav compression tools – ronaldwidha Oct 21 '16 at 17:11
In Visual Studio, choose "File Open..." then "File...". Then pick the Shell32.dll. A folder tree should be opened, and you will find the icons in the "Icon" folder.
To save an Icon, you can right-click on the icon in the folder tree and choose "Export".

- 350
- 1
- 9

- 23,422
- 22
- 79
- 93
-
2when I use this I only have this folder tree and all the icons listed but without a preview and the titles aren't that helpfull (1, 10, 1001, ..) Is there a way to get a preview or do I really have to open all the Icons? – Dominik Jul 23 '15 at 10:46
-
2@MickyD Can't confirm - exporting Icons worked like a charm for me in VS Community 2017 (15.8.3) - just as written in this answer. The menu may have changed a bit - it's now "File" --> "Open" --> "File...". (I copied shell32.dll to my desktop to test this) – RicoBrassers Sep 20 '18 at 06:11
-
1@RicoBrassers well that's embarrassing, works now. I must have done something silly. Thanks buddy :) – Sep 20 '18 at 06:41
-
It is important to open the shell32.dll file from the Windows\System32 folder, otherwise there is no "Icon" folder. – ViH Dec 24 '21 at 15:24
-
1As of 2023, this solution no longer works in Windows 10 or 11. The [TheManInOz's answer](https://stackoverflow.com/a/71200876/1469208) is the only one correct right now. – trejder Jan 27 '23 at 19:17
Another option is to use a tool such as ResourceHacker. It handles way more than just icons as well. Cheers!

- 28,944
- 5
- 56
- 71
-
1I tried to use Resource Hacker, but every icon has 12 duplicates (with various sizes). – HighTechProgramming15 Jan 03 '17 at 13:27
-
1
-
As of 2023, this solution no longer works in Windows 10 or 11. The [TheManInOz's answer](https://stackoverflow.com/a/71200876/1469208) is the only one correct right now. – trejder Jan 27 '23 at 19:18
Not sure if I am 100% correct, but from my testing, the above options for using 7Zip or VS don't work on Windows 10 / 11 versions of imageres.dll or shell32.dll. This is the content I see:
[shell32.dll]
.rsrc\MANIFEST\124
.rsrc\MUI\1
.rsrc\TYPELIB\1
.rsrc\version.txt
.data
.didat
.pdata
.rdata
.reloc
.text
CERTIFICATE
Update: And I think I found why. Link to an article I found. (Sorry for being off-domain). You can find the resources in files in these locations:
"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)

- 191
- 1
- 3
-
WOW, I wasted a lot of time trying to find `UIFILES` and Icons in `shell32.dll`! Why they hid them in `.mun` file???! – ScienceDiscoverer Jul 06 '22 at 18:38
-
2I copied the `shell32.dll.mun` file then used 7-Zip **Extract Here** and found the icons I needed. – Mark Davich Jul 14 '22 at 05:06
I needed to extract icon #238 from shell32.dll and didn't want to download Visual Studio or Resourcehacker, so I found a couple of PowerShell scripts from Technet (thanks John Grenfell and to #https://social.technet.microsoft.com/Forums/windowsserver/en-US/16444c7a-ad61-44a7-8c6f-b8d619381a27/using-icons-in-powershell-scripts?forum=winserverpowershell) that did something similar and created a new script (below) to suit my needs.
The parameters I entered were (the source DLL path, target icon file name and the icon index within the DLL file):
C:\Windows\System32\shell32.dll
C:\Temp\Restart.ico
238
I discovered the icon index that I needed was #238 by trial and error by temporarily creating a new shortcut (right-click on your desktop and select New --> Shortcut and type in calc and press Enter twice). Then right-click the new shortcut and select Properties then click 'Change Icon' button in the Shortcut tab. Paste in path C:\Windows\System32\shell32.dll and click OK. Find the icon you wish to use and work out its index. NB: Index #2 is beneath #1 and not to its right. Icon index #5 was at the top of column two on my Windows 7 x64 machine.
If anyone has a better method that works similarly but obtains higher quality icons then I'd be interested to hear about it. Thanks, Shaun.
#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"

- 366
- 1
- 6
- 15
-
Great method but it doesn't work for me. I am on Windows 7x64 on which script seems to be confirmed to work. But I get `TypeNotFound` errors for `System.Drawing.Icon` and `System.Drawing.Bitmap`. My first try to run a PS-script so maybe I do something wrong? – Danny Lo Jan 18 '16 at 01:07
-
1Ok, I just needed to execute `Add-Type -AssemblyName System.Drawing` first. – Danny Lo Jan 18 '16 at 01:12
-
Just open the DLL with IrfanView and save the result as a .gif or .jpg.
I know this question is old, but it's the second google hit from "extract icon from dll", I wanted to avoid installing anything on my workstation and I remembered I use IrfanView.
-
I already use IrfanView so this was an easy choice for a quick browse of the icons. Press **F10** to see thumbnails of all the stored images. I did not find a way to identify the image number. Is there a way? – Ben May 12 '22 at 15:48
Resources Extract is another tool that will recursively find icons from a lot of DLLs, very handy IMO.

- 2,656
- 4
- 28
- 37
-
3While that tool is good for pulling the resource out, they also have a tool IconsExtract https://www.nirsoft.net/utils/iconsext.html that I find more handy in most cases since I can browse the icons and simply link to the system file when I want the icon in an embedded/linked document in Office. – undrline - Reinstate Monica Sep 07 '18 at 18:50
-
As of 2023, this solution no longer works in Windows 10 or 11. The [TheManInOz's answer](https://stackoverflow.com/a/71200876/1469208) is the only one correct right now. – trejder Jan 27 '23 at 19:18
Here is an updated version of a solution above. I added a missing assembly that was buried in a link. Novices will not understand that. This is sample will run without modifications.
<#
.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]"

- 541
- 3
- 18
-
I had to remove this line to have it to work: $form = New-Object System.Windows.Forms.Form And the output icons are very poor quality ones, like 256 colors (or even 16). Perhaps script has to be tweaked in some way? I am on Windows 10 – luiggig May 12 '20 at 15:55
-
Sorry but your code threw multiple errors, starting from "illegal characters in path" to "error extracting ico file". The code you tried to improve worked immediately for me. – David Trevor Jul 08 '20 at 07:04
You can download freeware Resource Hacker and then follow below instructions :
- Open any dll file you wish to find icons from.
- Browse folders to find specific icons.
- From menu bar, select 'action' and then 'save'.
- Select destination for .ico file.
Reference : http://techsultan.com/how-to-extract-icons-from-windows-7/

- 21
- 1
There is also this resource available, the Visual Studio Image Library, which "can be used to create applications that look visually consistent with Microsoft software", presumably subject to the licensing given at the bottom. https://www.microsoft.com/en-ca/download/details.aspx?id=35825

- 400
- 4
- 7
This question already has answers here, but for anybody new wondering how to do this, I used 7Zip and navigated to %SystemRoot%\system32\SHELL32.dll\.rsrc\ICON
, then copied all the files to a desired location.
If you'd like a pre-extracted directory, you can download the ZIP here.
Note: I extracted the files on a Windows 8.1 installation, so they may vary from the ones on other versions of Windows.

- 605
- 5
- 12
If you're on Linux, you can extract icons from a Windows DLL with gExtractWinIcons.
It's available in Ubuntu and Debian in the gextractwinicons
package.
This blog article has a screenshot and brief explanation.

- 1,673
- 14
- 18
The following is a similar take to Mr. Annoyed's answer, it uses ExtractIconEx
function to extract icons from libraries. Main difference is, this function should be compatible with both, Windows PowerShell 5.1 and PowerShell 7+ and will also extract both icons by default, large and small, from a given index (-InconIndex
). The function outputs 2 FileInfo
instances pointing to the created icons given in -DestinationFolder
. If no destination folder is provided, the icons will be extracted to the PowerShell current directory ($pwd
).
function Invoke-ExtractIconEx {
[CmdletBinding(PositionalBinding = $false)]
param(
[Parameter()]
[ValidateNotNull()]
[string] $SourceLibrary = 'shell32.dll',
[Parameter(Position = 0)]
[string] $DestinationFolder = $pwd.Path,
[Parameter(Position = 1)]
[int] $InconIndex
)
$refAssemblies = @(
[Drawing.Icon].Assembly.Location
if ($IsCoreCLR) {
$pwshLocation = Split-Path -Path ([psobject].Assembly.Location) -Parent
$pwshRefAssemblyPattern = [IO.Path]::Combine($pwshLocation, 'ref', '*.dll')
(Get-Item -Path $pwshRefAssemblyPattern).FullName
}
)
Add-Type -AssemblyName System.Drawing
Add-Type '
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Drawing;
using System.IO;
namespace Win32Native
{
internal class SafeIconHandle : SafeHandle
{
[DllImport("user32.dll")]
private static extern bool DestroyIcon(IntPtr hIcon);
public SafeIconHandle() : base(IntPtr.Zero, true) { }
public override bool IsInvalid
{
get
{
return handle == IntPtr.Zero;
}
}
protected override bool ReleaseHandle()
{
return DestroyIcon(handle);
}
}
public static class ShellApi
{
[DllImport("shell32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern uint ExtractIconExW(
string szFileName,
int nIconIndex,
out SafeIconHandle phiconLarge,
out SafeIconHandle phiconSmall,
uint nIcons);
private static void ExtractIconEx(string fileName, int iconIndex, out SafeIconHandle iconLarge,
out SafeIconHandle iconSmall)
{
if (ExtractIconExW(fileName, iconIndex, out iconLarge, out iconSmall, 1) == uint.MaxValue)
{
throw new Win32Exception();
}
}
public static FileInfo[] ExtractIcon(string sourceExe,
string destinationFolder, int iconIndex)
{
SafeIconHandle largeIconHandle;
SafeIconHandle smallIconHandle;
ExtractIconEx(sourceExe, iconIndex, out largeIconHandle, out smallIconHandle);
using (largeIconHandle)
using (smallIconHandle)
using (Icon largeIcon = Icon.FromHandle(largeIconHandle.DangerousGetHandle()))
using (Icon smallIcon = Icon.FromHandle(smallIconHandle.DangerousGetHandle()))
{
FileInfo[] outFiles = new FileInfo[2]
{
new FileInfo(Path.Combine(destinationFolder, string.Format("{0}-largeIcon-{1}.bmp", sourceExe, iconIndex))),
new FileInfo(Path.Combine(destinationFolder, string.Format("{0}-smallIcon-{1}.bmp", sourceExe, iconIndex)))
};
largeIcon.ToBitmap().Save(outFiles[0].FullName);
smallIcon.ToBitmap().Save(outFiles[1].FullName);
return outFiles;
}
}
}
}
' -ReferencedAssemblies $refAssemblies
$DestinationFolder = $PSCmdlet.GetUnresolvedProviderPathFromPSPath($DestinationFolder)
[Win32Native.ShellApi]::ExtractIcon($SourceLibrary, $DestinationFolder, $InconIndex)
}
Usage:
# Extracts to PWD
Invoke-ExtractIconEx -InconIndex 1
# Targeting a different library
Invoke-ExtractIconEx -SourceLibrary user32.dll -InconIndex 1
# Using a different target folder
Invoke-ExtractIconEx path\to\my\folder -InconIndex 1

- 41,465
- 5
- 14
- 37