Pregunta

Estoy usando la función Win32 CreateProcess para realizar una llamada a un ejecutable externo. El ejecutable devuelve una cadena.

¿Hay alguna forma de capturar e interrogar la cadena devuelta después de llamar al ejecutable? De lo contrario, podría tener que escribir la cadena en un archivo en el ejecutable y leer eso en el programa de llamada después de que la llamada haya finalizado. Sin embargo, eso parece poco convincente.

¿Fue útil?

Solución

Jedi Code Library contiene la función CreateDOSProcessRedirected que ejecuta un proceso y le proporciona archivos de entrada y salida. Puede poner la entrada requerida (si la hay) en el archivo de entrada y leer la salida del proceso (si la hay) del archivo de salida (después de que el proceso se haya completado).

Así es como se implementa esto en el 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;

Otros consejos

Suponiendo que desea capturar lo que el exe está escribiendo en la salida estándar, puedes comenzar con

yourprog.exe > results.txt

Esto escribirá la salida en results.txt , que luego podrá leer y evaluar.

O puede probar el método explicado en este hilo : Cree una tubería para el resultado de su proceso generado y leerlo. La publicación número 7 tiene un ejemplo fuente sobre cómo usar las funciones relevantes de WinApi en C ++, que debería traducirse fácilmente a Delphi.

¿Cómo devuelve el ejecutable una cadena ? Lo máximo que sé que puede devolver un ejecutable es solo un número, el código de salida.

Puede usar la memoria compartida para comunicarse entre las dos aplicaciones.

Puede usar la función Win32 CreateFileMapping, y quizás usar un mutex para sincronizar llamadas al archivo mapeado de memoria.

El siguiente código crea el archivo.

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

el siguiente código cierra el mapfile

if PMapData <> nil then
  UnMapViewOfFile(PMapData);
if fMapping <> 0 then
  CloseHandle(fMapping);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top