Can I access the string returned from a Delphi CreateProcess command?

依然范特西╮ 提交于 2019-12-03 09:08:17

Jedi Code Library contains function CreateDOSProcessRedirected which runs a process and provides it with input and output file. You can put required input (if any) into the input file and read process output (if any) from the output file (after the process has completed).

That's how this is implemented in the JCL:

function CreateDOSProcessRedirected(const CommandLine, InputFile, OutputFile: string): Boolean;
var
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
  SecAtrrs: TSecurityAttributes;
  hInputFile, hOutputFile: THandle;
begin
  Result := False;
  hInputFile := CreateFile(PChar(InputFile), GENERIC_READ, FILE_SHARE_READ,
    CreateInheritable(SecAtrrs), OPEN_EXISTING, FILE_ATTRIBUTE_TEMPORARY, 0);
  if hInputFile <> INVALID_HANDLE_VALUE then
  begin
    hOutputFile := CreateFile(PChar(OutPutFile), GENERIC_READ or GENERIC_WRITE,
      FILE_SHARE_READ, CreateInheritable(SecAtrrs), CREATE_ALWAYS,
      FILE_ATTRIBUTE_TEMPORARY, 0);
    if hOutputFile <> INVALID_HANDLE_VALUE then
    begin
      FillChar(StartupInfo, SizeOf(StartupInfo), #0);
      StartupInfo.cb := SizeOf(StartupInfo);
      StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
      StartupInfo.wShowWindow := SW_HIDE;
      StartupInfo.hStdOutput := hOutputFile;
      StartupInfo.hStdInput := hInputFile;
      Result := CreateProcess(nil, PChar(CommandLine), nil, nil, True,
        CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, nil, StartupInfo,
        ProcessInfo);
      if Result then
      begin
        WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
        CloseHandle(ProcessInfo.hProcess);
        CloseHandle(ProcessInfo.hThread);
      end;
      CloseHandle(hOutputFile);
    end;
    CloseHandle(hInputFile);
  end;
end;

Assuming that you want to capture what the exe is writing to the standard output, you can start it with

yourprog.exe > results.txt

This will write the output to results.txt, which you can then read and evaluate.

Or, you can try the method explained in this thread: Create a pipe for the output from your spawned process and read from it. Post number 7 has a source example on how to use the relevant WinApi functions in C++, that should easily translate into Delphi.

How does the executable return a string? The most I know an executable can return is just a number, the exit code.

You could use shared memory to communicate between the two applications.

You can use the Win32 CreateFileMapping function, and perhaps use a mutex to synchronise calls to the memory mapped file.

The following code creates the file.

var
  fMapping : THandle;
  pMapData : Pointer;

fMapping := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE,
             0, MAPFILESIZE, pchar('MAP NAME GOES HERE'));

PMapData := MapViewOfFile(fMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0);

the following code closes the mapfile

if PMapData <> nil then
  UnMapViewOfFile(PMapData);
if fMapping <> 0 then
  CloseHandle(fMapping);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!