In einer .NET 4.0-Anwendung (WPF) verwenden wir SHGetFileInfo
um Shell-Symbole für einen Verzeichnisbaum zu erhalten. Da dies in manchen Fällen recht lange dauert (z. B. bei einem nicht erreichbaren Netzlaufwerk oder einem Diskettenlaufwerk), wollten wir dies in einem Thread erledigen und das Symbol dann aktualisieren, wenn es eingelesen wurde.
Der Aufruf ist im Grunde derselbe, er wird jetzt nur innerhalb eines Threads ausgeführt. Weil jemand sagte, dass der Thread sein muss STA
damit dies funktioniert, haben wir für die Tests Thread statt ThreadPool verwendet, mit den gleichen Ergebnissen. Verwendung von ThreadPool
hat ebenfalls nicht funktioniert.
SHGetFileInfo
ist erfolgreich (gibt 1 zurück), aber das hIcon-Mitglied in der Struktur ist Null.
IntPtr GetIcon(string name)
{
Shell32.SHFILEINFO shfi = new Shell32.SHFILEINFO();
uint flags = Shell32.SHGFI_ICON | Shell32.SHGFI_USEFILEATTRIBUTES | Shell32.SHGFI_SMALLICON;
Shell32.SHGetFileInfo(
name, System.IO.Directory.Exists(name) ? Shell32.FILE_ATTRIBUTE_DIRECTORY : Shell32.FILE_ATTRIBUTE_NORMAL,
ref shfi,
(uint) System.Runtime.InteropServices.Marshal.SizeOf(shfi),
flags );
return shfi.hIcon;
}
Derselbe Code funktioniert auch über den GUI-Thread. Was muss getan werden, damit die Funktion von einem separaten Thread aus funktioniert, oder, wie auch immer, damit sie funktioniert, ohne den GUI-Thread zu blockieren?
Update: Der Code dazu ist im Grunde folgender:
var thread = new System.Threading.Thread(() => {
var result = GetIcon("C:\\");
// ... do something with the result
});
thread.SetApartmentState(System.Threading.ApartmentState.STA);
thread.Start();
wenn nur die Zeilen innerhalb des Thread-Delegaten gelassen werden, funktioniert es gut (aber auf dem GUI-Thread, natürlich).
Aktualisierung: Im Moment rufen wir nur den Aufruf von SHGetFileInfo
damit es funktioniert. Dies hat den Vorteil, dass das ursprüngliche Problem (die Seite mit der Dateiansicht wurde erst angezeigt, nachdem alle Symbole geladen waren) gelöst wurde, obwohl es bedeutet, dass die Seite für jedes Symbol hängen bleibt. Aber zumindest sieht der Benutzer jetzt, dass etwas vor sich geht. Wir sind immer noch auf der Suche nach einer tatsächlichen Lösung für das Problem.