Laden...

Shell32 als COM Objekt unter verschiedenen Windows Versionen nutzen

Erstellt von brave_snoopy vor 8 Jahren Letzter Beitrag vor 8 Jahren 4.743 Views
B
brave_snoopy Themenstarter:in
99 Beiträge seit 2011
vor 8 Jahren
Shell32 als COM Objekt unter verschiedenen Windows Versionen nutzen

Hallo,

ich verwende einige Funktionen aus der shell32.dll. Mein Entwicklungssystem ist derzeit ein Windows 10 mit Visual Studio 2015 Community.

Auf diesem Funktioniert alles wunderbar.
Wenn ich nun mein Programm auf einem Windows 7 ausführe, erhalte ich diese Fehlermeldung:

Fehlermeldung:
Das COM-Objekt des Typs "Shell32.ShellClass" kann nicht in den Schnittstellentyp "Shell32.IShellDispatch6" umgewandelt werden. Dieser Vorgang konnte nicht durchgeführt werden, da der QueryInterface-Aufruf an die COM-Komponente für die Schnittstelle mit der IID "{286E6F1B-7113-4355-9562-96B7E9D64C54}" aufgrund des folgenden Fehlers nicht durchgeführt werden konnte: Schnittstelle nicht unterstützt (Ausnahme von HRESULT: 0x80004002 (E_NOINTERFACE)).

Nach ein wenig Recherche klingt es danach, dass die Shell32.dll unterschiedlich zwischen den Betriebssystemen ist.
In meiner Anwendung habe ich die shell32 als Referenz hinzugefügt und auf INTEROP gesetzt. Sie wird daher auch mit in das Ausgabeverzeichnis beim Build kopiert mit interop.shell32.dll

Hat jemand eine Idee, wie ich mein Programm unter allen Windows Versionen ans laufen bekomme?

Hinweis von Coffeebean vor 8 Jahren

Bitte benutze die richtigen [Hinweis] Wie poste ich richtig? Punkt 6Tags

1.029 Beiträge seit 2010
vor 8 Jahren

Hi,

nun - die Fehlermeldung klingt für mich recht sinnig - und dass der Fehler fliegt ist auch normal - du hast die Win10 Shell verwendet, die IShellDispatch6 implementiert.

Diese Schnittstelle erweitert IShellDispatch um eine Funktionalität mit der AppSearchPane, die es unter Windows 7 gar nicht gibt.

Es ist nicht so, dass ich mich mit der Materie wirklich auskenne - aber ich denke die Shell zu referenzieren war ein Fehler - die paar Male, wo ich die Shell gebraucht hab - hab ich mir auf pinvoke die nötigen Sachen rausgesucht und diese so gesteuert.

Mein Tipp: www.pinvoke.net - die benötigten Funktionen per DLLImport einbinden und gut ist.

LG

B
brave_snoopy Themenstarter:in
99 Beiträge seit 2011
vor 8 Jahren

Hallo Taipi88,

danke für die Info. Der Fehler tritt bei diesem Aufruf der shell32 auf.


        public string GetShortcutTargetPath(string shortcutFilename)
        {
            
            string pathOnly = System.IO.Path.GetDirectoryName(shortcutFilename);
            string filenameOnly = System.IO.Path.GetFileName(shortcutFilename);

            Shell32.Shell shell = new Shell32.ShellClass();
            Shell32.Folder folder = shell.NameSpace(pathOnly);
            Shell32.FolderItem folderItem = folder.ParseName(filenameOnly);
            if (folderItem != null)
            {
                Shell32.ShellLinkObject link =
            (Shell32.ShellLinkObject)folderItem.GetLink;
                return link.Path;
            }
            return ""; // not found
        }

Leider kann ich mit dem PInvoke nicht viel anfangen.
Kannst du mir dabei bitte auf die Sprünge helfen?

Vielen Dank und Gruss
Stefan

3.003 Beiträge seit 2006
vor 8 Jahren

PINvoke (Platform Invoke) erlaubt die Einbindung einzelner Funktionen der Plattform, auf der das .NET-Programm läuft. Unmittelbare Folge davon ist, dass, sofern die aufgerufene Methode auf der Plattform (WIn-Version) vorhanden ist, sie benutzt werden kann, egal welche Windowsversion.

Anstatt dich also auf eine bestimmte .dll zu verlassen, die eine Funktion enthält, die du benötigst, verlass dich lieber darauf, dass auf dem Client eine dll vorhanden ist, die eine Variante der Funktion enthält, die du benötigst.

Nebeneffekt ist, dass du nicht eine dll voller Funktionen, die du gar nicht benötigst, mitliefern musst.

Beispiele und Vorgehensweisen enthält der Link, den Taipi88 gepostet hat.

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

B
brave_snoopy Themenstarter:in
99 Beiträge seit 2011
vor 8 Jahren

Hallo,

danke für die Antworten. Mit P/Invoke habe ich mich nun ein wenig vertraut gemacht. Zum Beispiel wende ich es erfolgreich für die Funktion "ExtractAssociatedIcon" aus der shell32.dll an. Allerdings ist dies eine Funktion.
ExtractAssociatedIcon function

Bei meinem Problem geht es um ein Object aus der shell32. Bzw. um ein Interface. IShellLinkW.
Siehe: IShellLink

Leider bin ich nicht wirklich weiter gekommen, wie ich diese Methoden/Objekte mittels P/Invoke aufrufe.

Könnt ihr mir bitte dazu auf die Sprünge helfen.
Vielen Dank.

1.029 Beiträge seit 2010
vor 8 Jahren

Hi,

für den IShellLinkW wird es in der Tat aufwänder - eine Implementierung davon hast du ja sicher gefunden und zumindest zum kompilieren gebracht oder?
Falls nicht - woran hängt es?

Prinzipiell brauchst du nämlich nicht nur IShellLinkW - sondern auch IPersistFile - denn letztlich musst du:

  1. Mit IPersistFile Zugriff auf die Datei erhalten
  2. Diese Datei laden um an eine Instanz von IShellLinkW zu kommen
  3. Auf diese Instanz GetPath aufrufen

LG

Edit: Da das durchaus in Arbeit ausartet - hab ich Google mal bemüht, wo relativ häufig das "Windows Script Host Model" erwähnt wird:
How do i get the path name from a file shortcut

Vll hilft das ja noch...

B
brave_snoopy Themenstarter:in
99 Beiträge seit 2011
vor 8 Jahren

Hallo Taipi88,

die WSH Schnittstelle zu nutzen war dann gestern in der Tat mein Workaround. Scheint auch relativ schnell zu laufen.

Ich werde dann wohl dabei erstmal bleiben.

Vielen Dank.

1.029 Beiträge seit 2010
vor 8 Jahren

Hi,

der Vollständigkeit halber noch ein Link zur Umsetzung mit IShellLinkW und IPersistFile:

https://chiplegend.wordpress.com/2013/03/26/how-to-resolve-a-lnk-in-c/

LG