Registriert seit: 12. Sep 2007
Ort: Bern
178 Beiträge
Delphi 2006 Architect
|
Warten bis ein Process wieder ready ist
10. Okt 2007, 10:47
Hallo miteinander
Ich bin auf der suche nach einer möglichkeit zu prüffen ob meine cmd process immernoch arbeitet oder nicht.
Wundert euch nicht über sonderheitem im Code, ich hatte bisher das so realisiert das man beim aufruf ein Endzeichen mitgeben kann sowie ein timer, Es war bisher so das ich gewartet habe bis entweder das zeichen kommt oder der Timer ableuft und dann das nächste comando der konsole übergeben habe. nun waitforsingleObject wartet bis der process beendet wird, aber ich will ihn ja garnicht beenden sondern ein weiteres commando später absetzen. also wirklich so arbeiten wie die Konsole...
Die version hier funktioniert gut solange man in etwa abschätzen kann wielange der computer braucht um den befehl auszuführen sowie man einen rückgabewert hat. Mein problem ist nun das ich keinen output kriege und nicht weis wielange er braucht bis er fertig ist aber dennoch bemerken muss wann er fertig ist. wisst ihr also wie ich den process fragen kann ob er noch beschäftigt ist oder nicht ?
bin wirklich kurz vor dem verzweifeln..
danke schonmal im voraus und liebe grüsse
Severin
Delphi-Quellcode:
procedure TConsoleThread.RC_Run(Command: string);
const bufsize=1024; // 1KByte buffer
var
buf: array [0..bufsize-1] of char;
si: tSTARTUPINFO;
sa: tSECURITYATTRIBUTES;
// sd: tSECURITYDESCRIPTOR;
pi: tPROCESSINFORMATION;
newstdin, newstdout, read_stdout, write_stdin: tHandle;
bread, avail: dword;
OffTime : Integer;
ConsoleCommand, StringOffTime: string;
CommandTypePos,OffCharPos : Integer;
begin
//Initialisierung ProcessInfo
FillChar(pi, SizeOf(TProcessInformation), 0);
//Initialisierung SecurityAttr
FillChar(sa, SizeOf(TSecurityAttributes), 0);
sa.nLength := SizeOf(sa);
sa.bInheritHandle := true;
sa.lpSecurityDescriptor := nil;
// create pipe A
if not CreatePipe(newstdin, write_stdin, @sa, 0) then
begin
TriggerConsoleOut('Error creating Pipe A');
exit;
end;
// create Pipe B
if not CreatePipe(read_stdout, newstdout, @sa, 0) then begin
TriggerConsoleOut('Error creating Pipe B');
CloseHandle(newstdin);
CloseHandle(write_stdin);
exit;
end;
// Conf. si
GetStartupInfo(si);
si.dwFlags:=STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
si.wShowWindow:=SW_HIDE;
si.hStdOutput:=newstdout;
si.hStdError:=newstdout;
si.hStdInput:=newstdin;
// Create Process
if not CreateProcess(pchar(command), pchar('/a'), nil, nil, true,
CREATE_NEW_CONSOLE, nil, nil, si, pi) then
begin
TriggerConsoleOut('Error creating process: '+command);
CloseHandle(newstdin);
CloseHandle(newstdout);
CloseHandle(read_stdout);
CloseHandle(write_stdin);
exit;
end;
// Loop principal
fillchar(buf, sizeof(buf), 0);
FRC_End:=false;
// FRC_SendBuf:='';
repeat
if FInQueue.count > 0 then
begin
if Length(FRC_SendBuf) = 0 then
begin
waitforsingleobject(pi.hProcess,100); //<----- hier müsste man warten bis die Konsole ready ist hier wäre //sonst eine boolean variable die auf true geht sobald der timer ableuft oder das endzeichen kommt.
if pos('#',FInQueue[0])<> 0 then
begin
CommandTypePos := pos('#1',FInQueue[0]);
OffCharPos := pos('#2',FInQueue[0]);
OffTime:= 20000;
FCommandType:= copy(FInQueue[0],CommandTypePos+2,OffCharPos - (CommandTypePos + 2));
FOffChar:=copy(FInQueue[0],OffCharPos+2,(length(FInQueue[0])+1)-(OffCharPos+2));
ConsoleCommand := copy(FInQueue[0],1,(CommandTypePos-1));
FTimer.Interval := OffTime;
FTimer.Enabled:= true;
FRC_SendBuf := '';
FRC_SendBuf := ConsoleCommand+ CRLF;//FInQueue[0];
FInQueue.Delete(0);
modlogger.AddToLog('der Console Kommando Queue wurde folgendes kommando zur verarbeitung hinausgenommen.' +
FRC_SendBuf, ModDebug);
FReady:= False;
end
else
begin
FOffChar := '';
FTimer.Interval := 20000;
FTimer.Enabled:= true;
FRC_SendBuf := '';
FRC_SendBuf :=FInQueue[0]+ CRLF;
FInQueue.count;
FInQueue.Delete(0);
FReady:= False;
end;
end;
end;
OffTime := OffTime;
application.processmessages;
// Application.HandleMessage;
GetExitCodeProcess(pi.hProcess, FRC_ExitCode);
if (FRC_ExitCode <> STILL_ACTIVE) then FRC_End:=True;
PeekNamedPipe(read_stdout, @buf, bufsize, @bread, @avail, nil);
// Comprobamos texto de salida
if (bread<>0) then begin
fillchar(buf, bufsize, 0);
if (avail > bufsize) then
while (bread >= bufsize) do begin
ReadFile(read_stdout, buf, bufsize, bread, nil);
SplitLines(buf);
fillchar(buf, bufsize, 0);
end
else begin
ReadFile(read_stdout, buf, bufsize, bread, nil);
SplitLines(buf);
end;
end;
// Eingabe text
while (Length(FRC_SendBuf) > 0) do
begin
WriteFile(write_stdin, FRC_SendBuf[1], 1, bread, nil);
Delete(FRC_SendBuf, 1, 1);
end;
until FRC_End or Terminated;
// Close
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
CloseHandle(newstdin);
CloseHandle(newstdout);
CloseHandle(read_stdout);
CloseHandle(write_stdin);
Terminate;
end;
|