Discussion:
CreateProcess mit cmd.exe und Parametern
(zu alt für eine Antwort)
Gerd-Ulrich Meyer
vor 12 Jahren
Permalink
Hallo,

irgendwie komme ich mit den Parametern von CreateProcess nicht klar (da
sind mir zuviele NIL's an den unerwartetsten Stellen :-) ).

Ich habe diese Routine inzwischen mühsam zusammengesetzt (und auch
zusammengesucht):

procedure ExecuteCommandLine(CmdLineZeileStr : string);
var pStartUpInfo : TStartupInfo;
pProcessInfo : TProcessInformation;
CmdZeileStr : string;
isExec : boolean;
begin
FillChar(pStartUpInfo,SizeOf(pStartUpInfo),#0);
with pStartUpInfo do
begin
cb:=SizeOf(pStartUpInfo);
dwFlags:=STARTF_USESHOWWINDOW;
wShowWindow:=SW_SHOWNORMAL;
end; // with pStartUpInfo do
isExec:=CreateProcess(PChar(copy(CmdLineZeileStr,1,
pos(' ',CmdLineZeileStr)-1)),PChar(copy(CmdLineZeileStr,
pos(' ',CmdLineZeileStr)+1,length(CmdLineZeileStr))),
nil,nil,false,CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS,
nil,nil,pStartUpInfo,pProcessInfo);
end; // procedure ExecuteCommandLine

und rufe sie so auf:

...
CommandLineZeileStr:='cmd.exe /C pushd '+dbGetAktUserBaseDir+'
'+ProgrammDateiNameStr+' > '+AusgabeDateiNameStr+' & popd & exit';
ExecuteCommandLine(CommandLineZeileStr);

wobei dbGetAktUserBaseDir mir ein Verzeichnis (in diesem Fall Q:)
zurückliefert.

ProgrammDateiNameStr enthält zur Zeit zum Testen den Wert "md
Testverzeichnis" (später sollen so komplette DOS-Befehle möglich sein).

Wo gehören jetzt welche Teile hin? Ich probiere jetzt seit ca. 3 Tagen.

Vielen Dank und

Gruss

Gerd-Ulrich Meyer
Matthias Frey
vor 12 Jahren
Permalink
Post by Gerd-Ulrich Meyer
Hallo,
Hallo
Post by Gerd-Ulrich Meyer
irgendwie komme ich mit den Parametern von CreateProcess nicht klar (da
sind mir zuviele NIL's an den unerwartetsten Stellen :-) ).
Ich habe diese Routine inzwischen mühsam zusammengesetzt (und auch
...
Post by Gerd-Ulrich Meyer
isExec:=CreateProcess(PChar(copy(CmdLineZeileStr,1,
pos(' ',CmdLineZeileStr)-1)),PChar(copy(CmdLineZeileStr,
pos(' ',CmdLineZeileStr)+1,length(CmdLineZeileStr))),
nil,nil,false,CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS,
nil,nil,pStartUpInfo,pProcessInfo);
end; // procedure ExecuteCommandLine
...

Eine Patentlösung habe ich gerade nicht (hier) aber schlage vor,
dass du die mühsam zusammengesetzte Routine wieder auseinandernimmst.
Also weise z.B. erstmal "copy(CmdLineZeileStr,1,pos('
',CmdLineZeileStr)-1))" einer lokale Variable zu, dasmit du das
auch debuggen kannst.

Ansonsten könnte google helfen - "delphi CreateProcess", 1. Treffer

Matthias
Gerd-Ulrich Meyer
vor 12 Jahren
Permalink
Hallo,
...
So ähnlich habe ich mir das heute Nacht (und heute mittag in meiner
Pause) auch überlegt.
Post by Matthias Frey
Also weise z.B. erstmal "copy(CmdLineZeileStr,1,pos('
',CmdLineZeileStr)-1))" einer lokale Variable zu, dasmit du das
auch debuggen kannst.
Das scheint eine von wahrscheinlich 2 Möglichkeiten zu sein. Die andere,
statt der komplexen Zeile Zerlegung der einzelnen Befehle und
"Schreiben" einer Batch-datei, die dann über CreateProcess aufgerufen
werden kann.
Post by Matthias Frey
Ansonsten könnte google helfen - "delphi CreateProcess", 1. Treffer
Guck ich mir gleich noch an.
Danke.
Post by Matthias Frey
Matthias
Gruss

Gerd-Ulrich Meyer
Achim Kalwa
vor 12 Jahren
Permalink
Hallo,
Post by Gerd-Ulrich Meyer
irgendwie komme ich mit den Parametern von CreateProcess nicht klar (da
sind mir zuviele NIL's an den unerwartetsten Stellen :-) ).
Muss es CreateProcess sein? Oder reicht ShellExecute() für Deine Zwecke
evtl. aus? Das kommt mit deutlich weniger NILs aus :-)

Du zerlegst Deinen CmdLineZeileStr in Teile und nimmst dazu das
Leerzeichen. Das kann aber u.U auch in den Pfadangaben auftauchen, das
könnte also schief gehen:
C:\Program Files (x86)\CompanyName\something.exe

Du solltest versuchen, nicht alles in einen String zu quetschen
(CmdLineZeileStr), sondern die Beteiligten jeweils als eigenen String zu
übergeben; oder zumindest zwischen Programm-Dateinamen und Parametern zu
trennen.

Achim
Gerd-Ulrich Meyer
vor 12 Jahren
Permalink
Hallo,
Post by Gerd-Ulrich Meyer
Hallo,
Post by Gerd-Ulrich Meyer
irgendwie komme ich mit den Parametern von CreateProcess nicht klar (da
sind mir zuviele NIL's an den unerwartetsten Stellen :-) ).
Muss es CreateProcess sein? Oder reicht ShellExecute() für Deine Zwecke
evtl. aus? Das kommt mit deutlich weniger NILs aus :-)
Das müsste ich mir angucken. Ich hatte bisher nur Abstand von WinExec
genommen und war dazu auf CreateProcess gestossen.
Post by Gerd-Ulrich Meyer
Du zerlegst Deinen CmdLineZeileStr in Teile und nimmst dazu das
Leerzeichen. Das kann aber u.U auch in den Pfadangaben auftauchen, das
C:\Program Files (x86)\CompanyName\something.exe
Du solltest versuchen, nicht alles in einen String zu quetschen
(CmdLineZeileStr), sondern die Beteiligten jeweils als eigenen String zu
übergeben; oder zumindest zwischen Programm-Dateinamen und Parametern zu
trennen.
Ich denke, ich gucke mir mal an (siehe auch meine andere Antwort), ob
und wie ich die relevanten Teile in eine Batch-datei "stopfen" kann und
die dann ausführe.

Vielen Dank.
Post by Gerd-Ulrich Meyer
Achim
Gruss

Gerd-Ulrich Meyer
Gunnar
vor 12 Jahren
Permalink
Moin,
Post by Gerd-Ulrich Meyer
irgendwie komme ich mit den Parametern von CreateProcess nicht klar (da
sind mir zuviele NIL's an den unerwartetsten Stellen :-) ).
ich würde erst mal ganz klein anfangen und nur versuchen, cmd.exe zu starten
(ohne irgendwelche Parameter).

CreateProcess sucht die auszuführende Datei im "aktuellen Verzeichnis" - das
wird in den seltensten Fällen das sein, in dem sich cmd.exe befindet. Du
solltest also besser den Inhalt der Umgebungsvariablen %ComSpec% benutzen.

Wenn das klappt, dann kannst Du Dich um die Parameter kümmern . . .

Gruß
Gunnar
Gerd-Ulrich Meyer
vor 12 Jahren
Permalink
Hallo,
Post by Gunnar
Moin,
Post by Gerd-Ulrich Meyer
irgendwie komme ich mit den Parametern von CreateProcess nicht klar
(da sind mir zuviele NIL's an den unerwartetsten Stellen :-) ).
ich würde erst mal ganz klein anfangen und nur versuchen, cmd.exe zu
starten (ohne irgendwelche Parameter).
Cmd.exe hatte ich in einem ganz anderen Projekt schon mal "sauber"
ausführen können, allerdings mit wesentlich weniger Parametern. Deshab
mein Gedanke mit der Batch-Datei (siehe dazu meine anderen Antworten).
Post by Gunnar
CreateProcess sucht die auszuführende Datei im "aktuellen Verzeichnis" -
das wird in den seltensten Fällen das sein, in dem sich cmd.exe
befindet. Du solltest also besser den Inhalt der Umgebungsvariablen
%ComSpec% benutzen.
Das hab ich nicht bedacht. Da könnte schon das erste Problem liegen.
Post by Gunnar
Wenn das klappt, dann kannst Du Dich um die Parameter kümmern . . .
Gruß
Gunnar
Danke und

Gruss

Gerd-Ulrich Meyer
Gerd-Ulrich Meyer
vor 12 Jahren
Permalink
Hallo,

für mich ist die Frage gelöst (ob's die beste Lösung ist, sei
dahingestellt).
...
Die Routine ist prinzipiell richtig, bis auf die Tücken mit der
Zuordnung der Parameter.
Post by Gerd-Ulrich Meyer
CommandLineZeileStr:='cmd.exe /C pushd '+dbGetAktUserBaseDir+'
'+ProgrammDateiNameStr+' > '+AusgabeDateiNameStr+' & popd & exit';
ExecuteCommandLine(CommandLineZeileStr);
wobei dbGetAktUserBaseDir mir ein Verzeichnis (in diesem Fall Q:)
zurückliefert.
ProgrammDateiNameStr enthält zur Zeit zum Testen den Wert "md
Testverzeichnis" (später sollen so komplette DOS-Befehle möglich sein).
Wo gehören jetzt welche Teile hin? Ich probiere jetzt seit ca. 3 Tagen.
Ist nicht mehr wichtig. Die einfachste Lösung: Verpacken der nötigen
Befehle (u.a. ein pushd <Arbeitsverzeichnis> und ein popd am Ende) in
eine Batchdatei und anschließendes Ausführen funktioniert für mich.
Post by Gerd-Ulrich Meyer
Vielen Dank und
Vielen Dank trotzdem für's Mitdenken
Post by Gerd-Ulrich Meyer
Gruss
Gerd-Ulrich Meyer
Gerd-Ulrich Meyer
Loading...