¿Puedo acceder a la cadena devuelta por un comando Delphi CreateProcess?
-
19-08-2019 - |
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.
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);