Ich arbeite mit Rohrleitungen, um die cmd.exe Ausgabe in meinem Programm zu bekommen. Manchmal habe ich bemerkt, dass, wenn die cmd.exe nach Benutzereingaben fragt (ich erstelle ein verstecktes cmd-Fenster), das Programm hängt, weil niemand die Eingabe in das Fenster legt, und der cmd bleibt einfach. Also habe ich WaitForSingleObject implementiert, um zu verhindern, dass die Fälle, in denen cmd nach Benutzereingaben fragt oder sich einfach aus einem anderen Grund aufhängt, hängen bleiben. Das Problem tritt auf, wenn ich versuche, Powershell-Befehle auszuführen, weil es für WaitForSingleObject nicht mehr reagiert und ich immer das Timeout erreiche. Die Funktion ist:CreateProcess, PowerShell und WaitForSingleObject
function GetDosOutput(const Exe, Param: string): string;
const
InheritHandleSecurityAttributes: TSecurityAttributes =
(nLength: SizeOf(TSecurityAttributes); bInheritHandle: True);
var
hReadStdout, hWriteStdout: THandle;
si: TStartupInfo;
pi: TProcessInformation;
WaitTimeout, BytesRead: DWord;
lReadFile: boolean;
Buffer: array[0..255] of AnsiChar;
begin
Result:= '';
if CreatePipe(hReadStdout, hWriteStdout, @InheritHandleSecurityAttributes, 0) then
begin
try
si:= Default(TStartupInfo);
si.cb:= SizeOf(TStartupInfo);
si.dwFlags:= STARTF_USESTDHANDLES;
si.hStdOutput:= hWriteStdout;
si.hStdError:= hWriteStdout;
if CreateProcess(Nil, PChar(Exe + ' ' + Param), Nil, Nil, True, CREATE_NO_WINDOW,
Nil, PChar(ExtractFilePath(ParamStr(0))), si, pi) then
begin
CloseHandle(hWriteStdout);
while True do
begin
try
WaitTimeout:= WaitForSingleObject(pi.hProcess, 20000);
if WaitTimeout = WAIT_TIMEOUT then
begin
Result:= 'No result available';
break;
end
else
begin
repeat
lReadFile:= ReadFile(hReadStdout, Buffer, SizeOf(Buffer) - 1, BytesRead, nil);
if BytesRead > 0 then
begin
Buffer[BytesRead]:= #0;
OemToAnsi(Buffer, Buffer);
Result:= Result + String(Buffer);
end;
until not (lReadFile) or (BytesRead = 0);
end;
if WaitTimeout = WAIT_OBJECT_0 then
break;
finally
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
end;
end;
end;
finally
CloseHandle(hReadStdout);
end;
end;
end;
Wenn ich diese Funktion übergeben nennen:
cmd.exe/C dir c: \
Es geht in Ordnung. Aber wenn ich rufe mit:
Power dir c: \ oder cmd.exe/C Power dir c: \
Die WaitForSingleObject erreicht das Timeout, und nichts passiert. Irgendwelche Hilfe bei diesem?
Robs Antwort sollte über den Blockgrund genau sein. Ich kann mir aber keine Möglichkeit vorstellen, auf eine Pfeife zu warten.Wahrscheinlich müssen Sie Ihr Design ändern. Vielleicht einen Thread einlesen. Oder warte vielleicht in einem Thread. Oder machen Sie ein mcve, bei dem das Warten auf Benutzereingaben aufhört, damit wir das Problem reproduzieren können. –