Entwickler-Ecke

Dateizugriff - Programm starten und auf dessen Beendigung warten


alexschultze - So 17.11.02 20:25
Titel: Programm starten und auf dessen Beendigung warten
hiho,

ich beschäftige mich gerade mal mit einem kleinen Installer, der mehrere EXEn ausführen soll. Damit nicht alle auf einmal kommen würd ich die gern nach und nach ausführen, also auf die Beendigung des Vorgängers warten. Ich habe im Netz 2 Codebeispiele gefunden, aber beide liefen bei mir nicht. Gebt mal Codes ;)

green


DeCodeGuru - So 17.11.02 20:29

poste mal die beiden anderen Codebeispiele. Was man machen könnte, wäre, dass man dauernd überprüft, ob das Prog läuft (->siehe FindWindow) und wenn das Handle, das FindWindow liefert, 0 ist, dann kann man die nächste EXE starten.


alexschultze - So 17.11.02 21:03

Zitat:

Thema: Starten von Anwendungen und auf deren Ende warten
Wer nicht nur eine andere Anwendung starten will, sondern auch noch warten, bis diese ihre Abarbeitung beendet hat, muß etwas tiefer in die Trickkiste greifen. Eine relativ einfache (und unter 16 Bit die einzige) Möglichkeit besteht darin, das von WinExec zurückgelieferte Instanzenhandle zu nutzen, um die Anzahl der Nutzungen zu zählen und daruaf zu warten, daß diese Anzahl 0 wird. Beispiel:

Function WinExecAndWait(Path : string; Visibility : word) : word;

var InstanceID : THandle;

PathLen : integer;

begin

PathLen := Length(Path);

Move(Path[1],Path[0],PathLen);

Path[PathLen] := #00;

{ Try to run the application }

InstanceID := WinExec(@Path,Visibility);



if InstanceID > 32 then { Wert kleiner 32 ist ein Fehler }

WinExecAndWait := InstanceID

else begin

Repeat

Application.ProcessMessages;

until Application.Terminated or (GetModuleUsage(InstanceID) = 0);

WinExecAndWait := 32;

end;

end;


Für 32Bit-Anwendungen ist ein anderer Weg empfehlenswerter: die Funktionen CreateProcess, WaitforSingleObject und GetExitCodeProcess. Beispiel:

function WinExecAndWait(FileName:String; Visibility : integer):integer;

var zAppName : array[0..512] of char;

zCurDir : array[0..255] of char;

WorkDir : String;

StartupInfo : TStartupInfo;

ProcessInfo : TProcessInformation;

begin

StrPCopy(zAppName,FileName);

GetDir(0,WorkDir);

StrPCopy(zCurDir,WorkDir);

FillChar(StartupInfo,Sizeof(StartupInfo),#0);

StartupInfo.cb := Sizeof(StartupInfo);

StartupInfo.dwFlags := STARTF_USESHOWWINDOW;

StartupInfo.wShowWindow := Visibility;

if not CreateProcess(nil,

zAppName, { Kommandozeile }

nil, { Zeiger auf Sicherheitsattribute Prozess }

nil, { Zeiger auf Sicherheitsattribute Thread }

false, { Behandlung Flag inheritance }

CREATE_NEW_CONSOLE or { Create-Flags }

NORMAL_PRIORITY_CLASS,

nil, { Zeiger auf Environment-Block }

nil, { Zeiger auf aktuelles Verzeichnis }

StartupInfo, { Startinformationen }

ProcessInfo) then Result := -1 { Prozessinformationen }



else begin

WaitforSingleObject(ProcessInfo.hProcess,INFINITE);

GetExitCodeProcess(ProcessInfo.hProcess,Result);

end;

end;



Das ist von irgendeiner Seite, das habe ich vor 2 Jahren mal gespeichert..


Delete - So 17.11.02 21:31

http://www.delphipraxis.net/viewtopic.php?t=1033


alexschultze - So 17.11.02 21:40

ah, donke!

aber jetzt bin ich auf einmal zu blöd ne Funktion einzubinden?
`???

ich schreibe unter type
function RunProcess(FileName: string; ShowCmd: DWORD; wait: Boolean; ProcID: PCardinal): Longword;

und fertig. Geht aber nicht?


Delete - So 17.11.02 21:43

Brauchst du nicht.
Einfach die Funktion gleich hinter Implementation in den Code kopieren und wie ich es im Beispiel gemacht habe aufrufen.


alexschultze - So 17.11.02 21:44

ach, scho erledigt, TFORM1 vergessen


Delete - So 17.11.02 22:12

Oder so.


check_it_now - So 29.12.02 15:34

ich bekomme beim compilieren meines progs mit dieser funktion die error meldung

Undefinierter Bezeichner 'PCardinal'

macht mich doch mal schlau was mein problem ist.


danke


alexschultze - So 29.12.02 17:06

keine ahnung, bei mir funzt es prima!


Delete - Mo 30.12.02 15:49

check_it_now hat folgendes geschrieben:
macht mich doch mal schlau was mein problem ist.

Evtl. die Delphi-Version? Du kannst es ersatzweise mit

Quelltext
1:
PDWORD                    

(deklariert in Delphi 5 als "^Cardinal"), oder du deklarierst den Typ selbst:

Quelltext
1:
2:
type
  PCardinal = ^Cardinal;

Das muss dann vor Luckies Funktion!