Benutzer mit den meisten Antworten
Icon aus .exe laden (per Shell32) liefert kein Ergebnis

Frage
-
Hallo,
ich möchte aus einer .exe den Icon extrahieren. Da diese .exe leider auf einem Netzwerk-Share liegt, muss ich diesen leider wohl über P-Invoke (Interop) laden.
Da ich auf diesem Gebiet noch unerfahren hab, hab ich mir per Internet und C#-Beispielen folgende Funktion zusammengebaut:
<DllImport("Shell32", CharSet:=CharSet.Auto, SetLastError:=True)> _ Public Shared Function ExtractAssociatedIcon(ByVal hInst As IntPtr, ByVal builder As StringBuilder, ByRef pIcon As UShort) As Boolean End Function Public Shared Function returnIcon(ByVal pFileName As String) As System.Drawing.Icon Dim uicon As UShort Dim builder As New StringBuilder(pFileName) Dim handle As IntPtr = ExtractAssociatedIcon(IntPtr.Zero, builder, uicon) Dim result As Icon = Icon.FromHandle(handle) Return result End Function
Leider liefert mir diese keinen Icon zurück (result = empty)Hat jemand eine Idee ?
Vielen Dank
Antworten
-
Hallo,
nichts desto trotz hast Du das Rad neu erfunden ;-)
Die Methode wird bereits durch die Icon-Klasse als ExtractAssociatedIcon-Methode bereitgestellt.
Der DLLImport erwartet als letzten Parameter einen ByRef Integer:
<DllImport("shell32.dll", BestFitMapping = false, CharSet = CharSet.Auto, EntryPoint = "ExtractAssociatedIcon") > _ Public Shared Function ExtractAssociatedIcon(ByVal hInst As IntPtr, ByVal iconPath As StringBuilder, ByRef index As Integer) As IntPtr End Function
(abgeleitet aus System.Drawing.SafeNativeMethods - ohne HandlefRef)Gruß Elmar
- Als Antwort vorgeschlagen Robert BreitenhoferModerator Donnerstag, 20. Oktober 2011 14:46
- Als Antwort markiert Robert BreitenhoferModerator Donnerstag, 20. Oktober 2011 16:10
-
Hallo,
bei einem ByRef Parameter spielt es schon eine Rolle ob die Variable zwei (short) oder vier Byte (integer) hat.
denn die API-Funktion schreibt da auch zurück.Gruß Elmar
- Als Antwort vorgeschlagen Robert BreitenhoferModerator Donnerstag, 20. Oktober 2011 14:45
- Als Antwort markiert Robert BreitenhoferModerator Donnerstag, 20. Oktober 2011 16:10
-
Ach ich bin doch blind, hab den Fehler gefunden:
Ich musste noch den Rückgabewert der 'ExtractAssociatedIcon'-Funktion auf IntPtr ändern.
- Als Antwort markiert Ralf Stiegele Donnerstag, 20. Oktober 2011 11:06
- Bearbeitet Robert BreitenhoferModerator Donnerstag, 20. Oktober 2011 13:21 Formatierung
Alle Antworten
-
Ach ich bin doch blind, hab den Fehler gefunden:
Ich musste noch den Rückgabewert der 'ExtractAssociatedIcon'-Funktion auf IntPtr ändern.
- Als Antwort markiert Ralf Stiegele Donnerstag, 20. Oktober 2011 11:06
- Bearbeitet Robert BreitenhoferModerator Donnerstag, 20. Oktober 2011 13:21 Formatierung
-
Hallo,
nichts desto trotz hast Du das Rad neu erfunden ;-)
Die Methode wird bereits durch die Icon-Klasse als ExtractAssociatedIcon-Methode bereitgestellt.
Der DLLImport erwartet als letzten Parameter einen ByRef Integer:
<DllImport("shell32.dll", BestFitMapping = false, CharSet = CharSet.Auto, EntryPoint = "ExtractAssociatedIcon") > _ Public Shared Function ExtractAssociatedIcon(ByVal hInst As IntPtr, ByVal iconPath As StringBuilder, ByRef index As Integer) As IntPtr End Function
(abgeleitet aus System.Drawing.SafeNativeMethods - ohne HandlefRef)Gruß Elmar
- Als Antwort vorgeschlagen Robert BreitenhoferModerator Donnerstag, 20. Oktober 2011 14:46
- Als Antwort markiert Robert BreitenhoferModerator Donnerstag, 20. Oktober 2011 16:10
-
Hallo,
nichts desto trotz hast Du das Rad neu erfunden ;-)
Die Methode wird bereits durch die Icon-Klasse als ExtractAssociatedIcon-Methode bereitgestellt.
Der DLLImport erwartet als letzten Parameter einen ByRef Integer:
<DllImport("shell32.dll", BestFitMapping = false, CharSet = CharSet.Auto, EntryPoint = "ExtractAssociatedIcon") > _ Public Shared Function ExtractAssociatedIcon(ByVal hInst As IntPtr, ByVal iconPath As StringBuilder, ByRef index As Integer) As IntPtr End Function
(abgeleitet aus System.Drawing.SafeNativeMethods - ohne HandlefRef)Gruß Elmar
Die Extract-Methode funktioniert ja wie beschrieben nicht, da sich die .exe auf einem Netzwerk-Laufwerk befindet, welcher nur per \\Server\Pfad... angesprochen werden kann.
Darum sieht das dann so aus:
If FileIO.FileSystem.FileExists(_CurrentAppPath) Then Try picBoxApplicationIcon.Image = Icon.ExtractAssociatedIcon(_CurrentAppPath).ToBitmap Catch exArgument As ArgumentException 'Fehler abfangen bei Shares picBoxApplicationIcon.Image = SharedFunctions.returnIcon(_CurrentAppPath).ToBitmap End Try End if
Ist dieser Integer-Parameter wichtig ? Denn es scheint bisher mit meiner Methode problemlos zu funktionieren.
- Bearbeitet Ralf Stiegele Donnerstag, 20. Oktober 2011 12:52 Typo
-
Hallo,
bei einem ByRef Parameter spielt es schon eine Rolle ob die Variable zwei (short) oder vier Byte (integer) hat.
denn die API-Funktion schreibt da auch zurück.Gruß Elmar
- Als Antwort vorgeschlagen Robert BreitenhoferModerator Donnerstag, 20. Oktober 2011 14:45
- Als Antwort markiert Robert BreitenhoferModerator Donnerstag, 20. Oktober 2011 16:10
-
Ist dieser Integer-Parameter wichtig ? Denn es scheint bisher mit meiner Methode problemlos zu funktionieren.
Hallo RQ-1,
Ich verwende ihm zum Beispiel eine gewisse Icon zu extrahieren.
[VB.NET Code]
Imports System.Runtime.InteropServices Imports System.Text Imports System.IO Imports System.Drawing.Imaging Imports System.ComponentModel Public Class Form1 Private Declare Auto Function ExtractAssociatedIcon Lib "shell32" ( _ ByVal hInst As IntPtr, ByVal path As String, ByRef index As Integer) As IntPtr Private Declare Auto Function DestroyIcon Lib "user32" (ByVal hIcon As IntPtr) As Boolean Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click Dim myIcon As Icon = ExtractIcon("C:\Windows\System32\moricons.dll", 3) '//ist die 4 Icon aus der Liste (0 based) '//Dim myIcon As Icon = ExtractIcon("C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe") Dim imageStream As Stream = New MemoryStream() Dim bmp As Bitmap = myIcon.ToBitmap() bmp.Save(imageStream, ImageFormat.Jpeg) PictureBox1.Image = Image.FromStream(imageStream) imageStream.Close() End Sub Public Shared Function ExtractIcon(ByVal path As String, Optional ByVal index As Integer = 0) As Icon Dim handle As IntPtr = ExtractAssociatedIcon(IntPtr.Zero, path, index) If handle = IntPtr.Zero Then Throw New Win32Exception(Marshal.GetLastWin32Error()) Dim retval As Icon = Nothing Using temp As Icon = Icon.FromHandle(handle) retval = CType(temp.Clone(), Icon) DestroyIcon(handle) End Using Return retval End Function End Class
Kleiner Hinweis: Die 'System.Drawing.Icon.ExtractAssociatedIcon' und die ExtractAssociatedIcon extrahieren nur ein 32 x 32 Pixel-Icon. (“Both the ExtractAssociatedIcon and 'System.Drawing.Icon.ExtractAssociatedIcon' extract only a 32x32 pixels icon.”)…und vielleicht möchtest Du auch 16 x 16 Pixel-Icons bekommen: Building a Better ExtractAssociatedIcon
Grüße,
Robert