Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Eigenes Programm elegant ersetzen (https://www.delphipraxis.net/123930-eigenes-programm-elegant-ersetzen.html)

Oreaden 11. Nov 2008 13:25


Eigenes Programm elegant ersetzen
 
Hallo Wissende,

ich suche eine Möglichkeit, das eigene Programm elegant durch ein anderes (z. B. neue Version) zu ersetzen. Dabei stellen sich mir folgende Problempunkte
  • Wie kann ich das laufende Programm elegant ersetzen?
  • Welche Probleme können auftreten und wie lassen sie sich umgehen (z. B. Sperreintrag des Programms, Schreibrechte im Verzeichnis)

Danke für euere Hilfe. Verzeiht, daß ich einen neuen Thread eröffne, aber die bisherigen enthalten leider nicht die gewünschten Informationen damit ich ein eigenes Update im Programmlauf umsetzen kann.

Schöne Grüße
Oreaden

Larsi 11. Nov 2008 13:31

Re: Eigenes Programm elegant ersetzen
 
Also das einfachste wäre wohl eine externe Datei die die orgigal Datei gegen die neue ersetzt.

nat 11. Nov 2008 13:37

Re: Eigenes Programm elegant ersetzen
 
hi

also ich hab mal ne update klasse fürn tool von mir geschrieben die
das ganze in etwa so regelt:

laufendes programm => neue dateien runterladen (temp dir)
=> ini-file in dem temp-dir erstellen in dem der pfad der installation steht und die aktuelle prozess-id
=> programm im temp-dir starten (mit speziellem parameter)
=> neu gestartetes programm wartet auf programmende des org. programms (kannst es hier auch killen).
kannst in deinem prog ja ne meldung ausgeben "progamm muß neu gestartet werden" und dann beenden.
=> laufendes programm im temp-dir löscht die dateien im install-dir und kopiert sich selbst dort hin
=> start des neuen programms
=> löschen der temp dateien
=> temp-dateien die in benutzung sind (z.B. aktuell laufende exe) zum löschen beim nächsten reboot vormerken
=> programmende des progs im temp-dir

für den user läuft das ganze eigentlich ziemlich unsichtbar ab (ausser die meldung mit dem update und dem programm neustart)

joachimd 11. Nov 2008 13:45

Re: Eigenes Programm elegant ersetzen
 
Du kannst ein laufendes Programm zwar nicht ersetzen, wohl aber umbenennen.
-> neues herunterladen (zB als meineapp.v1.0.exe)
-> bisheriges umbenennen (zB in meineapp.v0.9.exe)
-> neues umbenennen (in meineapp.exe)
Beim nächsten Programmstart startet dann die neue Version und du kannst auf die alte immer noch zugreifen (falls Update nicht gewünscht war oder Probleme macht).

Oreaden 11. Nov 2008 13:46

Re: Eigenes Programm elegant ersetzen
 
Hallo Nat,

das ganze hört sich ganz gut an. Stellte mir auch ungefähr so den Ablauf vor, daß nach dem Reboot die neue Programmversion verfügbar ist. Möchte aber nicht den User mit irgendwelchen Aufforderungen quälen, das Programm zu beenden, sondern einfach beim nächsten Programmstart die neue Version zur Verfügung stellen. Ist hierfür auch die ganze Geschichte mit den ThreadID's notwendig (wie kann man diese ermitteln)? Auf der anderen Seite ist das Problem mit den ganzen Schreibrechten, wie kann man diese elegant beim Update handhaben?

Schöne Grüße
Oreaden

nicodex 11. Nov 2008 13:47

Re: Eigenes Programm elegant ersetzen
 
Zitat:

Zitat von joachimd
Du kannst ein laufendes Programm zwar nicht ersetzen, wohl aber umbenennen.

Auch auf FAT-formatierten Laufwerken?

joachimd 11. Nov 2008 13:50

Re: Eigenes Programm elegant ersetzen
 
Zitat:

Zitat von nicodex
Zitat:

Zitat von joachimd
Du kannst ein laufendes Programm zwar nicht ersetzen, wohl aber umbenennen.

Auch auf FAT-formatierten Laufwerken?

zumindest auf NTFS...wer hat (außer auf externen Platten) noch FAT?

Fridolin Walther 11. Nov 2008 13:56

Re: Eigenes Programm elegant ersetzen
 
Das Ganze funktioniert auch mit FAT Dateisystemen und ist die Methode, die die meisten Applikationen nutzen heutzutage wenn es darum geht sich selbst upzudaten.

nat 11. Nov 2008 14:04

Re: Eigenes Programm elegant ersetzen
 
Zitat:

Zitat von Oreaden
daß nach dem Reboot die neue Programmversion verfügbar ist.

die neue programmversion ist bei mir schon nach einem neustart des progamms verfügbar.
beim reboot wird quasi nur im temp-dir aufgeräumt (also alles was nicht sofort
gelöscht werden konnte wird beim reboot gelöscht).

Zitat:

Zitat von Oreaden
Möchte aber nicht den User mit irgendwelchen Aufforderungen quälen, das Programm zu beenden, sondern einfach beim nächsten Programmstart die neue Version zur Verfügung stellen.

kannst du ja machen. die instanz des programms im temp-dir wartet ja auf das programmende.
mußt es ja nicht sofort beenden.[/quote]

Zitat:

Zitat von Oreaden
Ist hierfür auch die ganze Geschichte mit den ThreadID's notwendig (wie kann man diese ermitteln)?

was meisnt du damit? wie gesagt, ich speichere die prozess-id der laufenden org. instanz.
die 2. instanz (im temp dir) wartet dann solange bis der prozess beendet ist.
speichern tue ich das ganze in der 1. instanz in etwa so:
Delphi-Quellcode:
  ini := TIniFile.Create(TempDir+'update.ini');
  try
    ini.WriteString(SECTION, 'OldFile', ParamStr(0));
    ini.WriteInteger(SECTION, 'pid', GetCurrentProcessId);
  finally
    ini.free;
  end;
in der 2. instanz lese und warte ich dann so:
Delphi-Quellcode:
  //alten dateinamen und prozess-id auslesen
  ini := TIniFile.Create(IniFilename);
  try
    OldFile := ini.ReadString(SECTION, 'OldFile', '');
    result := FileExists(OldFile);
    if not result then exit;

    pid := ini.ReadInteger(SECTION, 'pid', 0);
    result := pid > 0;
    if not result then exit;
  finally
    ini.free;
  end;

  //warten bis prozess beendet ist
  while ProcessExists(pid) do
  begin
    sleep(1000);
    Application.ProcessMessages;
  end;



Zitat:

Zitat von Oreaden
Auf der anderen Seite ist das Problem mit den ganzen Schreibrechten, wie kann man diese elegant beim Update handhaben?

ich weiß nicht genau was du meinst... welche schreibrechte?

Oreaden 11. Nov 2008 14:06

Re: Eigenes Programm elegant ersetzen
 
Danke,

habe das mit dem umbenennen auf NTFS und FAT32 getestet und funktioniert einwandfrei :angel: . Wie bekommt man das Problem mit dem Schreibschutz oder anderen Zicken (wie UAC, etc.) in den Griff?

Schöne Grüße
Oreaden

So wie mit den Umbenennen hatte ich es mir vorgestellt :thumb:

smallsmoker 11. Nov 2008 14:19

Re: Eigenes Programm elegant ersetzen
 
also ich lade die neue datei in das verzeichnis der alten, diese datei hatt den namen meines programmes + '_update'

den rest mache ich mit ner batch datei

Delphi-Quellcode:
procedure UpdateClient(MainForm: TForm);
begin
  with TStringList.Create do try
    Add(':Label1');
    Add('del "' + Paramstr(0) + '"');
    Add('if Exist "' + Paramstr(0) + '" goto Label1');

    Add('move "' + Paramstr(0) + '_update" "' + paramstr(0)+'"');
    Add('start ' + ExtractFilename(Paramstr(0)));

    Add('del "' + ExtractFilePath(Paramstr(0)) + 'name.bat"');
    SavetoFile(ExtractFilePath(Paramstr(0)) + 'name.bat');
  finally Free end;
  //Ausführen
  ShellExecute(MainForm.Handle, 'open', PChar(ExtractFilePath(Paramstr(0)) + 
    'name.bat'), nil, nil, SW_HIDE);
  //Beenden
  MainForm.Close;
end;

Fridolin Walther 11. Nov 2008 16:04

Re: Eigenes Programm elegant ersetzen
 
Zitat:

Zitat von Oreaden
Danke,

habe das mit dem umbenennen auf NTFS und FAT32 getestet und funktioniert einwandfrei :angel: . Wie bekommt man das Problem mit dem Schreibschutz oder anderen Zicken (wie UAC, etc.) in den Griff?

Nunja, UAC (bzw. eingeschränkte Rechte) sind das größte Problem. Schreibschutz kann man ja mit FileSetAttr() entfernen vorher ;). Prinzipiell gibts nur eine Möglichkeit das Problem anzugehen:

Die Updateprozeduren müssen ausgelagert sein. Die Möglichkeiten dazu sind mannigfaltig. COM Server (wie es der Windows Explorer macht), Services (wie es die meisten Applikationen tun) oder aber sich selbst mit Admin Rechten neustarten fürs Update bzw. die Update Applikation mit Admin Rechten starten.

Oreaden 11. Nov 2008 16:56

Re: Eigenes Programm elegant ersetzen
 
Mhhhh, Schreibrechte? Kann man denn prüfen ob man die Rechte (falls ja, wie) hat, in ein Verzeichnis zu schreiben? Denke, dann wäre der Fall klar,
Delphi-Quellcode:
if Schreibrecht_im_Verzeichnis(paramstr(0)) then
  Update_Programm
else
  Offer_User_Download_Option;
Denn in diesem Falle weiss der User am besten, wie man das Programm zum laufen bekommt, und da wäre es doch sehr aufwendig alle Optionen abzufangen, oder?

Habe den Vorschlag von SmallSmoker kurz geprüft, und es scheint ganz gut zu funktionieren :thumb:
Delphi-Quellcode:
procedure Restart_Programm;
var
  s: string;
begin
  s := ChangeFileExt(paramstr(0), '_old.exe');
  RenameFile(s, paramstr(0));
  ShellExecute(0, 'Open', pWideChar(paramstr(0)), NIL, NIL, SW_NORMAL);
  close;
end;
Danke für Euere Tipps
Oreaden

haentschman 11. Nov 2008 18:28

Re: Eigenes Programm elegant ersetzen
 
Hallo...

ein paar Denkanstöße... :P

ich löse das Update bei meiner Anwendung wie folgt:

- die Haupanwendung lädt eine INI mit den Versionsinformationen vom server im Internet via HTTP
- ist eine neue Version vorhanden wird eine Update.exe downgeloadet, gestartet und die Hauptanwendung beendet.
- die Update.exe übernimmt dann:
- das Downloaden der Dateien, wobei bei allen Dateien ein Unterstrich angehängt wird, damit im Fehlerfalle die Originaldatei erhalten bleibt.
- nach erfolgreichem Download das Umbenennen der Dateien
- Anpassungen der Datenbank
- Anpassen / Korrigieren von Ordnern bzw. Ordnerstrukturen
- löschen von überflüssigen Dateien
- was man sonst noch verändern will....
- letztendlich den Start der Hauptanwendung nach dem Update.

- da die Update.exe je nach Bedarf programmiert / erweitert wird, ist man im Update recht flexibel.

Vieleicht hilft es ja bei der Entscheidung... :hi:

Oreaden 11. Nov 2008 18:55

Re: Eigenes Programm elegant ersetzen
 
WoW haentschman, für das ganze denke ich daß wirklich ein eigener Updater nötig ist. Für die Routinen wo ich suche, handelt es sich um eine Exe. Dar Ansatz ist wirklich nicht schlecht, was ich mich frage, wie gehtst Du mit den Verzeichnissen um? Gehst Du immer davon aus, dass Du in das Verzeichnis schreiben darfst, prüfst Du das zuvor (Wie denn?) oder soll sich der User bei Bedarf darum kümmern?

Schönen Abend
Oreaden

haentschman 11. Nov 2008 19:06

Re: Eigenes Programm elegant ersetzen
 
also...

- die Anwendung ist im Programme Ordner
- die Hauptanwendung lädt die Update.exe ins gleiche Verzeichnis
- unter XP sollten Schreibrechte im Installationsverzeichnis der Hauptanwndung möglich sein
- unter Vista fordert die Update.exe Adminrechte an, die der User bestätigen muß.
- alle anderen Dateien liegen im AllUsers bzw. im Benutzerverzeichnis

:wink: so richtig glücklich bin ich mit der Adminrechteanforderung noch nicht. Ich werde mal abwarten, wie sich das ganze auf den unterschiedlichsten Systemen verhält.
...Probleme sind da um Lösungen zu finden 8)

PS: wenn es sich nur um eine exe handelt sind weiter oben wesentlich einfachere Varianten aufgelistet...da wäre diese Variante mit Kanonen auf Spatzen geschossen.

:hi:

[edit]
- so eine Update.exe ist eigentlich schnell zusammengestrickt, welche die Anwendung beendet, die exe downloadet und dann wieder startet.
Vorteile zur Batch Datei: Visuell schööön machbar. (Ladebalken etc.)
[/edit]

RWarnecke 11. Nov 2008 19:09

Re: Eigenes Programm elegant ersetzen
 
Hallo Oreaden

schaue Dir doch mal die beiden Projekte an. Da findest Du bestimmt viele Anregungen.

Link 1 --> OpenSource
Link 2 --> Freeware

Fridolin Walther 11. Nov 2008 19:48

Re: Eigenes Programm elegant ersetzen
 
Hm, wenn Deine Anwendung wirklich nur aus einer Datei besteht und Du da nicht exzessiv rumdoktorn willst, dann wäre es am einfachsten Du checkst nach dem Vorhandensein eines Updates und überprüfst dann ob Du Admin Rechte hast. Falls nicht, forderst Du diese an (indem Du Dich selbst mit Administratorrechten neu startest z.B.) bzw. bittest den User Dich als Admin zu starten. Falls Du Admin Rechte hast, kannst Du die Datei direkt ersetzen.

Zu überprüfen ob Du in einem Verzeichnis Schreibrechte hast oder nicht wäre für mich als Pragmatiker relativ einfach:
Ich probier in dem Verzeichnis was zu schreiben*. Wenns klappt, prima. Wenns nicht klappt, hab ich offensichtlich keine Rechte dazu. Da der Administrator aber ohnehin immer Rechte hat (bzw. sie sich besorgen kann), wäre so ein expliziter Check eher nicht notwendig, sofern der Update Code an sich korrektes Fehlerhandling betreibt.

* Das Ganze stimmt so nicht ganz. Windows Vista führt bei aktivierter UAC für sogenannte "Legacy Applications" Dateisystemvirtualisierung durch. Das bedeutet das wenn eine Legacy Application versucht im Programme Ordner zu schreiben, werden die Dateioperationen stattdessen in einen Ordner im Userprofil durchgeführt. Der Check funktioniert bei "Legacy Applications" also nicht. Legacy Applications sind dabei 32bit Anwendungen ohne Manifest bzw. Anwendungen die in der Compatibility Database von Vista explizit als Legacy markiert sind.

ts230 23. Dez 2008 04:05

Re: Eigenes Programm elegant ersetzen
 
Ich löse dass so:
Datei laden
datei mit suffix "_new_" versehen
Datei UPADATE.INI erstellen
in der alten Version schauen ob die datei da ist und wenn ja,dem User schon wieder :) mitteilen
Im neuen Programm das alte löschen uns sich durch ein drittes Programm ummbenennen
Wenn in der update.ini etwas besonderes steht(surch das 3. Programn),das dritte Programm löschen

Fertig :bounce1: :coder: :cheers: :coder2:


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:21 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