User32_DestroyIcon
User32_DestroyIcon
is a «P/Invoke» class that wraps the single
WinAPI call:
DestroyIcon()
. This function is needed after an Icon is extracted from a DLL.
add-type -typeDefinition '
using System;
using System.Runtime.InteropServices;
public class User32_DestroyIcon {
[DllImport(
"User32.dll",
EntryPoint = "DestroyIcon"
)]
public static extern int DestroyIcon(IntPtr hIcon);
}
';
go.ps1
go.ps1
is a simple PowerShell script that tries to demonstrate how icons might be extracted from a
DLL.
#
# Prevent Error
# Unable to find type [System.Drawing.Icon]
# and
# Unable to find type [System.Drawing.Imaging.ImageFormat].
#
$null = [Reflection.Assembly]::LoadWithPartialName('System.Drawing');
$null = [Reflection.Assembly]::LoadWithPartialName('System.Drawing.Imaging');
$dllPath = "$env:SystemRoot\System32\imageres.dll"
[System.IntPtr] $phiconSmall = 0
[System.IntPtr] $phiconLarge = 0
$nofImages = [Shell32_Extract]::ExtractIconEx($dllPath, -1, [ref] $phiconLarge, [ref] $phiconSmall, 0)
foreach ($iconIndex in 0 .. ($nofImages-1)) {
$nofIconsExtracted = [Shell32_Extract]::ExtractIconEx($dllPath, $iconIndex, [ref] $phiconLarge, [ref] $phiconSmall, 1)
if ($nofIconsExtracted -ne 2) {
write-error "iconsExtracted = $nofIconsExtracted"
}
$iconSmall = [System.Drawing.Icon]::FromHandle($phiconSmall);
$iconLarge = [System.Drawing.Icon]::FromHandle($phiconLarge);
$bmpSmall = $iconSmall.ToBitmap()
$bmpLarge = $iconLarge.ToBitmap()
$iconIndex_0 = '{0,3:000}' -f $iconIndex
#
# System.Drawing.Image.Save(), without specifying an encoder, stores
# the bitmap in png format.
#
$bmpLarge.Save("$(get-location)\small-$iconIndex_0.png");
$bmpLarge.Save("$(get-location)\large-$iconIndex_0.png");
#
# Use System.Drawing.Imaging.ImageFormat to specify a
# different format:
#
$bmpSmall.Save("$(get-location)\small-$iconIndex_0.bmp", [System.Drawing.Imaging.ImageFormat]::Bmp );
$bmpLarge.Save("$(get-location)\large-$iconIndex_0.bmp", [System.Drawing.Imaging.ImageFormat]::Bmp );
$bmpSmall.Save("$(get-location)\small-$iconIndex_0.jpg", [System.Drawing.Imaging.ImageFormat]::Jpeg);
$bmpLarge.Save("$(get-location)\large-$iconIndex_0.jpg", [System.Drawing.Imaging.ImageFormat]::Jpeg);
}
create-html-with-icons-of-dll.ps1
The following script creates a
HTML document that contains the icons that are in a
DLL or
EXE.
$dllPath = $args[0]
if ($dllPath -eq $null) {
write-output "specify a dll";
return;
}
if (! (test-path $dllPath)) {
write-output "$dllPath is not a file";
return;
}
$filenameWithoutSuffix = [IO.Path]::GetFileNameWithoutExtension($dllPath)
. .\Shell32_Extract.ps1
. .\User32_DestroyIcon.ps1
"<html><head>
<title>Icons in $filenameWithoutSuffix.dll</title></head><body>
<h1>Icons in $filenameWithoutSuffix.dll</h1>
These icons were extracted with <a href='https://renenyffenegger.ch/notes/Windows/PowerShell/examples/WinAPI/ExtractIconEx'>PowerShell and the WinAPI function <code>ExtractIconEx</code></a><p>
<table><tr>" | out-file "$filenameWithoutSuffix.html";
$null = [Reflection.Assembly]::LoadWithPartialName('System.Drawing');
$null = [Reflection.Assembly]::LoadWithPartialName('System.Drawing.Imaging');
[System.IntPtr] $phiconSmall = 0;
[System.IntPtr] $phiconLarge = 0;
$nofImages = [Shell32_Extract]::ExtractIconEx($dllPath, -1, [ref] $phiconLarge, [ref] $phiconSmall, 0);
$nofImages;
foreach ($iconIndex in 0 .. ($nofImages-1)) {
$nofIconsExtracted = [Shell32]::ExtractIconEx($dllPath, $iconIndex, [ref] $phiconLarge, [ref] $phiconSmall, 1)
$iconLarge = [System.Drawing.Icon]::FromHandle($phiconLarge);
$bmpLarge = $iconLarge.ToBitmap()
$iconIndex_0 = '{0,3:000}' -f $iconIndex
$imgName = "$filenameWithoutSuffix-$iconIndex_0.png";
$bmpLarge.Save("$(get-location)\$imgName");
if ($iconIndex -and (! ($iconIndex % 10))) {
"</tr><tr>" | out-file "$filenameWithoutSuffix.html" -append;
}
"<td>$iconIndex_0</td><td><img src='$imgName'/></td>" | out-file "$filenameWithoutSuffix.html" -append;
$null = [User32_DestroyIcon]::DestroyIcon($phiconSmall);
$null = [User32_DestroyIcon]::DestroyIcon($phiconLarge);
}
"</table></body></html>" | out-file "$filenameWithoutSuffix.html" -append;