Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Icons aus EXE-/DLL-Datei extrahieren

Moderationshinweis von herbivore (20.11.2008 - 08:17:19):

Dies ist ein Thread, auf den aus der FAQ verwiesen wird. Bitte keine weitere Diskussion, sondern nur wichtige Ergänzungen und diese bitte knapp und präzise. Vielen Dank!

fusionwedge
myCSharp.de - Member



Dabei seit:
Beiträge: 27

Themenstarter:

Icons aus EXE-/DLL-Datei extrahieren

beantworten | zitieren | melden

Hallo,

wie erhalte ich bitte aus einer DLL-, einer EXE-, oder einer anderen Datei ein Symbol, um es in

meinem TreeView anzeigen lassen zu können?
Ich habs mit dem Icon-Konstruktor versucht, der akzeptiert aber nur ".ico"-dateien.
private Nachricht | Beiträge des Benutzers
_tb_
myCSharp.de - Member



Dabei seit:
Beiträge: 416

beantworten | zitieren | melden

Hi,

du kannst es mal mit der SDK Funktion ExtractIconEx versuchen und dann das Handle mit Icon.FromHandle konvertieren
private Nachricht | Beiträge des Benutzers
fusionwedge
myCSharp.de - Member



Dabei seit:
Beiträge: 27

Themenstarter:

beantworten | zitieren | melden

Danke.

Aber das wird bei mir in der Dokumentation nicht angezeigt (ich habe vom Framework nur die Dokumentation von 1.0, liegt es daran?).
In welchem Namespace liegt diese Methode, was ist der Rückgabewert und womit Überlade ich sie?
private Nachricht | Beiträge des Benutzers
_tb_
myCSharp.de - Member



Dabei seit:
Beiträge: 416

beantworten | zitieren | melden

Die Funktion ExtractIconEx gibts nicht im FrameWork, also auch in keinem Namespace. Du musst sie also direkt über die Windows API aufrufen.

Folgendermaßen wird sie deklariert. Beachte dass du die Icons am Ende noch zerstören musst um den reservierten Speicherplatz wieder freizugeben.

[DllImport("shell32.dll", CharSet=CharSet.Auto)]
 static extern uint ExtractIconEx(string szFileName, int nIconIndex,
   IntPtr[] phiconLarge, IntPtr[] phiconSmall, uint nIcons);

[DllImport("user32.dll", SetLastError=true)]
 static extern int DestroyIcon(IntPtr hIcon);
 

den Rückgabewert von ExtractIconEx übergibst du dann an Image.FromHandle.

Getestet hab ich das allerdings nicht, sollte aber eigentlich funktionieren.
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 52329
Herkunft: Berlin

beantworten | zitieren | melden

Hallo fusionwedge,

ExtractIcon ist eine eine Funktion von dem Win32-API, die du dir mit DllImport reinholen kannst.

Was deine eigentliche Frage angeht. Mir ist nicht genau klar, was du willst.

1) Icons aus bestehenden .exe und .dll Dateien rausziehen, sodass man nachher, das Icon auf der Platte hat?

Dafür gibt es extra Tools, z.B. PE Resource Explorer von http://www.wilsonc.demon.co.uk/d7resourceexplorer.htm oder Resource Hacker von http://www.users.on.net/johnson/resourcehacker/ .

2) Icons in die .exe-Datei deines Programms einbinden, um alles in der .exe-Datei komplett zu haben, um nicht mit separaten .ico-Dateien hantieren zu müssen?

Dazu musst du das Icon in eine .resources-Datei packen die du dann per Compliler-Option /res:<name>.resources einbinden kannst. Zugriff auf das Icon bekommst du mit


rm = new ResourceManager ("<name>", GetType().Assembly);
Icon = (Icon)rm.GetObject ("<name>.ico");

Für das Erstellen von .ressource-Dateien (zur Compile-Zeit) kann man die Klasse ResourceWriter verwenden. Ich habe mir ein keines (allerdings nicht allgemein verwendbares) Tools dafür geschrieben, dass diese Klasse benutzt.

3) Icons zur Laufzeit aus anderen .exe-Dateien laden?

In diesem Fall ist wohl wirklich ExtractIcon angezeigt.

HTH

herbivore
private Nachricht | Beiträge des Benutzers
fusionwedge
myCSharp.de - Member



Dabei seit:
Beiträge: 27

Themenstarter:

beantworten | zitieren | melden

Danke für die Antworten.
Wo gibt es denn eine Libary über alle API-Funktionen?
ExtractIconEx habe ich übrigens noch in meiner Visual C++6.0 Dokumentation gefunden, aber halt ohne DLL-Namen.

Ich meinte Nummer 3.

Ich wollte direkt von jeder Datei das im Explorer angezeigte Icon sehen. Und wie bekomme ich die Symbole der anderen Dateien (z.B. Txt, Doc, etc).
Ich dachte, ich finde die Pfadangaben der Bilder in der Registry, aber ich finde den (theoretisch) passenden Schlüssel nicht.
Ich wollte nämlich gerne eine Anzeige aller Ordner und Daten samt Icons haben.
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 52329
Herkunft: Berlin

beantworten | zitieren | melden

Hallo fusionwedge,

die Pfade der Icons stehen schon in der Registry. Für z.B. .txt-Dateien guckst du unter HKEY_CLASSES_ROOT\.txt und findest im Standardwert den Eintrag txtfile. Damit guckst du jetzt unter HKEY_CLASSES_ROOT\txtfile\DefaultIcon und findest dort "%SystemRoot%\system32\shell32.dll,-152" also das Icon mit dem Index 152 in der Datei %SystemRoot%\system32\shell32.dll. Die Icons müssen in der DLL als Win32-Ressourcen gespeichert sein, um auf diese weise ansprechbar zu sein.

HTH

herbivore
private Nachricht | Beiträge des Benutzers
fusionwedge
myCSharp.de - Member



Dabei seit:
Beiträge: 27

Themenstarter:

beantworten | zitieren | melden

Super, danke.

Ich würde euch gerne bewerten, aber das ist ja scheinbar nicht möglich!

Wo finde ich eine Dokumentation zur API?
private Nachricht | Beiträge des Benutzers
_tb_
myCSharp.de - Member



Dabei seit:
Beiträge: 416

beantworten | zitieren | melden

Moderationshinweis von herbivore (06.08.2013 - 08:05:23):

Link aktualisiert


Bspw. ExtractIconEx function

Wie du das ganze dann in C# einbinden kannst, kannst du bei http://www.pinvoke.net nachlesen
private Nachricht | Beiträge des Benutzers
GIJOE
myCSharp.de - Member

Avatar #avatar-1627.jpg


Dabei seit:
Beiträge: 142

beantworten | zitieren | melden

Hallo @fusionwedge,

Ich würde auch gerne die Symbole von den Dateien, die ich in die ListView lese mit anzeigen lassen. Bin leider noch ein Anfänger, und hab es mit API Funktionen noch nicht so. Was heisen soll, das ich mein Vorhaben einfach nicht auf die Reihe bringe.



Ich wäre dir, wenn du mir helfen könntest sehr dankbar!
Gruss, GIJOE

Auch Anfänger haben recht auf Leben!
private Nachricht | Beiträge des Benutzers
fusionwedge
myCSharp.de - Member



Dabei seit:
Beiträge: 27

Themenstarter:

beantworten | zitieren | melden

Sorry, bin leider nicht oft hier.
Wenn du dich hier noch mal meldest (dann weiß ich ja, dass du das liest), dann erklär ichs dir.
private Nachricht | Beiträge des Benutzers
GIJOE
myCSharp.de - Member

Avatar #avatar-1627.jpg


Dabei seit:
Beiträge: 142

beantworten | zitieren | melden

Hallo!

Habs glesen.
Gruss, GIJOE

Auch Anfänger haben recht auf Leben!
private Nachricht | Beiträge des Benutzers
fusionwedge
myCSharp.de - Member



Dabei seit:
Beiträge: 27

Themenstarter:

beantworten | zitieren | melden

Gut.
Was ist denn genau dein Problem?
Hast du schon eine ListView und brauchst nur noch die Symbole, oder brauchst du noch eine Art Explorer, um die Dateien zu finden?

Fusionwedge
private Nachricht | Beiträge des Benutzers
GIJOE
myCSharp.de - Member

Avatar #avatar-1627.jpg


Dabei seit:
Beiträge: 142

beantworten | zitieren | melden

@fusionwedge

Hab da schon was gefunden, mit dem kannst du aus jeder Datei das Icon ziehn.
Der einzige Nachteil ist, das die Auflösung zu wünschen übrig läst. Kann aber auch an den Einstellungen liegen. Aber man kann damit leben!

	[StructLayout(LayoutKind.Sequential)]
	public struct SHFILEINFO
	{
		public IntPtr hIcon;
		public IntPtr iIcon;
		public uint dwAttributes;
		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
		public string szDisplayName;
		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
		public string szTypeName;
	}

	public class ExtractIcon
	{
		/// <summary>
		/// Methode zum extrahieren von einem Icon aus einer Datei.
		/// </summary>
		/// <param name="FilePath">Hier übergeben Sie den Pfad der Datei von dem das Icon extrahiert werden soll.</param>
		/// <param name="Small">Bei übergabe von true wird ein kleines und bei false ein großes Icon zurück gegeben.</param>
		public static Icon GetIcon(string FilePath ,bool Small)
		{
			IntPtr hImgSmall;    
			IntPtr hImgLarge;         
			SHFILEINFO shinfo = new SHFILEINFO();
			if (Small)
			{
				hImgSmall = Win32.SHGetFileInfo(FilePath, 0, 
					ref shinfo,(uint)Marshal.SizeOf(shinfo),
					Win32.SHGFI_ICON |Win32.SHGFI_SMALLICON);
			}
			else
			{
				hImgLarge = Win32.SHGetFileInfo(FilePath, 0,
					ref shinfo, (uint)Marshal.SizeOf(shinfo),
					Win32.SHGFI_ICON | Win32.SHGFI_LARGEICON);
			}
			return(System.Drawing.Icon.FromHandle(shinfo.hIcon));
		}
	}

	/// <summary>
	/// DLL Definition für IconExtract.
	/// </summary>
	class Win32
	{
		public const uint SHGFI_ICON = 0x100;
		public const uint SHGFI_LARGEICON = 0x0;
		public const uint SHGFI_SMALLICON = 0x1;

		[DllImport("shell32.dll")]
		public static extern IntPtr SHGetFileInfo(string pszPath,
			uint dwFileAttributes,
			ref SHFILEINFO psfi,
			uint cbSizeFileInfo,
			uint uFlags);
	}
Gruss, GIJOE

Auch Anfänger haben recht auf Leben!
private Nachricht | Beiträge des Benutzers
fusionwedge
myCSharp.de - Member



Dabei seit:
Beiträge: 27

Themenstarter:

beantworten | zitieren | melden

Wenn ich das richtig verstehe, dann musst du beim Aufruf von

GetIcon(string FilePath ,bool Small)

für den Wert Small "false" eingeben. Dann wird das große Bild zurückgegeben und du hast ne bessere Auflösung:

also so

GetIcon("C:\\BlaBlaBla\\Bla.txt", false);

Kann aber auch sein, dass du ein kleines Bild haben willst, dann musst du "true" eingeben:


GetIcon("C:\\BlaBlaBla\\Bla.txt", false);

Hoffe, dass das dein Problem ist (was ich aber nicht glaube, weil das zu offensichtlich wäre... :D)
private Nachricht | Beiträge des Benutzers
GIJOE
myCSharp.de - Member

Avatar #avatar-1627.jpg


Dabei seit:
Beiträge: 142

beantworten | zitieren | melden

@fusionwedge

Ich weis wie ich das anzuwenden habe, dachte nur weil du doch auch danach gesucht hast!
Gruss, GIJOE

Auch Anfänger haben recht auf Leben!
private Nachricht | Beiträge des Benutzers
GIJOE
myCSharp.de - Member

Avatar #avatar-1627.jpg


Dabei seit:
Beiträge: 142

beantworten | zitieren | melden

@fusionwedge
Wie regelst du das mit den Icons jetzt, über die Registry?
Gruss, GIJOE

Auch Anfänger haben recht auf Leben!
private Nachricht | Beiträge des Benutzers
fusionwedge
myCSharp.de - Member



Dabei seit:
Beiträge: 27

Themenstarter:

beantworten | zitieren | melden


using Microsoft.Win32;

// IntPtr ist ein Handle des Icons
// GetIcons()[0] gibt das große Symbol zurück und GetIcons()[1] das kleine
// Z.B. so: Icon tmp = Icon.FromHandle(GetIcons("txt", "C:\\Test\\", TestItem)[0]);
// Sonst bei fragen bitte melden. Ich hab das jetzt nämlich nicht alles umgeschrieben...

protected IntPtr[] GetIcons(string endung, string pfad, ListViewItem item)
		{
			RegistryKey key;
			
			IntPtr[] Icos	= new IntPtr[2];
			
			IntPtr[] Symbolgross	= new IntPtr[1];
			IntPtr[] Symbolklein	= new IntPtr[1];
			
/* Wenn es keinen Eintrag in der Registry für die Endung gibt, kommt catch ins Spiel (z.b.: bei .EXE und .LNK Dateien)*/
			try{
				key	= Registry.ClassesRoot.OpenSubKey(endung, true);
				
				string str		= key.GetValue(null).ToString();
				key				= Registry.ClassesRoot.OpenSubKey(str + "\\DefaultIcon", true);
				str				= key.GetValue(null).ToString();
				string temp		= str;
				int index2		= 1;
				
				while(true)
				{
					temp	= temp.Remove(0, temp.Length - index2);
					temp	= temp.Remove(1, index2 - 1);
					if(temp	== ",")
					{
						break;
						// Ende if
					}
					temp	= str;
					index2++;
					// Ende while
				}
				temp = str.Remove(0, str.Length - index2 + 1);
				
				ExtractIconEx(str.Remove(str.Length - index2, index2), Int32.Parse(str.Remove(0, str.Length + 1 - index2)), Symbolgross, Symbolklein, 1);
				Icos[0]	= Symbolgross[0];
				Icos[1]	= Symbolklein[0];
				// Ende try
			}
			catch(Exception)
			{
				if((endung.ToUpper() == ".EXE") || (endung.ToUpper() == ".LNK"))
				{
					if(ExtractIconEx(pfad + "\\" + item.Text + endung, 0, Symbolgross, Symbolklein, 1) == 0)
					{
						ExtractIconEx(Environment.SystemDirectory + "\\System32\\Shell32.dll", 0, Symbolgross, Symbolklein, 1);
						// Ende if
					}
					// Ende if
				}
				else
				{
/* Wenn es sich um eine unbekannte Endung handelt, dann wähle ein Standarticon*/
					ExtractIconEx(Environment.SystemDirectory + "\\System32\\Shell32.dll", 0, Symbolgross, Symbolklein, 1);
					// Ende else
				}
				Icos[0]	= Symbolgross[0];
				Icos[1]	= Symbolklein[0];
				// Ende catch
			}
			 return Icos;
			// Ende GetIcons()
		}
private Nachricht | Beiträge des Benutzers
GIJOE
myCSharp.de - Member

Avatar #avatar-1627.jpg


Dabei seit:
Beiträge: 142

beantworten | zitieren | melden

@fusionwedge

Interessante Lösung über die Reg, bin begeistert.
Gruss, GIJOE

Auch Anfänger haben recht auf Leben!
private Nachricht | Beiträge des Benutzers
fusionwedge
myCSharp.de - Member



Dabei seit:
Beiträge: 27

Themenstarter:

beantworten | zitieren | melden

Danke, die ist ja von "herbivore" (danke noch mal).

Hoffe, ich konnte dir helfen.
private Nachricht | Beiträge des Benutzers
Programmierhans
myCSharp.de - Experte

Avatar #avatar-1651.gif


Dabei seit:
Beiträge: 4318
Herkunft: Zentralschweiz

beantworten | zitieren | melden

Weiterer interessanter Link wie extrahiere ich Icon's aus Dll's.

StolenIcon

Programmierhans
Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...
private Nachricht | Beiträge des Benutzers
winSharp93
myCSharp.de - Experte

Avatar #avatar-2918.png


Dabei seit:
Beiträge: 6155
Herkunft: Stuttgart

beantworten | zitieren | melden

Zitat von Programmierhans
Weiterer interessanter Link wie extrahiere ich Icon's aus Dll's.
Dann aber bitte immer die Lizenz prüfen, ob diese das auch zulässt!
private Nachricht | Beiträge des Benutzers