Note that there are some explanatory texts on larger screens.

plurals
  1. POGetting output from a command-line program in a Delphi application on Windows XP
    text
    copied!<p>I have VCL application written in Delphi XE2 that needs to execute a command-line program (also written in Delphi XE2) and obtain the text output by it. I am currently using the following code, which is based on that found here: <a href="https://stackoverflow.com/questions/9119999/getting-output-from-a-shell-dos-app-into-a-delphi-app/9120103#9120103">Getting output from a shell/dos app into a Delphi app</a></p> <pre><code>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 &gt; 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; </code></pre> <p>This works fine on most versions of Windows. Unfortunately it has recently come to our attention that it does not work on Windows XP. The call to WaitForSingleObject simply never returns. I tried replacing the second parameter INFINITE with a smaller value (e.g. 15000) but that doesnt't seem to make any difference. In Task Manager I can see that, after calling GetDosOutput, the command-line program is actually running. If I end the VCL application, the command-line program <em>then</em> seems to complete its work successfully (as evidenced by the fact that it outputs the files I was expecting it to). I've also noticed that if I remove STARTF_USESTDHANDLES from StartupInfo.dwFlags, the command-line program runs normally and WaitForSingleObject returns promptly; however I am then obviously unable to obtain the text returned by the program.</p> <p>Does anybody have a suggestion as to how I can get this working on Windows XP?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload