Entwickler-Ecke

Windows API - Mehrere DOS-Befehler nacheinander ausführen


CodexX - Mo 08.11.04 01:04
Titel: Mehrere DOS-Befehler nacheinander ausführen
hi!

ich habe folgendes problem:
ich muss aus delphi heraus mehrere dosbefehle, die auf eine bestimmte dos-datei zugreifen nacheinander ausführen. also erst wenn der eine abgearbeitet ist, soll der nächste aktiv werden.

in einer bat datei würde man das ganze einfach in mehrere zeilen schreiben und dann klappt das problemlos.

wenn ich nun in delphi

Delphi-Quelltext
1:
2:
3:
4:
output := 'datei.exe parameter';
output2 := 'datei.exe andererparameter';
winexec (PChar(output), SW_TRUE);
winexec (PChar(output2), SW_TRUE);

verwende, dann öffnen sich (fast) gleichzeitig 2 dosfenster und das zweite fenster gibt eine fehlermeldung aus, weil datei.exe bereits in benutzung ist.

ich könnte natürlich Sleep(5000); dazwischen schreiben, aber ich kann nicht davon ausgehen, dass auf langsameren rechnern der erste befehl nach 5sec bereits abgearbeitet wurde.
ich müsste die befehle also auf die gleiche weise an die eingabeaufforderung (command.com) übergeben, wie es eine bat datei auch macht.

ich habe mir nun folgendes gedacht:

Delphi-Quelltext
1:
2:
3:
4:
output3 := 'COMMAND.COM /K @echo on'+#10#13+output+#10#13+output2+#10#13+'wait';
ShowMessage(output3);
//oder
ShellExecute(0,'open', PChar('output3'), NILNIL, sw_show);

aber das funktioniert auch nicht.

ich könnte output3 natürlich in eine temp.bat reinschreiben, diese dann ausführen und dann wieder löschen, aber das ist zu umständlich. das muss doch auch direkt gehen.

vielen dank fürs komplette lesen; ich hoffe, es kann mir jemand helfen.

Moderiert von user profile iconChristian S.: Code- durch Delphi-Tags ersetzt.
Moderiert von user profile iconTino: Topic aus Sonstiges verschoben am Mo 08.11.2004 um 12:52


Delete - Mo 08.11.04 01:21

Versuch es mal so: http://www.luckie-online.de/Delphi/Sonstiges/RunProcess.html


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
function RunProcess(FileName: string; ShowCmd: DWORD; wait: Boolean; ProcID:
  PDWORD): Longword;
var
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
begin
  FillChar(StartupInfo, SizeOf(StartupInfo), #0);
  StartupInfo.cb := SizeOf(StartupInfo);
  StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_FORCEONFEEDBACK;
  StartupInfo.wShowWindow := ShowCmd;
  if not CreateProcess(nil,
    @Filename[1],
    nil,
    nil,
    False,
    CREATE_NEW_CONSOLE or
    NORMAL_PRIORITY_CLASS,
    nil,
    nil,
    StartupInfo,
    ProcessInfo)
    then
    Result := WAIT_FAILED
  else
  begin
    if wait = FALSE then
    begin
      if ProcID <> nil then
        ProcID^ := ProcessInfo.dwProcessId;
      result := WAIT_FAILED;
      exit;
    end;
    WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
    GetExitCodeProcess(ProcessInfo.hProcess, Result);
  end;
  if ProcessInfo.hProcess <> 0 then
    CloseHandle(ProcessInfo.hProcess);
  if ProcessInfo.hThread <> 0 then
    CloseHandle(ProcessInfo.hThread);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  ProcID: Cardinal;
begin
  ProcID := 0;
  if OpenDialog1.Execute then
    RunProcess(OpenDialog1.FileName, SW_SHOW, CheckBox1.Checked, @ProcID);
  ShowMessage(IntToStr(ProcID));
end;


CodexX - Di 09.11.04 00:47

kannst du deine funktion bitte etwas erläutern? ich komme damit leider nicht zurecht. bin nur ein anfänger mit komplizierten fragen :wink:
wie kann ich denn die funktion auf meine problemstellung anwenden?
danke :)


Delete - Di 09.11.04 05:23

In dem du jedes Programm damit startest und Wait auf true setzt:

Delphi-Quelltext
1:
2:
3:
RunProcess(Exe1.exe, SW_NOMAL, True, nil);
RunProcess(Exe2.exe, SW_NOMAL, True, nil);
RunProcess(Exe3.exe, SW_NOMAL, True, nil);


jaevencooler - Di 09.11.04 10:36

Moin, Moin,

ich habe dafür eine Komponente, bei Torry gezogen vor ca. 100 Jahren, wenn Du mir Deine email Adresse zukommen lässt schicke ich Dir die Komponente gerne zu. (Freeware)


Gruss
Michael


CodexX - Di 09.11.04 21:46

@Luckie
ok, ich habe das jetzt halbwegs hinbekommen. aber zwei sachen dazu:
1. wofür ist "@ProcID"
2. ein problem ist nun, dass die einzelnen aufgerufenen programme nicht nur auf einander warten, sondern das eigentliche delphi programm auch blockieren.
dh, wenn ich eine kleine form mit der anzeige, dass gewartet werden soll, einblenden will

Quelltext
1:
2:
3:
waitform.Show;
RunProcess(Exe1.exe, SW_NOMAL, True, nil);  
RunProcess(Exe2.exe, SW_NOMAL, True, nil);

dann wird es zwar geöffnet, aber das label und der button darauf werden erst angezeigt, nachdem Exe2.exe fertig ist. bis dahin 'hängt' das ganze programm.

@jaevencooler
sehr gerne: wwwpro@freenet.de


Motzi - Di 09.11.04 22:25

Das @ProcID brauchst du nur wenn du die ProcessID des gestarteten Prozesses haben willst. In deinem Fall also uninteressant (stattdessen wie im kurzen Bsp von Luckie einfach "nil" übergeben).

Bau nach Waitform.Show ein Application.ProcessMessages ein und es sollte alles passen.. :)