AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi Fehler bei eigenem Installationsprogramm - Verknüpfung
Thema durchsuchen
Ansicht
Themen-Optionen

Fehler bei eigenem Installationsprogramm - Verknüpfung

Ein Thema von Yheeky · begonnen am 7. Nov 2002 · letzter Beitrag vom 12. Nov 2002
Antwort Antwort
Yheeky

Registriert seit: 7. Jun 2002
1.339 Beiträge
 
#1

Fehler bei eigenem Installationsprogramm - Verknüpfung

  Alt 7. Nov 2002, 15:44
Hi,

ich habe folgendes Problem: Ich habe eine eigene Installationsroutine geschrieben. Soweit - sogut, funktioniert jedenfalls fast alles, bis auf das manche ein Problem haben mein Programm zu installieren. Bei manchen Leuten geht´s bei manchen nicht. Ich möchte für mein Programm eine Verknüpfung auf dem Desktop erstellen (*.lnk Datei) und verwende dafür folgende Funktion:

Code:
procedure NewShellLink(Const pcsFileToLinkTo : String);
const IID_IPersistFile: TGUID = '{0000010b-0000-0000-C000-000000000046}';
var
slShellLink : IShellLink;
pfPersistFile : IPersistFile;
wsShortCut : PWideChar;
hRes : HResult;
sShortCut : String;

begin
CoInitialize(nil);

hRes := CoCreateInstance(CLSID_ShellLink,
nil,
CLSCTX_INPROC_SERVER,
IID_IShellLinkA,
slShellLink);

if hRes = S_OK then
begin
slShellLink.SetPath(PChar(pcsFileToLinkTo)); // HIER DÜRFTE DER FEHLER LIEGEN!!!
hRes := slShellLink.QueryInterface(IID_IPersistFile, pfPersistFile);
end;
if hRes = S_OK then
begin
GetMem(wsShortCut,MAX_PATH shl 1);
sShortCut := ChangeFileExt(pcsFileToLinkTo,'.LNK');
MultiByteToWideChar(CP_ACP,
0,
PChar(sShortCut),
-1,
wsShortCut,
MAX_PATH shl 1);
pfPersistFile.Save(wsShortCut, TRUE);
FreeMem(wsShortCut,MAX_PATH shl 1);
end;
end;
Das Problem ist jetzt, dass bei manchen Leuten die Fehlermeldung "Konnte Pfad nicht setzen" kommt. Ich denke mir, dass es an der oben markieren Zeile liegt, aber wie kann ich den Fehler beheben? Wäre nett, wenn mir jemand helfen könnte!

Gruß Yheeky
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.105 Beiträge
 
Delphi 11 Alexandria
 
#2
  Alt 7. Nov 2002, 15:59
Moin Yheeky,

irgendwie erkenn' ich da meine "Handschrift"

Wenn ich nicht irre, war das ganze auch mal mit Kommentaren versehen.
Wichtig wäre schon einmal, dass das CoInitialize nur einmal pro Thread aufgerufen wird, was sich am elegantesten wohl im initialization Abschnitt des Hauptformulares erledigen lässt. Dazu muss zu jedem Aufruf von CoInitialize auch ein Aufruf von CoUninitialize erfolgen (finalization).

Das nur mal vorweg, da es für ein sauberes Resourcenmanagement wichtig ist.

Ich denke mal, dass der Fehler erst in der Zeile pfPersistFile.Save... liegt, da hier erst wirklich gespeichert wird.
Allerdings weiss ich nicht genau, welcher Pfad angemeckert wird, der der LNK Datei, oder der auf die die LNK Datei verweist (dann hättest Du wohl recht mit der fehlerhaften Zeile).

Gibt es bei den Systemen, bei denen der Fehler auftritt irgendwelche Gemeinsamkeiten (im Moment habe ich den Verdacht, dass es sich durchweg um XP bzw. W2K handeln könnte)?

Vermutlich liegt die Fehlerursache darin, dass auf einen Pfad verwiesen wird, der Leerstellen enthält.
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
Yheeky

Registriert seit: 7. Jun 2002
1.339 Beiträge
 
#3
  Alt 7. Nov 2002, 19:11
Hi,

was ein Zufall, dass die Funktion von dir ist
Naja, der Fehler taucht eigentlich unregelmäßig auf. Bei mir und ein paar Freunden geht es problemlos unter WinXP, bei meiner Freundin jedoch, kommt der oben beschriebene Fehler (auch unter WinXP).
Meinst du, dass es wirklich an den Leerzeichen liegt? Warum geht es denn dann an manchen Rechnern oder wie könnte man das Problem sonst beheben?

Hab den Rest jetzt so eingebaut. Ist das richtig?

Code:
Initialization
CoInitialize(nil);

Finalization
CoUnInitialize(nil);

end.
Gruß Yheeky
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.105 Beiträge
 
Delphi 11 Alexandria
 
#4
  Alt 7. Nov 2002, 20:02
Moin Yheeky,

unter XP hab' ich's noch nicht getestet.
Mittlerweile hab' ich die Funktion noch ein wenig überarbeitet. Ich muss nur mal sehen, wo ich sie habe. (nach der Neuinstallation ist noch nicht wieder alles da wo's hingehört )

Mal abgesehen davon, das CoUninitialize keinen Parameter hat stimmt's soweit, wenn Du's denn im Hauptformular eingetragen hast.

Es wäre zumindest noch interessant, wie die Pfade (zur Exe und zur Lnk) bei dem Rechner lauten sollen, bei dem es nicht funktioniert).

Tritt der Fehler reproduzierbar auf?
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
Yheeky

Registriert seit: 7. Jun 2002
1.339 Beiträge
 
#5
  Alt 7. Nov 2002, 20:26
Hi Christian,

okay, dann hab´ ich soweit alles richtig eingebaut.
Was die Pfade betrifft...das kann ich dir ja nicht sagen. Der User kann ja einen Pfad auswählen. Was ich dir aber sagen kann ist, dass es bei dem Standardpfad auftritt (in diesem Falle: "C:\Programme\BrotherSoft\ISDN - Exchange").

Gruß Yheeky
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.105 Beiträge
 
Delphi 11 Alexandria
 
#6
  Alt 7. Nov 2002, 20:55
Moin Yheeky,

hier noch eine leicht aktualisierte Fassung:

Delphi-Quellcode:
// Der Einfachheit halber heisst der Link genauso, wie die Datei
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
  // 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
    slShellLink.SetWorkingDirectory(PChar(ExtractFilePath(pcsFileToLinkTo)));
    slShellLink.SetHotKey((MOD_WIN shl 8) or ord('T'));
    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

    try
      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
    finally
      FreeMem(wsShortCut,MAX_PATH shl 1); // und den Platz wieder freigeben
    end;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  if Opendialog1.Execute then
  begin
    NewShellLink(OpenDialog1.FileName);
  end;
end;

initialization
begin
  CoInitialize(nil);
end;

finalization
begin
  CoUnInitialize;
end;
Leider kann ich den Fehler nicht reproduzieren (mit Deinem Pfad), und somit wird's auch etwas schwierig die Ursache zu ermitteln.

Was bei dem Beispiel Code noch wichtig wäre:
Der Link wird im gleichen Verzeichnis gespeichert, wie die Exe.
Soll die gleich auf dem Desktop landen, muss in der Zeile pfPersistFile.Save noch der richtige Pfad eingetragen werden.
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
Yheeky

Registriert seit: 7. Jun 2002
1.339 Beiträge
 
#7
  Alt 7. Nov 2002, 21:45
Hi Christian!

Okay, danke für die aktualisierte Version. Was aber meinst du mit
Zitat:
Soll die gleich auf dem Desktop landen, muss in der Zeile pfPersistFile.Save noch der richtige Pfad eingetragen werden.
Was muss ich da genau noch ändern? Muss ich den Parameter wsShortCut anpassen und dort den Pfad zum Desktop angeben?

Gruß Yheeky
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.105 Beiträge
 
Delphi 11 Alexandria
 
#8
  Alt 7. Nov 2002, 23:09
Moin Yheeky,

das Beispiel ist ja mehr als Demo denn als direkt verwertbarer Codeschnipsel zu verstehen.
Ich kann mir offengestanden nicht so recht den Fall vorstellen, in dem der Link genauso heissen soll und in genau dem Verzeichnis liegen soll, wie die Datei, auf die verwiesen werden soll.
Mindestens ein zweiter Parameter, der eben diesen Pfad (incl. Namen) angibt wäre wohl schon nicht verkehrt.

Statt der Variablen sShortCut wird dann dieser Parameter mit dem MultiByteToWideChar in wsShortCut geschoben. (die ChangeFileExt Zeile kann dann natürlich ersatzlos gestrichen werden).

Wie ich gerade gesehen habe setze ich da auch noch einen HotKey auf Windowstaste+T. Die Zeile kann auch gestrichen werden, das funktioniert nämlich sowieso nicht (jedenfalls nicht mit der Windowstaste).

Schau Dir doch mal im PSDK die Methoden von IShellLink an.
Dann bekommst Du mal eine Übersicht, was so alles eingestellt werden kann.
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
Yheeky

Registriert seit: 7. Jun 2002
1.339 Beiträge
 
#9
  Alt 12. Nov 2002, 18:23
Lag gar nicht an der Funktion, sondern an etwas anderem
Trotzdem danke für deine "aktuellen Zeilen".

Gruß Yheeky
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:36 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz