ExtractAssociatedIcon, ExtractIconExW, ExtractIcon mit Autoit3

  • Hi Liebe Autoit Gemeinde,
    ich will mich kurz halten & gleich zum Punkt kommen. Ich versuche eine Möglichkeit zu finden um .exen die icons zu stiebitzen. Dabei viel mir auf das 'ExtractAssociatedIcon' von der 'shell32' sich den ersten gefundenen .ico schnappt. welcher bei Autoit exen eine schlechte qualität hat. Deshalb erhöhte ich die Zahl & bekam das icon das ich wollte. Jedoch sind die Icons bei fast jeder exe anders angelegt. Manche besitzen nur 'einen'.


    So kam ich auf die idee gleich eine Ganze icon gruppe herauszuladen damit ich dem Problem direkt entgehen kann schlecht qualitative Icons zu bekommen. Das ist allerdings etwas das ich nicht weiß umzusetzen. Da ich im Umgang mit DLL's ziehmlich unerfahren bin.


    ich glaube das die Funktion 'ExtractIconExW' wie für mich gemacht ist.

    Keine ahnung wie ich die Zeile zu füllen habe :<
    Local $Ret = DllCall('shell32', 'long', ''ExtractIconExW', 'int', 0, 'str', $Path, 'int*', 1)


    hier ein Beispiel script:


  • So kam ich auf die idee gleich eine Ganze icon gruppe herauszuladen...

    Wieso nicht gleich alle?

    Mit alle meine ich, alle vorhandenen Icons anzeigen und dann auswählen, welche davon in welchem Format (jpg, png, ...) gespeichert werden sollen.
    Ich habe ein halb fertiges Script, mit dem das geht... werde mich die Tage mal dran setzen und es fertig schreiben.

    Keine ahnung wie ich die Zeile zu füllen habe :<

    Wenn du mit Dll-Calls noch nicht so gut bewandert bist, solltest du besser die dafür bereits vorhandenen API-Funktionen benutzen.

    Local $Ret = DllCall('shell32', 'long', ''ExtractIconExW', 'int', 0, 'str', $Path, 'int*', 1)

    $Path, der Name der Exe, Dll oder des Icons/Icon-Library (*.icl), von dem das Icon extrahiert werden soll, ist der einzige Parameter, den du vor dem Aufruf deklarieren musst.

    Hier schon mal vorab eine minimalistische Lösung für dich.

    7 Mal editiert, zuletzt von Bitnugger (1. April 2017 um 02:28)

  • Wieso nicht gleich alle?

    Mit alle meine ich, alle vorhandenen Icons anzeigen und dann auswählen, welche davon in welchem Format (jpg, png, ...) gespeichert werden sollen.
    Ich habe ein halb fertiges Script, mit dem das geht... werde mich die Tage mal dran setzen und es fertig schreiben.

    Dann bin ich tatsächlich nicht der einzige der das versucht, cool cool. Ich kann mir denken das es bei dem einem oder anderem Program ein Problem geben wird wenn alle Icons ausgelesen werden sollen. Wenn ich mir so z.b. Autoit Exen ansehe sind min. 2 Icon gruppen auslesbar.[Blockierte Grafik: https://s10.postimg.org/i1yc7b5yx/Unbenannt.jpg]
    Ich kann mir gut vorstellen das hierbei Probleme entstehen werden.

    $Path, der Name der Exe, Dll oder des Icons/Icon-Library (*.icl), von dem das Icon extrahiert werden soll, ist der einzige Parameter, den du vor dem Aufruf deklarieren musst.

    Ja danke dir, ich hätte die frage allerdings besser formulieren sollen, mir ist nicht bewusst woher ich weiß wie die Ganze zeile auszufüllen ist, $Path kam von mir doch von dem rest der Zeile weiß ich nichts. (hier markiert mit fragezeichen)
    Local $Ret = DllCall('shell32', 'long(?)', ''ExtractIconExW', 'int(?)', 0(?), 'str(?)', $Path, 'int*(?)', 1(ICON))

    Hier schon mal vorab eine minimalistische Lösung für dich.

    Ich danke dafür & habe jetzt auch Zeit mir diese Anzusehen. War mir nicht bewusst das Autoit soetwas auch kann.

  • Ich kann mir gut vorstellen das hierbei Probleme entstehen werden.

    Nein, die Sache muss man dann lediglich anders angehen... wenn du willst kann ich dir ja schon mal das unfertige Script hier hochladen, damit du darin schnuppern kannst, wie es in dem Fall gemacht werden kann.

    Ja danke dir, ich hätte die frage allerdings besser formulieren sollen, mir ist nicht bewusst woher ich weiß wie die Ganze zeile auszufüllen ist, $Path kam von mir doch von dem rest der Zeile weiß ich nichts. (hier markiert mit fragezeichen)
    Local $Ret = DllCall('shell32', 'long(?)', ''ExtractIconExW', 'int(?)', 0(?), 'str(?)', $Path, 'int*(?)', 1(ICON))

    Mehr gibt es in dieser Zeile nicht, was du da noch ausfüllen müsstest. Hier mal ein erleuchtender Link für dich zu einer super Seite von @BugFix: Dll-Tutorial für AutoIt

    Noch ein Tip... wenn du in SciTE mit dem Caret auf einem Funktionsnamen stehts, kannst du mit Strg + j zu dieser Funktion springen, auch wenn diese mit den Includes geladen wurde. Dort kannst du dir dann anschauen, wie der DllCall auszusehen hat und welche Parameter hier erwartet werden.

    Hier ein Bsp:

    AutoIt
    Func _WinAPI_ShellExtractIcon($sIcon, $iIndex, $iWidth, $iHeight)
    	Local $aRet = DllCall('shell32.dll', 'int', 'SHExtractIconsW', 'wstr', $sIcon, 'int', $iIndex, 'int', $iWidth, _
    			'int', $iHeight, 'ptr*', 0, 'ptr*', 0, 'int', 1, 'int', 0)
    	If @error Or Not $aRet[0] Or Not $aRet[5] Then Return SetError(@error, @extended, 0)
    	; If Not $aRet[0] Then Return SetError(1000, 0, 0)
    
    
    	Return $aRet[5]
    EndFunc   ;==>_WinAPI_ShellExtractIcon
  • Vielleicht kannst du ja auch den IconFileScanner von Holger Kotsch verwenden. Nutze ich immer, um mir die Icon in exe/dll anzusehen.

    Mit Windows 10 funktioniert der IconFileScanner jedenfalls nicht, da er nur wenige der "gefundenen Icons" anzeigt und mit der tatsächlich vorhandenen Anzahl auch total daneben liegt. Zudem will ich mir die Icons nicht nur anschauen können, sondern sie auch in dem von mir gewünschten Format speichern können, was in meinem Tool auch funktioniert.

    Beispiel: explorer.exe
    Der IconFileScanner findet 29 Icon groups, meint aber, es seien Icons, zeigt davon nur 2 an... beide aus der ersten Icon group... beide in derselben Größe 32x32.
    Mein Tool findet 29 Icon groups und insgesamt 233 Icons... zeigt davon 5 NICHT an... und alle in der Original-Größe!

    Derzeit kämpfe ich noch mit zwei Problemen...

    • Wie bekomme ich die Icons ($hIcon) mit Transparenz in das Pic-Control ($hBitmap)?
    • Wie bringe ich GDIPlus dazu, auch Icons die nur zwei Farben haben, als Bitmap anzuzeigen? (die 5 Icons, die in meinem Bild komplett schwarz sind...)

    Erstes Problem habe ich versucht mit _ScreenCapture_CaptureWnd() zu lösen, wobei die Transparenz soweit auch erhalten bleibt, aber das Bild insgesamt blasser wird.

    IconFileScanner.png_ExtractIcon.png _ScreenCapture_CaptureWnd.png

    4 Mal editiert, zuletzt von Bitnugger (2. April 2017 um 11:57)

  • Saubere Arbeit, allerdings sehen die Extrahierten Icons übel aus. So das mir die idee kam hier ein DllCall zu nutzen. Mir fehlt da allerdings immer noch die erfahrung. Ich werde mich wohl sicher bis nächstes Jahr nochmal damit befassen & dann eine Lösung finden. Ich geb dem Thema dann mal einen Hacken! Ihr habt mir wie immer gut geholfen.