Reputation: 617
Is there a way to get the path of an .ico of a short cut? I know how to change the shortcuts icon, but how do I find the path of the shortcut's icon file?
Upvotes: 1
Views: 3940
Reputation: 17027
I couldn't get Theo's code to work, for some reason. I think it was the RegEx. So I modified it for clarity and more info. However, it only works for links. In addition we didn't really address OP question to actually extract and get the icon file, that is embedded.
Put the following in your $PROFILE (or load as external *.ps1
function.).
function Get-ShortcutIcon {
$private:Path = $args[0]
$ws = New-Object -ComObject WScript.Shell
$sc = $ws.CreateShortcut($Path)
$scInd = 0 # Default to 0
$scLoc = $sc.IconLocation # C:\Windows\System32\shell32.dll,164
$scTar = $sc.TargetPath # "C:\Windows\System32\control.exe"
$scArg = $sc.Arguments # "ncpa.cpl"
if ($scLoc -match '^(.+),(\d+)') {
# C:\Windows\System32\shell32.dll,164
$scLoc = [string]$matches[1] # C:\Windows\System32\shell32.dll
$scInd = [int]$matches[2] # 164
}
$Tar = " {0,-20} : " -f "Shortcut Target" # $scTar
$Arg = " {0,-20} : " -f "Shortcut Arguments" # $scArg
$Loc = " {0,-20} : " -f "Icon Location" # $scLoc
$Ind = " {0,-20} : " -f "Icon Location Index" # $scInd
Write-Host -f Yellow "`nFile Icon info:`n"
Write-Host -f DarkGray "$Tar" -Non; Write-Host -f White "$scTar" #
Write-Host -f DarkGray "$Arg" -Non; Write-Host -f Gray "$scArg" #
Write-Host -f DarkGray "$Loc" -Non; Write-Host -f DarkYellow "$scLoc" #
Write-Host -f DarkGray "$Ind" -Non; Write-Host -f DarkYellow "$scInd" #
# Clean up
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($sc)
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($ws)
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
Write-Host
}
Set-Alias -Name GetIcon -Value Get-ShortcutIcon -Description 'lnk icon' -Scope Local -Option ReadOnly, Private
The output for a shortcut looks like this:
Drawback / Issues
*.exe
filesUpvotes: 1
Reputation: 61188
You could use below function.
It handles both 'regular' shrotcut files (.lnk) as well as Internet shortcut files (.url)
function Get-ShortcutIcon {
[CmdletBinding()]
Param (
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
[Alias('FullName')]
[string]$Path # needs to be an absulute path
)
switch ([System.IO.Path]::GetExtension($Path)) {
'.lnk' {
$WshShell = New-Object -ComObject WScript.Shell
$shortcut = $WshShell.CreateShortcut($Path)
$iconPath = $shortcut.IconLocation
$iconInfo = if ($iconPath -match '^,(\d+)') {
[PsCustomObject]@{ IconPath = $shortcut.TargetPath; IconIndex = [int]$matches[1] }
}
else {
[PsCustomObject]@{ IconPath = $iconPath; IconIndex = 0 }
}
# clean up
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($shortcut)
$null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($WshShell)
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
# return the icon information
$iconInfo
}
'.url' {
$content = Get-Content -Path $Path -Raw
$iconPath = [regex]::Match($content, '(?im)^\s*IconFile\s*=\s*(.*)').Groups[1].Value
$iconIndex = [regex]::Match($content, '(?im)^\s*IconIndex\s*=\s*(\d+)').Groups[1].Value
[PsCustomObject]@{ IconPath = $iconPath; IconIndex = [int]$iconIndex }
}
default { Write-Warning "'$Path' does not point to a '.lnk' or '.url' shortcut file.." }
}
}
Upvotes: 4