我用Delphi XE2編寫了需要執行命令行程序(也用Delphi XE2編寫)的VCL應用程序並獲取其輸出的文本。我目前使用下面的代碼,這是基於在這裏找到:Getting output from a shell/dos app into a Delphi app從Windows XP上的Delphi應用程序中的命令行程序獲取輸出
function GetDosOutput(ACommandLine : string; AWorkingDirectory : string): string;
var
SecurityAttributes : TSecurityAttributes;
StartupInfo : TStartupInfo;
ProcessInformation: TProcessInformation;
StdOutPipeRead, StdOutPipeWrite: THandle;
WasOK: Boolean;
Buffer: array[0..255] of AnsiChar;
BytesRead: Cardinal;
Handle: Boolean;
begin
Result := '';
SecurityAttributes.nLength := SizeOf(TSecurityAttributes);
SecurityAttributes.bInheritHandle := True;
SecurityAttributes.lpSecurityDescriptor := nil;
CreatePipe(StdOutPipeRead, StdOutPipeWrite, @SecurityAttributes, 0);
try
FillChar(StartupInfo, SizeOf(TStartupInfo), 0);
StartupInfo.cb := SizeOf(TStartupInfo);
StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
StartupInfo.wShowWindow := SW_HIDE;
StartupInfo.hStdInput := StdOutPipeRead;
StartupInfo.hStdOutput := StdOutPipeWrite;
StartupInfo.hStdError := StdOutPipeWrite;
FillChar(ProcessInformation, SizeOf(ProcessInformation), 0);
Handle := CreateProcess(
nil,
PChar(ACommandLine),
nil,
nil,
True,
0,
nil,
PChar(AWorkingDirectory),
StartupInfo,
ProcessInformation
);
CloseHandle(StdOutPipeWrite);
if Handle then
try
repeat
WasOK := ReadFile(StdOutPipeRead, Buffer, 255, BytesRead, nil);
if BytesRead > 0 then
begin
Buffer[BytesRead] := #0;
Result := Result + Buffer;
end;
until not WasOK or (BytesRead = 0);
WaitForSingleObject(ProcessInformation.hProcess, INFINITE);
finally
CloseHandle(ProcessInformation.hThread);
CloseHandle(ProcessInformation.hProcess);
end;
finally
CloseHandle(StdOutPipeRead);
end;
end;
這適用於Windows的大多數版本的罰款。不幸的是,最近我們注意到它在Windows XP上不起作用。對WaitForSingleObject的調用根本不會返回。我嘗試用較小的值(例如15000)替換第二個參數INFINITE,但這似乎沒有任何區別。在任務管理器中,我可以看到,在調用GetDosOutput之後,命令行程序實際上正在運行。如果我結束了VCL應用程序,命令行程序然後似乎成功地完成了它的工作(證明它輸出我期待它的文件)。我也注意到,如果我從StartupInfo.dwFlags中刪除STARTF_USESTDHANDLES,命令行程序正常運行,WaitForSingleObject立即返回;但是我顯然無法獲得程序返回的文本。
有沒有人有關於如何在Windows XP上運行的建議?
您可以找到正確的代碼在回答以下任務: http://stackoverflow.com/questions/9119999/getting-output-from-a-shell-dos-app-into-a-delphi-app/9120103#9120103 –
我喜歡讀這一點:Handle:Boolean –
@DavidHeffernan對於具有強類型背景的人來說,winAPI的BOOL類型可能會引起混淆。 – mg30rg