내 프로그램 내에서 cmd.exe 출력을 가져 오기 위해 파이프로 작업하고 있습니다. 때로는 cmd.exe가 사용자 입력을 요청하면 (내가 숨겨진 cmd 창을 만들 때) 아무도 창이 입력을 저장하지 않고 cmd가 그대로 남아 있기 때문에 프로그램이 중단됩니다. 그래서 WaitForSingleObject를 구현하여 cmd가 사용자 입력을 요청하거나 다른 이유로 중지하는 경우를 방지합니다. WaitForSingleObject에 대해 반응이 없기 때문에 powershell 명령을 실행하려고하면 문제가 발생하며 항상 시간 초과에 도달합니다. 이 기능은 다음과 같습니다CreateProcess, PowerShell 및 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;
나는이 기능을 전달 호출하는 경우 :
cmd.exe를/C DIR C : \
그것은 확실히 이동합니다.
파워 쉘의 디렉토리에 c : 내가 사용하는 전화하지만 또는 cmd.exe를 \/C PowerShell을 해줄 c :를
\ WaitForSingleObject이는 시간 제한에 도달하고, 아무 일도 발생하지 않습니다. 이거 도와 줘?
롭의 대답은 블록 이유에 대해 정확해야합니다. 나는 파이프를 기다릴 어떤 수단도 생각할 수 없다.아마도 디자인을 변경해야 할 것입니다. 스레드에서 아마도 읽습니다. 또는 스레드에서 기다릴 수도 있습니다. 또는 사용자 입력을 기다리는 mcve를 만들면 문제를 재현 할 수 있습니다. –