-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathExtract-Icon.ps1
More file actions
137 lines (113 loc) · 4.97 KB
/
Extract-Icon.ps1
File metadata and controls
137 lines (113 loc) · 4.97 KB
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
<#
.SYNOPSIS
Extract icons from executable files for deployment packages
.DESCRIPTION
Extracts all icon sizes from an executable and saves them individually or as a single .ico file
.PARAMETER SourceExe
Path to the executable file
.PARAMETER OutputPath
Directory to save extracted icons
.PARAMETER SaveAsIco
Save as multi-resolution .ico file (preserves all sizes)
.PARAMETER SaveAsPng
Save individual sizes as PNG files
.EXAMPLE
.\Extract-Icon.ps1 -SourceExe "C:\Program Files\App\App.exe" -OutputPath "C:\Packaging\AppName\SupportFiles" -SaveAsIco
#>
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true)]
[string]$SourceExe,
[Parameter(Mandatory=$true)]
[string]$OutputPath,
[switch]$SaveAsIco,
[switch]$SaveAsPng
)
# Create output directory if it doesn't exist
If (-not (Test-Path $OutputPath)) {
New-Item -Path $OutputPath -ItemType Directory -Force | Out-Null
Write-Host "Created output directory: $OutputPath" -ForegroundColor Green
}
# Get the executable name for file naming
$exeName = [System.IO.Path]::GetFileNameWithoutExtension($SourceExe)
# Load required assemblies
Add-Type -AssemblyName System.Drawing
Add-Type -AssemblyName System.Windows.Forms
# Function to extract icon using Win32 API (gets all sizes)
Add-Type @"
using System;
using System.Drawing;
using System.Runtime.InteropServices;
public class IconExtractor
{
[DllImport("shell32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr ExtractIcon(IntPtr hInst, string lpszExeFileName, int nIconIndex);
[DllImport("shell32.dll", CharSet = CharSet.Auto)]
public static extern int ExtractIconEx(string lpszFile, int nIconIndex, IntPtr[] phiconLarge, IntPtr[] phiconSmall, int nIcons);
[DllImport("user32.dll", SetLastError=true)]
public static extern bool DestroyIcon(IntPtr hIcon);
}
"@
Try {
Write-Host "Extracting icons from: $SourceExe" -ForegroundColor Cyan
# Method 1: Quick extraction of default icon (basic)
If ($SaveAsIco -and -not $SaveAsPng) {
$icon = [System.Drawing.Icon]::ExtractAssociatedIcon($SourceExe)
$icoPath = Join-Path $OutputPath "$exeName.ico"
$fileStream = [System.IO.File]::Create($icoPath)
$icon.Save($fileStream)
$fileStream.Close()
$icon.Dispose()
Write-Host "Saved icon to: $icoPath" -ForegroundColor Green
}
# Method 2: Extract all icon sizes using Win32 API
If ($SaveAsPng -or ($SaveAsIco -and $SaveAsPng)) {
# Get icon count
$iconCount = [IconExtractor]::ExtractIconEx($SourceExe, -1, $null, $null, 0)
Write-Host "Found $iconCount icon(s) in executable" -ForegroundColor Yellow
If ($iconCount -gt 0) {
# Extract large and small icons
$largeIcons = New-Object IntPtr[] $iconCount
$smallIcons = New-Object IntPtr[] $iconCount
$extracted = [IconExtractor]::ExtractIconEx($SourceExe, 0, $largeIcons, $smallIcons, $iconCount)
$iconIndex = 0
# Process large icons
ForEach ($iconPtr in $largeIcons) {
If ($iconPtr -ne [IntPtr]::Zero) {
$icon = [System.Drawing.Icon]::FromHandle($iconPtr)
If ($SaveAsPng) {
$bitmap = $icon.ToBitmap()
$pngPath = Join-Path $OutputPath "$exeName`_$($bitmap.Width)x$($bitmap.Height).png"
$bitmap.Save($pngPath, [System.Drawing.Imaging.ImageFormat]::Png)
Write-Host " Saved: $($bitmap.Width)x$($bitmap.Height) PNG" -ForegroundColor Green
$bitmap.Dispose()
}
$icon.Dispose()
[IconExtractor]::DestroyIcon($iconPtr) | Out-Null
}
$iconIndex++
}
# Process small icons
ForEach ($iconPtr in $smallIcons) {
If ($iconPtr -ne [IntPtr]::Zero) {
$icon = [System.Drawing.Icon]::FromHandle($iconPtr)
If ($SaveAsPng) {
$bitmap = $icon.ToBitmap()
$pngPath = Join-Path $OutputPath "$exeName`_$($bitmap.Width)x$($bitmap.Height)_small.png"
$bitmap.Save($pngPath, [System.Drawing.Imaging.ImageFormat]::Png)
Write-Host " Saved: $($bitmap.Width)x$($bitmap.Height) PNG (small)" -ForegroundColor Green
$bitmap.Dispose()
}
$icon.Dispose()
[IconExtractor]::DestroyIcon($iconPtr) | Out-Null
}
}
}
}
Write-Host "`nIcon extraction completed successfully!" -ForegroundColor Green
Write-Host "Output location: $OutputPath" -ForegroundColor Cyan
}
Catch {
Write-Host "Error extracting icon: $_" -ForegroundColor Red
Exit 1
}