Могу ли я получить доступ к строке, возвращенной из команды Delphi CreateProcess? - PullRequest
1 голос
/ 05 декабря 2008

Я использую функцию Win32 CreateProcess для вызова внешнего исполняемого файла. Исполняемый файл возвращает строку.

Есть ли способ, которым я могу захватить и опросить возвращенную строку после вызова исполняемого файла? В противном случае мне, возможно, придется записать строку в файл в исполняемом файле и прочитать ее в вызывающей программе после завершения вызова. Хотя это кажется отстойным.

Ответы [ 4 ]

8 голосов
/ 05 декабря 2008

Библиотека кодов джедаев содержит функцию CreateDOSProcessRedirected, которая запускает процесс и предоставляет ему файл ввода и вывода. Вы можете поместить необходимые входные данные (если они есть) во входной файл и прочитать выходные данные процесса (если есть) из выходного файла (после завершения процесса).

Вот как это реализовано в 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;
3 голосов
/ 05 декабря 2008

Предполагая, что вы хотите записать то, что исполняемый файл пишет в стандартный вывод, Вы можете начать это с

yourprog.exe > results.txt

Это запишет вывод в results.txt, который вы затем сможете прочитать и оценить.

Или вы можете попробовать метод, описанный в этой теме : создать канал для вывода из вашего порожденного процесса и прочитать его. Пост № 7 содержит исходный пример того, как использовать соответствующие функции WinApi в C ++, которые легко можно перевести на Delphi.

2 голосов
/ 05 декабря 2008

Как исполняемый файл возвращает строку ? Больше всего я знаю, что исполняемый файл может возвращать только число, код выхода.

1 голос
/ 05 декабря 2008

Вы можете использовать общую память для связи между двумя приложениями.

Вы можете использовать функцию Win32 CreateFileMapping и, возможно, использовать мьютекс для синхронизации вызовов с отображенным в память файлом.

Следующий код создает файл.

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);

следующий код закрывает файл карты

if PMapData <> nil then
  UnMapViewOfFile(PMapData);
if fMapping <> 0 then
  CloseHandle(fMapping);
...