![]() |
Verknüpfung erstellen
So, dann kommen wir mal zu Delphi zurück. :mrgreen:
Wenn ich eine Checkbox Checke, dann soll eine Verknüpfung auf dem Desktop erstellt werden. Wenn ich den Hacken wieder wegmach, dann soll die Verknüpfung wieder gelöscht werden. Das nächste Problem, ist weiss nicht auf welchem System das Programm läuft. Es muss also von Win95 bis WinXP funktionieren. Wie macht man sowas? Vielen Dank. |
Moin Daniel,
ich hab' hier mal 'ne alte Demo für das anlegen eines Shortcuts als solches
Code:
Die bedarf zwar noch einiger Überarbeitung, aber funktioniert soweit.
Procedure NewShellLink(Const pcsFileToLinkTo : String); // Auf diese Datei soll verwiesen werden
const // Fehlende Deklaration in Delphi // Zu finden in der Registry // HKEY_CLASSES_ROOT\Interface // nach IPersistFile suchen IID_IPersistFile: TGUID = '{0000010b-0000-0000-C000-000000000046}'; Var slShellLink : IShellLink; // ShellLink Interface pfPersistFile : IPersistFile; // Shortcut (Link) Permanent speichern wsShortCut : PWideChar; // Buffer für den Shortcutnamen hRes : HResult; // Für Zwischenergebnisse sShortCut : String; // So heisst dann der Shortcut Begin CoInitialize(nil); // COM Library Initialisieren (einmal pro Thread deshalb hier eigentlich // Fehl am Platze :( // COM Object der Klasse ShellLink erzeugen hRes := CoCreateInstance(CLSID_ShellLink, // ID von ShellLink (Typ TGUID) nil, CLSCTX_INPROC_SERVER, IID_IShellLinkA, // Referenz auf die Funktion slShellLink); // erhält nach erfolgreichem Aufruf // den Pointer auf die Funktion if hRes = S_OK then Begin slShellLink.SetPath(PChar(pcsFileToLinkTo)); // Auf diese Datei geht der Link hRes := slShellLink.QueryInterface(IID_IPersistFile, // wieder mal einen pfPersistFile); // Pointer holen end; if hRes = S_OK then Begin GetMem(wsShortCut,MAX_PATH shl 1); // Speicher reservieren für den Shortcutpfadnamen // Eigentlich genügt die Länge MAX_PATH, aber da // der Wert in UNICode zurückgegeben wird mal 2 sShortCut := ChangeFileExt(pcsFileToLinkTo,'.LNK'); // Soll einfach mal so heissen, // Wie die aufzurufende Datei MultiByteToWideChar(CP_ACP, // ANSI Codepage benutzen 0, PChar(sShortCut), // Der soll konvertiert werden -1, // der zu konvertierende String ist Null terminiert wsShortCut, // und hier soll das Ergebnis rein MAX_PATH shl 1); // Länge von wsShortCut pfPersistFile.Save(wsShortCut, TRUE); // Jetzt noch den Link speichern FreeMem(wsShortCut,MAX_PATH shl 1); // und den Platz wieder freigeben end; end; procedure TForm1.Button1Click(Sender: TObject); begin if Opendialog1.Execute then Begin NewShellLink(OpenDialog1.FileName); end; end; Wenn ich dazu komm' wird die noch mal aktualisiert. Beim ersten Parameter von pfPersistFile.Save müsste noch der Pfad ausgetauscht werden, denn in diesem Beispiel zeigt der auf das gleiche Verzeichnis, in dem auch die Datei liegt, auf die der Link geht. Jetzt ist noch die Frage, welchen Desktop Folder Du meinst. Current User oder All Users. |
hi,
1. ich blick da überhaupt nciht mehr durch. Sieht irgendwie chaotisch aus. Und sooo viiieel. 2. Hmm... ich würd sagen alle User. |
Was brauche ich da noch für Units?
Ich hab sooooo viele Fehler. [Fehler] Einst.pas(194): Undefinierter Bezeichner: 'IShellLink' [Fehler] Einst.pas(195): Undefinierter Bezeichner: 'IPersistFile' [Fehler] Einst.pas(200): Undefinierter Bezeichner: 'CoInitialize' [Fehler] Einst.pas(203): Undefinierter Bezeichner: 'CoCreateInstance' [Fehler] Einst.pas(203): Undefinierter Bezeichner: 'CLSID_ShellLink' [Fehler] Einst.pas(205): Undefinierter Bezeichner: 'CLSCTX_INPROC_SERVER' [Fehler] Einst.pas(206): Undefinierter Bezeichner: 'IID_IShellLinkA' Das sind nur mal die wichtigsten. |
ActiveX, würde ich sagen. :-)
|
Uuuaa. Ich hab nur D6PE. Ist es da überhaupt dabei?
|
Moin Daniel,
ich hab' s noch mal überarbeitet:
Code:
Wie Mathias so richtig sagte, die Unit ACTIVEX muss noch mit eingebunden werden, sowie SHLOBJ.
// Der Einfachheit halber heisst der Link genauso, wie die Datei
function CreateDesktopLink(const p_sFilePath : string;const p_sDesktopDir : string) : Boolean; const // Fehlende Deklaration in Delphi // Zu finden in der Registry // HKEY_CLASSES_ROOT\Interface // nach IPersistFile suchen IID_IPersistFile: TGUID = '{0000010b-0000-0000-C000-000000000046}'; var slShellLink : IShellLink; // ShellLink Interface pfPersistFile : IPersistFile; // Shortcut (Link) Permanent speichern wszShortCut : PWideChar; // Buffer für den Shortcutnamen hRes : HResult; // Für Zwischenergebnisse sShortCut : string; // So heisst dann der Shortcut dwLen : DWORD; begin Result := false; // COM Object der Klasse ShellLink erzeugen hRes := CoCreateInstance(CLSID_ShellLink, // ID von ShellLink (Typ TGUID) nil, CLSCTX_INPROC_SERVER, IID_IShellLinkA, // Referenz auf die Funktion slShellLink); // Pointer auf IShellLink Interface if hRes <> S_OK then begin exit; end; slShellLink.SetPath(PChar(p_sFilePath)); // Auf diese Datei geht der Link hRes := slShellLink.QueryInterface(IID_IPersistFile,pfPersistFile); // Pointer auf IPersist holen if hRes <> S_OK then begin exit; end; dwLen := (MAX_PATH+1)*2; wszShortcut := AllocMem(dwLen); try sShortCut := ChangeFileExt(p_sFilePath,'.LNK'); sShortCut := p_sDesktopDir + '\' + ExtractFileName(sShortCut); StringToWideChar(sShortCut,wszShortCut,dwLen); hRes := pfPersistFile.Save(wszShortCut, TRUE); // Jetzt noch den Link speichern finally FreeMem(wszShortCut,dwLen); // und den Platz wieder freigeben end; Result := (hRes = S_OK); end; procedure TForm1.Button1Click(Sender: TObject); var szDesktopFolder : PChar; begin if Opendialog1.Execute then begin szDesktopFolder := StrAlloc(MAX_PATH+1); try if not SHGetSpecialFolderPath(self.Handle,szDesktopFolder,CSIDL_COMMON_DESKTOPDIRECTORY,false) then begin ShowMessage(SysErrorMessage(GetLastError)); exit; end; if not CreateDesktopLink(OpenDialog1.FileName,szDesktopFolder) then begin ShowMessage(SysErrorMessage(GetLastError)); end; finally StrDispose(szDesktopFolder); end; end; end; initialization begin CoInitialize(nil); end; finalization begin CoUninitialize; end; Ich hoffe, dass ich jetzt nicht vergessen habe irgendetwas freizugeben, aber so funktioniert's Eingestellt ist All Users, sollte es mal der Current User sein sollen, musst Du CSIDL_COMMON_DESKTOPDIRECTORY durch CSIDL_DESKTOPDIRECTORY austauschen. SHGetSpecialFolderPath funktioniert unter NT 4 und Win 95 ab IE 4.0, ansonsten muss man sich mal nach einer anderen Variante umsehen diesen Pfad zu ermitteln. Wichtig Bei userspezifischer Installation kann man nicht den Namen des angemeldeten Users als Teil des Pfades annehmen, da bei eventueller Umbenennung des Accounts der Profilpfad nicht geändert wird, sondern noch den alten Namen enthält. Das CoInitialize und CoUninitialize muss einmal pro Thread durchgeführt werden, sollte also sinnvoller Weise in der Projektdatei, oder der Unit des Hauptformulares stehen. ***EDIT*** Ich hab' die doppelte Initialisierung :oops: von wszShortCut mal gelöscht. Der Test unter D6PE war auch erfolgreich, nur zu Deiner Beruhigung. ***EDIT, die zweite*** Das löschen geht dann schlicht mit DeleteFile. Den Pfad zu der Link Datei zu ermitteln dürfte jetzt wohl nicht die Schwierigkeit sein. |
1. was muss ich jetzt genau in die Uses aufnehmen?
2. es schreckt mich doch sehr ab. Ich versteh keine einzige Zeile. 3. der OpenDialog bringt mir überhaupt nichts. Ich habe eben nur eine Checkbix, sonst nichts. Ich klicke sie an oder aus. Das muss scho n langen. ich hba mir gedacht das ist vielleicht im Ordner c:\windows\desktop oder C:\winnt\allusers\....\desktop die Verknüpfung erstelle. Aber nicht jeder hat sein System auf C. Hmm... also, irgenwie vergeht mir die Lust an der ganzen sache. |
Moin Daniel,
das IShellLink Interface ist für die Shortcuts zuständig. Als erstes wird einmal eine Instanz davon erzeugt, und ein Pointer darauf zurückgegeben. Wenn das geklappt hat wird der Pfad auf die Datei gesetzt, für die ein Shortcut angelegt werden soll. Um den Shortcut speichern zu können, wird dann ein Pointer auf das IPersistFile Interface geholt, damit auf dessen Funktionen zugegriffen werden kann. War das von Erfolg gekrönt, wird noch der komplette Pfad des Shortcuts erzeugt und in einen Widestring umgewandelt. Anschliessend wird dieser dann gespeichert (pfPersistFile.Save(...,true)). True damit die Datei auch gespeichert wird. In der OnClick Routine des Buttons wird der absolute Pfad des Desktop Ordners geholt. Zu 1. In Uses musst Du natürlich ActiveX und ShlObj aufnehmen. Zu 2. Verlangt ja auch niemand. Schau Dir doch das ganze auch mal im PSDK an. Zu 3. Der OpenDialog dient doch nur der Auswahl der Datei :shock: , auf die der Shortcut gesetzt werden soll. Ich denke mal, dass Du den Pfad dahin in Deinem Programm wohl selber wirst festlegen können. |
Hey, es funktioniert. Ich hba aber nur ME. Das geht also auch unter NT/XP?!?
Den OpenDialog muss ich rausschmeissen. Ich brauch ja nur die Verknüpfung zu meinem Prog. Nicht anderes. Ich will ja nicht einfach nur Verknüpfungen erstellen. Also, ExtractFilePath, o.ä. Klasse, Danke. :D |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:13 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