Extrahieren Sie alle icons aus EXE ohne mithilfe der ExtractIconEx

Muss ich extrahieren Sie alle Symbole aus einer EXE-Datei und speichern Sie Sie als Dateien auf der Festplatte, aber ich kann nicht für die einfachste Lösung (ExtractIconEx) da Brauch ich zu extrahieren, die ICO-Dateien in einer Weise, bewahrt das große Symbole, sogar, wenn der code läuft auf Systemen mit Windows XP. Ich werde später extrahieren wollte Symbole (128x128 und in anderen vista Größe der Symbole) verwenden anderen code, aber ich brauche einen Weg zu extrahieren Sie alle Symbole, mit all Ihren Ressourcen, wie Sie in der EXE-Datei, unabhängig davon, ob der PC mein code läuft mit XP, Vista oder Win7.

So weit ich weiß, die icons sind in den RT_GROUP_ICONS.

Ich kenne einige Leute getan haben muss, diese zuvor in Delphi, weil Hilfsmittel wie IcoFX-und Ressourcen-explorer scheinen dies getan haben. Ich habe einmal erinnere mich an eine komplett open-source Delphi-tool, das es tun würde, aber es war vor Jahren.

Zu formulieren, ich habe das problem mit ExtractIconEx - Es wird nicht auf die gesamte .ico-Datei, es wird nur ein Auszug der unterstützten Symbol-Ressource-Formate, die jemals auf eine einzige Auflösung (Größe), die von der Plattform unterstützt. Also auf XP, zum Beispiel, wird es extrahieren Sie eine 32x32 oder 48x48-icon, aber nicht im Vista-format 128x128 Symbol.

Update: Dies ist eine modifizierte version der akzeptierten Antwort, das löst mein Zukunftssicherheit sorgen. wenn irgendwie die Funktion, die wir aufrufen war zu verschwinden User32.dll in einer zukünftigen windows-version, ich würde wollen, dass es scheitern mehr anmutig, als zu scheitern, zu laden, bis meine ganze Anwendung.

unit ExtractIconUtils;

interface

uses Graphics,Forms,Windows;

//----------------------------------------------------------------------------
// ExtractIcons
// Call "private" MS Api to extract Icon file. This calls a publically
// documented function marked as deprecated in the MSDN documentation.
// It was no doubt Not Originally Intended to be documented, or publically
// accessed, but it provides functionality that its hard to live without.
// It exists on Windows 2000, XP, Vista, and Windows7, but might not exist
// in some future Windows version (released after year 2011).
//
// uses global   hUserDll    : THandle;
//----------------------------------------------------------------------------
function ExtractIcons(exeFilename,icoOutFileName:String;icoSize:Integer):Boolean;



var
  hUserDll    : THandle;





implementation



function ExtractIcons(exeFilename,icoOutFileName:String;icoSize:Integer):Boolean;
const
{$ifdef UNICODE}
 ExtractProcName='PrivateExtractIconsW';
{$else}
 ExtractProcName='PrivateExtractIconsA';
{$endif}
type
  TExtractFunc = function(lpszFile: PChar; nIconIndex, cxIcon, cyIcon: integer; phicon: PHANDLE; piconid: PDWORD; nicon, flags: DWORD): DWORD; stdcall;
var
  hIcon   : THandle;
  nIconId : DWORD;
  Icon    : TIcon;
  PrivateExtractIcons:TExtractFunc;
begin
  result := false;
  if (hUserDll<4) then begin
    hUserDll := LoadLibrary('user32.dll');
    if (hUserDll<4) then exit;
  end;

     { PrivateExtractIcons:
        MSDN documentation says that this function could go away in a future windows
        version, so we must try to load it, and if it fails, return false, rather than
        doing a static DLL import.
     }
    PrivateExtractIcons :=     GetProcAddress(hUserDll, ExtractProcName);

    if not Assigned(PrivateExtractIcons) then exit;

    //extract a icoSize x icoSize  icon where icoSize is one of 256,128,64,48,32,16
    if PrivateExtractIcons ( PWideChar(exeFilename),
                            0, icoSize, icoSize, @hIcon, @nIconId, 1, LR_LOADFROMFILE) <>0 then
    try
      Icon:=TIcon.Create;
      try
        Icon.Handle:=hIcon;
        Icon.SaveToFile(icoOutFileName);
        result := true;
      finally
        Icon.Free;
      end;
    finally
      DestroyIcon (hIcon);
    end;
end ;


initialization
  // none

finalization
   if (hUserDll>4) then
      FreeLibrary(hUserDll);

end.
  • Vista icons sind 256px PNG-Bilder, nicht 128px, FWIW
  • sind Sie versucht, die PrivateExtractIcons Funktion ? msdn.microsoft.com/en-us/library/ms648075
  • Es ist eine funktionale Idee arbeiten, aber es macht mir Angst, dass es brechen wird in der Zukunft (Dank MSDN!)
  • sehr schön-code aktualisieren! 🙂 Ich war gerade auf der Suche nach so etwas wie dieses. BTW, ich glaube, dass DestroyIcon ist nicht erforderlich, da Icon.Free behandelt, die über die interne FImage: TIconImage.
  • Sie wählen, durch die compiler-Option für die Verwendung von ANSI-oder WIDE-Funktion aufrufen, aber dann müssen Sie die Verwendung von PChar statt PWideChar ;o) und bewegen Sie den hUserDLL in den implementation-Abschnitt zu machen, unit global und nicht global auf alle, sondern nur Nebeneffekte zu reduzieren
InformationsquelleAutor Warren P | 2011-05-10
Schreibe einen Kommentar