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!
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.
Hi,
du kannst es mal mit der SDK Funktion ExtractIconEx versuchen und dann das Handle mit Icon.FromHandle konvertieren
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?
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.
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.
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/ .
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.
In diesem Fall ist wohl wirklich ExtractIcon angezeigt.
HTH
herbivore
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.
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
Super, danke.
Ich würde euch gerne bewerten, aber das ist ja scheinbar nicht möglich!
Wo finde ich eine Dokumentation zur API?
Link aktualisiert
Bspw. ExtractIconEx function
Wie du das ganze dann in C# einbinden kannst, kannst du bei http://www.pinvoke.net nachlesen
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! 😁
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.
Hallo!
Habs glesen.
Gruss, GIJOE
Auch Anfänger haben recht auf Leben! 😁
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
@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! 😁
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... 😄)
@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! 😁
@fusionwedge
Wie regelst du das mit den Icons jetzt, über die Registry?
Gruss, GIJOE
Auch Anfänger haben recht auf Leben! 😁
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()
}
@fusionwedge
Interessante Lösung über die Reg, bin begeistert.
Gruss, GIJOE
Auch Anfänger haben recht auf Leben! 😁
Danke, die ist ja von "herbivore" (danke noch mal).
Hoffe, ich konnte dir helfen.
Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...
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!