Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Sich selbst neu starten? (https://www.delphipraxis.net/67701-sich-selbst-neu-starten.html)

PeterPanino 18. Apr 2006 18:43


Sich selbst neu starten?
 
Was ist die beste Methode, mit der ein Programm sich selbst neu starten kann?

Es sollen aber nicht zwei Instanzen zur gleichen Zeit laufen, d.h. das neu zu startende Programm soll erst dann (besser: im gleichen Augenblick) gestartet werden, wenn das alte beendet ist.

Es ist mir klar, dass das nur über ein anderes Programm geht, aber vielleicht gibt es jemanden, der da besondere Tricks kennt oder Erfahrungen damit gemacht hat.

Nicodius 18. Apr 2006 19:17

Re: Sich selbst neu starten?
 
für was barauchst du das denn :shock:


sonst gibts heir in der codelib nen code dass nie 2 instanzen des programms gleichzeitig offen sind.
Und dann könntest du einfach das neue öffnen und das alte schliessen?


grüße Nico

mirage228 18. Apr 2006 19:24

Re: Sich selbst neu starten?
 
Hi,

Ich habe das mal so gemacht, dass ich ein Mini-Programm als Resource in das neu zustartende Programm integriert habe.
Muss selbiges neugestartet werden, dann wird das Mini-Programm entpackt (nach TEMP) und wartet solange bis sich das Hauptprogramm beendet hat (bzw. beendet dieses ggf. selbst) und startet dieses dann neu (das Mini-Programm beendet sich selbst und wird vom Hauptprogramm beim Start gelöscht).

mfG
mirage228

3_of_8 18. Apr 2006 19:29

Re: Sich selbst neu starten?
 
Du könntest auch die MainForm schließen und in die beim Projektquellcode eine bedingt terminierte Schleife drumrum machen.

PeterPanino 18. Apr 2006 20:07

Re: Sich selbst neu starten?
 
Zitat:

Zitat von 3_of_8
Du könntest auch die MainForm schließen und in die beim Projektquellcode eine bedingt terminierte Schleife drumrum machen.

Könntest du das bitte mal an einem konkreten Beispiel zeigen? Danke!

3_of_8 18. Apr 2006 20:15

Re: Sich selbst neu starten?
 
Du gehst auf Projekt/Quellcode anzeigen.

Dann steht da irgendwo

Delphi-Quellcode:
begin
Application.Initialize;
...
Application.Run;
end.
Ersetzen durch:

Delphi-Quellcode:
var Terminate: Boolean;
begin
repeat
Teminate:=True;
Application.Initialize;
...
Application.Run;
until Terminate;
end.
Wenn du das Programm neustarten musst, ruf einfach an der betreffenden Stelle auf:
Delphi-Quellcode:
Terminate:=false;
Close;
(Ungetestet)

PeterPanino 18. Apr 2006 21:52

Re: Sich selbst neu starten?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Danke, funktioniert aber leider nicht! S. angehängtes Projekt.

Zitat:

Zitat von 3_of_8
Du gehst auf Projekt/Quellcode anzeigen.

Dann steht da irgendwo

Delphi-Quellcode:
begin
Application.Initialize;
...
Application.Run;
end.
Ersetzen durch:

Delphi-Quellcode:
var Terminate: Boolean;
begin
repeat
Teminate:=True;
Application.Initialize;
...
Application.Run;
until Terminate;
end.
Wenn du das Programm neustarten musst, ruf einfach an der betreffenden Stelle auf:
Delphi-Quellcode:
Terminate:=false;
Close;
(Ungetestet)


3_of_8 19. Apr 2006 06:53

Re: Sich selbst neu starten?
 
Hmm, keine Ahnung. Der Code nach Application.Run wird irgendwie gar nicht ausgeführt. Du könntest es natürlich noch eleganter machen, indem du alle relevanten Variablen am Anfang in ein Array oder in eine Datei speicherst und sie dann wieder einliest.

Nicodius 19. Apr 2006 06:57

Re: Sich selbst neu starten?
 
Morgen

jetzt erklär mir nochmal wieso du das brauchst ;)


grüße Nico

Sascha L 19. Apr 2006 07:46

Re: Sich selbst neu starten?
 
Das ist doch völlig irrelevant für die Lösung, wieso er das braucht?! Es gibt 1000ende Anwendungsmöglichkeiten, wieso ein Programm neugestartet werden soll und da ist es für den User ein Komfort-Feature, wenn es das selber kann.

Ich würde einfach ein Mini-Programm schreiben welches das Programm beendet und danach neustartet. Dieses Programm in das Hauptprogramm zu packen, wie hier schon jmd. schrieb, finde ich aber unnötig. Das Programm kann ja ganz normal als zweite Exe im Hauptverzeichnis liegen. Das Programm schadet ja nicht. D.h. selbst wenn jmd. das Programm selber über den Explorer ausführt, wird ja nur das Programm - sofern es geöffnet ist - beendet und danach neugestartet.

Jasocul 19. Apr 2006 07:57

Re: Sich selbst neu starten?
 
Ganz unwichtig ist die Frage nicht. Auch Viren, Trojaner, etc. sorgen oft dafür, dass sie beim Beenden automatisch neu gestartet werden.
Üblicherweise läuft dafür ein zweites Programm (oder ein Dienst) im Hintergrund mit, das überwacht, ob das Programm noch läuft.

PeterPanino 19. Apr 2006 08:37

Re: Sich selbst neu starten?
 
Zitat:

Zitat von Nicodius
Morgen
jetzt erklär mir nochmal wieso du das brauchst ;)
grüße Nico

Das ist etwas kompliziert zu erklären, ist aber DEFINITIV nichts Illegales.

mbamler 19. Apr 2006 08:44

Re: Sich selbst neu starten?
 
Zitat:

Zitat von PeterPanino
Zitat:

Zitat von Nicodius
Morgen
jetzt erklär mir nochmal wieso du das brauchst ;)
grüße Nico

Das ist etwas kompliziert zu erklären, ist aber DEFINITIV nichts Illegales.


Mach doch einfach sowas wie:

...
Shellexecute('Programmname.exe', true); //mit warten bis das Programm läuft
Terminate; //diese Instanz beenden
...

Gruß
Matthias

r2c2 19. Apr 2006 08:54

Re: Sich selbst neu starten?
 
Oder du schreibtst ne 2-Zeilen-Batch...

mfg

Christian

marabu 19. Apr 2006 10:26

Re: Sich selbst neu starten?
 
Eine Zeile mehr und man hat auch eine Ausstiegsmöglichkeit:

Code:
@echo off
rem this is demo.cmd
demo.exe
if %errorlevel% GTR 0 exit
demo.cmd
Übrigens ein Trick aus der Zeit, als man noch nicht wusste, was ein Watchdog Service ist bzw. wie man ihn implementieren könnte. Das letzte mal habe ich das unter MS-DOS 2.10 bei Magee AutoMenu gesehen...

Grüße vom marabu

H4ndy 19. Apr 2006 10:38

Re: Sich selbst neu starten?
 
Also ich habe mir für dieses "Feature" einfach ein kleines Kommandozeilen-Programm geschrieben,
welches wartet bis mein Hauptprogramm beendet wurde und es dann neustartet.

Ist leicht umzusetzten, klein (44KB), resourcenschonend und sieht professioneller aus als ne Batch-Datei ;)
(Außerdem denke ich, dass das die "sauberste" Methode, da so dem Hauptprogramm genug Zeit eingeräumt wird,
damit es sich selbst sauber beenden kann)

PeterPanino 20. Apr 2006 00:29

Re: Sich selbst neu starten?
 
Das wichtigste Ziel der Methode "Sich selbst neu starten" ist, sicherzustellen, dass nicht beide Programme zur gleichen Zeit auf die selben Daten zugreifen können. Deshalb habe ich mir folgende Vorgehensweise ausgedacht (ProgrammA und ProgrammB sind verschiedene Instanzen *desselben* EXE-Programms):

- ProgrammA startet ProgrammB

- ProgrammB überprüft in einer Zeitschleife von X Sekunden im OnCreate-Event des Hauptfensters, ob ProgrammA läuft (etwa mittels Prozessliste):
- Wenn nein: Zeitschleife abbrechen und normal starten
- Wenn ja: Überprüfung in der Zeitschleife weiter ausführen:
- Wenn Zeitschleife X Sekunden abgelaufen: Sich selbst beenden.

- ProgrammA beendet sich selbst

Damit hätte man mehrere Vorteile:
- Starten einer zweiten Instanz wird verhindert.
- Programm kann sich selbst neu starten. Durch Ausführung der Instanzprüfung am Beginn des ersten Form.OnCreate-Events wird garantiert, dass nicht Programmcode in mehr als einer Instanz zur gleichen Zeit ausgeführt wird.

Wie könnte man die Zeitschleife am besten programmieren?

marabu 20. Apr 2006 07:56

Re: Sich selbst neu starten?
 
Hallo Peter,

vergiss die Zeitschleife, das Starten einer zweiten Instanz deines Programms verhinderst du so oder so nicht - warum auch. Verhindern musst du ja nur die gleichzeitige Benutzung bestimmter Ressourcen. Die zweite Instanz wird immer regulär gestartet, prüft dann eine Integritätsbedingung (Hier im Forum suchenCreateMutex) und tritt dann entweder in die Phase der Ressourcenbeschaffung ein oder beendet sich, mitunter nach Übergabe der Aufrufparameter an die existierende Instanz. Wichtig ist nur, dass du den Ein- und Austritt in bzw. aus dem kritischen Teil deines Programmes korrekt signalisierst. Eine überlappende Ausführung außerhalb dieses Blockes ist kein Problem.

Grüße vom marabu

Aike 27. Jul 2006 10:47

Re: Sich selbst neu starten?
 
Hm, ich hätte auch gerne die Möglichkeit, mein Programm neu zu starten, aber hier ist keine Lösung zu funden. Der Gund des Neustarts: Einstellungen übernehmen.

dataspider 27. Jul 2006 11:05

Re: Sich selbst neu starten?
 
Hi,

ich benutze folgende Routine, um z.B. nach kritischen Fehlern mein Programm wieder zu starten.

Delphi-Quellcode:
procedure ForceKillApplication(ARestart: boolean = False);
var
  AStartInfo: TStartupInfo;
  AProcInfo: TProcessInformation;
begin
  if ARestart then
  begin
    GetStartupInfo(AStartInfo);
    FillChar(AProcInfo, SizeOf(TProcessInformation), #0);
    CreateProcess(nil, GetCommandLine, nil, nil, False,
      CREATE_NEW_PROCESS_GROUP + NORMAL_PRIORITY_CLASS, nil,
      PChar(GetCurrentDir), AStartInfo, AProcInfo);
  end;
  TerminateProcess(GetCurrentProcess, 1);
end;
Frank

paritycheck 27. Jul 2006 11:07

Re: Sich selbst neu starten?
 
Hab es nicht weiter getestet aber vielleicht funktioniert folgendes:

Delphi-Quellcode:
program Project1;

uses
  Forms,
  Windows, Sysutils, Messages,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

var hMutex: Cardinal;
    aHWND: THandle;

begin
  hMutex:= CreateMutex(nil, True, PChar(ExtractFilename(ParamStr(0))));
  if GetLastError() = ERROR_ALREADY_EXISTS then begin
     aHWND:= FindWindow(nil, PChar('Form1'));
     if ParamStr(1) = '-r' then begin //vielleicht doch erst überprüfen ob das Programm neu getartet werden darf.
                                      //könnte sonst unerwünschte Nebenwirkungen geben....
        if aHWND <> 0 then begin
           SendMessage(aHWND, WM_CLOSE, 0, 0);
           Sleep(1000);
        end;
     end else begin
        MessageBox(0, PChar('Programm läuft bereits.'), PChar(ExtractFilename(ParamStr(0))), mb_OK);
        Halt;
     end;  
  end;
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
  if hMutex <> 0 then begin
     ReleaseMutex(hMutex);
     CloseHandle(hMutex);
  end;
end.
Dann einfach via CreateProcess oder auch ShellExecute das Programm neu starten.

MuTzE 24. Sep 2006 23:23

Re: Sich selbst neu starten?
 
Eine weitere Möglichkeit wäre diese:

Delphi-Quellcode:
procedure RestartApplication;

 function GetTmpDir: String;
 var
  PC: PChar;
 begin
  PC := StrAlloc(MAX_PATH + 1);
  GetTempPath(MAX_PATH, PC);
  Result := String(PC);
  StrDispose(PC);
 end;

 function GetTmpFileName(Ext: String): String;
 var
  PC: PChar;
 begin
  PC := StrAlloc(MAX_PATH + 1);
  GetTempFileName(PChar(GetTmpDir), 'uis', 0, PC);
  Result := string(PC);
  Result := ChangeFileExt(Result, Ext);
  StrDispose(PC);
 end;

var
 BatchFile: TStringList;
 BatchName: String;
begin
 batchname := GetTmpFileName('.bat');
 FileSetAttr(ParamStr(0), 0);
 BatchFile := TStringList.Create;
 with BatchFile do
  begin
   try
    Add(':Label1');
    Add(Copy(ParamStr(0), 0, 2));
    Add('cd ' + Copy(ExtractFilePath(ParamStr(0)), 4, Length(ExtractFilePath(ParamStr(0))) -1));
    Add('start ' + ExtractFileName(ParamStr(0)));
    Add('del ' + BatchName);
    SaveToFile(BatchName);
    ChDir(GetTmpDir);
    WinExec(PChar(BatchName), SW_HIDE);
   finally
    BatchFile.Free;
   end;
   Halt;
  end;
 Application.Terminate;
end;

Mackhack 25. Sep 2006 00:15

Re: Sich selbst neu starten?
 
Wie marabu schon andeutete mit dem Link, n Mutex und Ruhe ist im Laden :mrgreen:

Pichel 29. Jul 2010 15:03

AW: Re: Sich selbst neu starten?
 
Zitat:

Zitat von MuTzE (Beitrag 529145)
Eine weitere Möglichkeit wäre diese:

Mittlerweile meldet unter anderem Antivir sobald dieser Code verwendet wird einen "TR/Dldr.Delphi.Gen" Virus und man kann ihn nicht mehr wirklich verwenden.

franktron 29. Jul 2010 15:14

AW: Re: Sich selbst neu starten?
 
Zitat:

Zitat von Pichel (Beitrag 1038394)
Zitat:

Zitat von MuTzE (Beitrag 529145)
Eine weitere Möglichkeit wäre diese:

Mittlerweile meldet unter anderem Antivir sobald dieser Code verwendet wird einen "TR/Dldr.Delphi.Gen" Virus und man kann ihn nicht mehr wirklich verwenden.


Das ist nicht der Code sonder ein Virus den es in Delphi gibt such mal hier im Forum das steht das.


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