![]() |
IShellLink SetPath gibt E_INVALIDARG zurück
Hallo ihr :).
Da ich (mal wieder) nichts Passendes zu meinem Problem finde, bitte ich euch erneut um Hilfe. Gegeben sei folgender Code:
Delphi-Quellcode:
FShellLink und FPersistFile sind eigentlich in einer Klasse deklariert, aber darum soll es nicht gehen. Die Methode
uses ShlObj, ActiveX, ComObj;
const IID_IPersistFile: TGUID = ( D1:$0000010B;D2:$0000;D3:$0000;D4:($C0,$00,$00,$00,$00,$00,$00,$46)); var FShellLink: IShellLink; FPersistFile: IPersistFile; var Lfile: string; begin OleCheck(CoCreateInstance(CLSID_ShellLink, nil, CLSCTX_INPROC_SERVER, {$IFDEF UNICODE}IID_IShellLink{$ELSE}IID_IShellLinkA{$ENDIF}, FShellLink)); OleCheck(FShellLink.QueryInterface(IID_IPersistFile, FPersistFile)); Lfile:= 'blub.exe'; // Lfile:= 'C:\blub.exe'; // Lfile:= '.\blub.exe'; OleCheck(FShellLink.SetPath(PChar(Lfile))); end;
Delphi-Quellcode:
wirft immer E_INVALIDARG (0x80070057) raus, wenn man einen Dateinamen ohne Pfad im Funktionsparameter übergibt [ADD], und diese Datei nicht existiert (auch nicht im %PATH%) [/ADD]. Steht in dem Parameter ein Laufwerk oder ein relativer Pfad (kommentierte Zuweisungen an Lfile oben), ist alles in Ordnung. Und das obwohl es die Datei in KEINEM der o.g. Fälle gibt.
SetPath
Kann sich - oder besser noch mir ;) - das jemand erklären? MfG Dalai |
AW: IShellLink SetPath gibt E_INVALIDARG zurück
Ich habe
![]()
Delphi-Quellcode:
Der Code scheint auch ohne Pfadangabe zu funktionieren. Zumindest mit der calc.exe... ;)
uses ShlObj, ActiveX, ComObj;
... procedure TForm1.Button1Click(Sender: TObject) ; var IObject : IUnknown; ISLink : IShellLink; IPFile : IPersistFile; PIDL : PItemIDList; InFolder : array[0..MAX_PATH] of Char; TargetName : String; LinkName : WideString; begin TargetName := 'calc.exe'; {Use TargetName:=ParamStr(0) which returns the path and file name of the executing program to create a link to your Application} IObject := CreateComObject(CLSID_ShellLink) ; ISLink := IObject as IShellLink; IPFile := IObject as IPersistFile; with ISLink do begin SetPath(pChar(TargetName)) ; //SetWorkingDirectory(pChar(ExtractFilePath(TargetName))) ; end; // if we want to place a link on the Desktop SHGetSpecialFolderLocation(0, CSIDL_DESKTOPDIRECTORY, PIDL) ; SHGetPathFromIDList(PIDL, InFolder) ; { or if we want a link to appear in some other, not-so-special, folder: InFolder := 'c:\SomeFolder' } LinkName := InFolder + '\Delphi Created Link.lnk'; IPFile.Save(PWChar(LinkName), false) ; end; |
AW: IShellLink SetPath gibt E_INVALIDARG zurück
Mein Code oben funktioniert auch mit calc.exe, das ist nicht das Problem. Dein Code verhält sich übrigens genauso. Einfach ein OleCheck um SetPath setzen und staunen (bei nicht existierenden Dateien) ;).
Es geht nur um nicht existierende Dateien. Klar, macht keinen Sinn, eine Verknüpfung zu einer solchen Datei zu erstellen, aber darum geht es nicht. Ich kann nicht kontrollieren, was der Nutzer für Eingaben in meiner Software macht, und auch nur sehr begrenzt abfangen/umwandeln bzw. im %PATH% suchen. Ich wüsste gern, warum das mit Angabe des Pfads funktioniert, aber ohne nicht. MfG Dalai |
AW: IShellLink SetPath gibt E_INVALIDARG zurück
Ach, noch eine Info: unter Win2k arbeitet die Funktion "normal", sie setzt allerdings dem Dateinamen den Pfad zum Desktop des aktuellen Nutzers voran, so dass dann im Beispiel
Code:
rauskommt. Ab XP gibt es das E_INVALIDARG.
C:\Dokumente und Einstellungen\Administrator\Desktop\blub.exe
MfG Dalai |
AW: IShellLink SetPath gibt E_INVALIDARG zurück
Wenn sonst keiner eine Idee hat, werde ich die Exception fangen, diese dem Nutzer anzeigen (beides bereits der Fall) und in die FAQ/Known Issues einen Hinweis auf das "Problem" aufnehmen, der die Ursache erklärt. Gern würde ich das schöner machen, aber da ich nicht weiß, woran es genau liegt, und noch weniger, wie ich es beheben/umgehen/abfangen soll, sehe ich keine andere Möglichkeit.
MfG Dalai |
AW: IShellLink SetPath gibt E_INVALIDARG zurück
![]() Runterblätter bis zum 2. Beitrag von "Sprint". Könnte helfen/umsetzbar sein ;-) |
AW: IShellLink SetPath gibt E_INVALIDARG zurück
Und was genau davon soll mir helfen? Oder anders gefragt: Wo ist die Verbindung zu diesem Problem hier? :gruebel:
MfG Dalai |
AW: IShellLink SetPath gibt E_INVALIDARG zurück
Zitat:
"SetPath wirft immer E_INVALIDARG (0x80070057) raus, wenn man einen Dateinamen ohne Pfad..." aus #1 :oops: Aber das Result von FileExists() ist Dir schon bekannt, oder? if FileExists() then Setpath... else Fehlermeldung(). LG |
AW: IShellLink SetPath gibt E_INVALIDARG zurück
Die Verwendung von FileExists würde voraussetzen, dass die Datei IMMER zuverlässig gefunden wird, egal ob 32 oder 64 Bit System, egal ob WOW64, egal ob Umgebungsvariable oder sonstwas. Könntest du das mit einem Algorithmus garantieren? Ich nicht. Man kann mit PathFindOnPath und FileSearch eine ganz brauchbare Annäherung erreichen, aber eine hundertprozentige Garantie geben die auch nicht her. Daher bin ich zu o.g. Entschluss gelangt, bevor ich zuviel "Kollateralschaden" verursache.
MfG Dalai |
AW: IShellLink SetPath gibt E_INVALIDARG zurück
Wenn Dir fileExists() nicht genügt, dann schildere Dein Problem bitte etwas genauer und auf das Wesentliche reduziert.
Lt. #1 gehts Dir um "Dateinamen ohne Pfad"? Was willst Du denn von dem (möglicherweise) frei erfundenen Dateinamen wissen? Wer bekommt den Dateinamen der nicht existierenden Datei von wem? Sorry, möglicherweise kapiere ich Dein Problem einfach nicht :oops: ===== P.S. Willst Du den "VirtualStore" oder wie immer das Ding heißt, mit einem in Stein gemeißelten Pfad (egal ob XP, >Vista 32-bit oder >Vista 64-bit) auf der Festplatte ermitteln? |
AW: IShellLink SetPath gibt E_INVALIDARG zurück
Zitat:
Zitat:
Zitat:
Zitat:
Zitat:
MfG Dalai |
AW: IShellLink SetPath gibt E_INVALIDARG zurück
Zitat von Dir aus #11:
"Das steht bereits in #3: der Nutzer gibt den Dateinamen, mit oder ohne Pfad, in meine Software ein. Ob die Datei existiert, kann ich erst danach ermitteln, und das tue ich auch, um deren Eigenschaften anzuzeigen (optional)." Aha. Ich - als Nutzer - kann also "DepperterDepp.Du" als Dateinamen eintippen und Du musst herausfinden, ob es die Datei gibt? Scheint mir eine geniale Lösung zu sein: Den Nutzer einen (frei erfundenen) Dateinamen eingeben zu lassen... Viel Spaß beim Suchen! |
AW: IShellLink SetPath gibt E_INVALIDARG zurück
Zitat:
Bis dahin bleibe ich dabei, die Exception zu zeigen, und so die Verantwortung an den Nutzer zurückzugeben. Wenn der Nutzer irgendwas nicht-existierendes eingibt, ist das sein Problem. MfG Dalai |
AW: IShellLink SetPath gibt E_INVALIDARG zurück
Der "zuverlässig Algo" ist recht einfach. Alle Partitionen durchsuchen und die Fundstellen ggfs. noch mit der "heutigen" Uhrzeit vergleichen. Dauert halt ein wenig bei 0,5 bis 2,3 TB auf lokalen Datenträgern ;-)
Danach könnte man noch - um die Zuverlässigkeit zu erhöhen - noch alle Clouds weltweit überprüfen. Dauert halt noch ein wenig länger, denn wer weiß denn schon, wohin der Nutzer gerade gespeichert hat... Was spricht dagegen, den Nutzer dazu zu ZWINGEN, einen SaveDialog zu verwenden? Also: Du willst Sachen im Universum zuverlässig und schnell finden, die es möglicherweise nicht gibt? Das würde ich mal als gediegen "anspruchsvoll" bezeichnen wollen ;-) Aber noch ziemlich harmlos - verglichen mit dem Abfangen eines SaveDialog.Filenames aus einem Paralleluniversums der Stringwelten! SCNR |
AW: IShellLink SetPath gibt E_INVALIDARG zurück
Tja, das Wesentliche war wohl doch zu stark reduziert...
Dem Nutzer wird die Möglichkeit gegeben, eine Kommandozeile zu editieren, unter anderem die von Verknüpfungen. Ob es da nun einen Dialog zur Auswahl einer Datei gibt oder nicht, spielt keine Rolle, weil der Nutzer trotzdem in der Eingabe frei ist und sein muss; ein Savedialog macht in dem Zusammenhang aber überhaupt keinen Sinn. Diese Kommandozeile wird dann von mir auseinandergenommen und in Datei und Parameter gesplittet. Diese beiden Strings werden dann im Falle von Verknüpfungen an SetPath und SetArguments übergeben. Die Datei wird gesucht, um ggf. deren Eigenschaften zu ermitteln und anzuzeigen. Aber diese Suche hat eben Grenzen. Ich habe einfach keine Lust, alle möglichen "Tricks" von Windows nachzuahmen, um auch wirklich alles zu unternehmen, die Datei zu finden. Es ist ja nicht nur der %PATH%, der durchsucht wird. Nein, es gibt da noch so tolle Sachen wie
Code:
wo Dateinamen drinstehen, die irgendwo liegen können und Windows findet die auch dann, wenn dessen Verzeichnis nicht im %PATH% steht. Und wahrscheinlich gibt's da noch andere Dinge, an die ich nicht einmal gedacht habe. Und mit jeder Windows-Version könnte etwas Neues hinzukommen.
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths
Du siehst also: so simpel ist das nicht. Daher beschränke ich den Algorithmus auf das Wesentliche, und zeige dem Nutzer die Exception, wenn er - ob absichtlich oder nicht - einen nicht-existierenden Dateinamen angibt. MfG Dalai |
AW: IShellLink SetPath gibt E_INVALIDARG zurück
Und so ein Kommandozeilen-Eingabefenster muss echt sein, denn der Nutzer muss den Rechner (und Dein Programm) auch wirklich echt Verschrotten können? Ehrensache!
Ohne PC hätte ich deutlich weniger PC-Probleme... :wink::wink::wink: |
AW: IShellLink SetPath gibt E_INVALIDARG zurück
Wirklich ein hilfreicher Beitrag ... echt, Ehrensache ... :roll:
Hättest du ein Problem und jemand würde dir mit einer solchen Antwort kommen, würde dir das helfen? Ich glaube kaum. Ich bin ja dankbar für Hilfe und ich hab auch nichts gegen Kommentare und Witze, aber keines davon vermag ich deinem Beitrag zu entnehmen. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:20 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz