Wie kann ich ein Symbol mit einer bekannten DLL-ID direkt anzeigen?

Wie kann ich ein Symbol mit einer bekannten DLL-ID direkt anzeigen?

Weiß jemand, wie man ein Symbol direkt in seinem „Registry“-Format anzeigen kann? Beispielsweise ist „%SystemRoot%\system32\shell32.dll,112“, also C:\Windows\System32\shell32.dll,112, normalerweise die ID eines Symbols, wie sie in den Registrierungsdaten für den Wert „IconPath“ zu finden ist. Der Pfad ist real, der Symbolcode „112“ nur eine Zufallszahl.

Der Punkt ist, dass es mühsam ist, das richtige Symbol zu finden, wenn die DLL aus Hunderten von Symbolen besteht, selbst wenn man ein Tool wieSymbolextraktor, das Symbolinformationen anzeigt, wenn der Cursor über die Symbole fährt. Alle diese Tools scheinen nur umgekehrt zu funktionieren: Man muss die DLL laden und dann hoffen, das Symbol mit dem entsprechenden Code zu finden.

Antwort1

Die Symbole für Dateitypen sind Ressourcen (d. h. alle Arten von Bildern, Medien usw.), die in bekannte DLLs eingebettet sind. Diese Symbolnummer (oder Symbolgruppenindex) ist nicht zufällig. DLL-Dateien haben einen Abschnitt zum Speichern dieser Ressourcen. Jedes Symbol wird mit einer eindeutigen Nummer gespeichert. Ein Symboltyp kann aus unterschiedlichen Symbolgrößen, Abmessungen und Bittiefen bestehen. Diese Symbol-ID ergibt sich aus der Symbolgruppennummer, sodass sich beim Ändern der Zoomstufe durch den Benutzer nur die Symbolgröße und nicht das Symbol selbst ändert.

Dies lässt sich anhand eines Beispiels leicht nachvollziehen. Für diesen Fall verwende ichRessourcen-Hacker. Hier sind die Screenshots der Symbole der Shortcut-Dateien (Erweiterung .LNK) in Resource Hacker (Symbole können abweichen):

Resource_Hacker_Shell32

Und hier sind die Registrierungseinstellungen:

Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\.lnk\ShellNew]
"Handler"="{ceefea1b-3e29-4ef1-b34c-fec79c4f70af}"
"IconPath"="%SystemRoot%\system32\shell32.dll,-16769"
"ItemName"="@shell32.dll,-30397"
"MenuText"="@shell32.dll,-30318"
"NullFile"=""

Sehen Sie die Nummer "16769", vergleichen Sie sie mit dem Screenshot. Aber wie öffnet man sie inRessourcen-Hacker? Antwort: Laden Sie die Software herunter und führen Sie sie aus --> Kopieren Sie sie shell32.dll(oder eine beliebige DLL-/EXE-Datei) in Ihren Desktop-/Arbeitsordner --> ziehen Sie die Datei in das Resource Hacker-Fenster --> Doppelklicken Sie auf die „Symbolgruppe“ --> Scrollen Sie zu dieser Nummer. Beachten Sie, dass sich in einer Symbolgruppe viele Symbole befinden, was ihre Abmessungen (16 x 16, 20 x 20 usw.) betrifft. Diese stehen für unterschiedliche Zoomstufen im Datei-Explorer.

Antwort2

Es ist mühsam, das richtige Symbol zu finden, wenn die DLL aus Hunderten von Symbolen besteht

Sie können das folgende Powershell-Skript verwenden .\DisplayIcon.ps1:

<#
.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
)

$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
        $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]"

# Loosely based on http://www.vistax64.com/powershell/202216-display-image-powershell.html

[void][reflection.assembly]::LoadWithPartialName("System.Windows.Forms")

$img = [System.Drawing.Image]::Fromfile($TargetIconFilePath);

# This tip from http://stackoverflow.com/questions/3358372/windows-forms-look-different-in-powershell-and-powershell-ise-why/3359274#3359274
[System.Windows.Forms.Application]::EnableVisualStyles();
$form = new-object Windows.Forms.Form
$form.Text = "Image Viewer"
$form.Width = $img.Size.Width;
$form.Height =  $img.Size.Height;
$pictureBox = new-object Windows.Forms.PictureBox
$pictureBox.Width =  $img.Size.Width;
$pictureBox.Height =  $img.Size.Height;

$pictureBox.Image = $img;
$form.controls.add($pictureBox)
$form.Add_Shown( { $form.Activate() } )
$form.ShowDialog()
#$form.Show();

Beispielausgabe:

> .\DisplayIcon.ps1 -SourceEXEFilePath 'C:\Windows\system32\shell32.dll' -TargetIconFilePath 'f:\test\Myicon.ico' -IconIndexNo 41
Icon file can be found at [f:\test\Myicon.ico]

Bildbeschreibung hier eingeben

Anmerkungen:

  • Dieses Skript wurde unter Verwendung der unten aufgeführten Quellen erstellt.
  • Dank anBen NInRoot-Zugrifffür seine Hilfe beim Debuggen des Codes.

Quellen:

verwandte Informationen