Capturar salida estándard de un proceso

15/12/2003 - 20:27 por Alberto | Informe spam
Hola,

Necesito capturar la salida estándar y de error de un
proceso de consola de comandos. Para ello lo lanzo con
CreateProcess cambiando los handles de la estructura de
información del proceso, pero no me funciona, el comando
se ejecuta, y el texto que envía a la salida estándar y
de error no se envía a los ficheros.
A ver si podeis decirme que es lo que hago mal o si no es
ésta la forma de hacerlo:

(CODE START)


//Defino 3 handles: salida estándard, error y entrada
HANDLE m_hstdIn, m_hstdOut, m_hstdErr;
//Asigno cada handle a un fichero que creo
m_hstdErr = CreateFile(_T("C:\\Test1.txt"),
GENERIC_WRITE, FILE_SHARE_READ,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
m_hstdIn = CreateFile(_T("C:\\Test2.txt"),
GENERIC_WRITE, FILE_SHARE_READ,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
m_hstdOut = CreateFile(_T("C:\\Test3.txt"),
GENERIC_WRITE, FILE_SHARE_READ,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

//Defino las estructuras para lanzar el proceso con
CreateProcess
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
//Cambio el flag para indicar que los handles indicados
son válidos
si.dwFlags |= STARTF_USESTDHANDLES;
//Redirecciono los handles del proceso a crear a los
creados anteriormente (debería enviarse a los ficheros)
si.hStdError = m_hstdErr;
si.hStdInput = m_hstdIn;
si.hStdOutput = m_hstdOut;
ZeroMemory( &pi, sizeof(pi) );

//Lanzo el proceso
CreateProcess(NULL,"c:\test.exe -l -
va",NULL,NULL,false,0,NULL,NULL,&si,&pi);

//Espero a que acabe el proceso
WaitForSingleObject(pi.hProcess, INFINITE);

//Cierro los handles del proceso
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
//Cierro los handles de los ficheros
CloseHandle(m_hstdErr);
CloseHandle(m_hstdIn);
CloseHandle(m_hstdOut);


(CODE END)

La información enviada por el proceso a stdout y stderr,
debería estar en los ficheros, pero éstos están vacíos.
Por otra parte, lo de redireccionar a ficheros lo hago a
modo de test, lo que en realidad necesito es
redireccionarlo a buffers internos de memoria, pero como
no creo que ésto se pueda, utilizaría los archivos
CMemFile.

Muchas gracias por adelantado.
 

Leer las respuestas

#1 Tomas Restrepo \(MVP\)
16/12/2003 - 00:21 | Informe spam
Alberto,

<<
Necesito capturar la salida estándar y de error de un
proceso de consola de comandos. Para ello lo lanzo con
CreateProcess cambiando los handles de la estructura de
información del proceso, pero no me funciona, el comando
se ejecuta, y el texto que envía a la salida estándar y
de error no se envía a los ficheros.
A ver si podeis decirme que es lo que hago mal o si no es
ésta la forma de hacerlo:

(CODE START)


//Defino 3 handles: salida estándard, error y entrada
HANDLE m_hstdIn, m_hstdOut, m_hstdErr;
//Asigno cada handle a un fichero que creo
m_hstdErr = CreateFile(_T("C:\\Test1.txt"),
GENERIC_WRITE, FILE_SHARE_READ,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
m_hstdIn = CreateFile(_T("C:\\Test2.txt"),
GENERIC_WRITE, FILE_SHARE_READ,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
m_hstdOut = CreateFile(_T("C:\\Test3.txt"),
GENERIC_WRITE, FILE_SHARE_READ,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);






Creo que tu problema puede estar en el hecho de que abres el archivo que
contiene la entrada (m_hStdIn) como de escritura, y lo que el proceso que
vas a crear necesita es leer de el. Abrelo con GENERIC_READ, y no con
GENERIC_WRITE.

<<
//Defino las estructuras para lanzar el proceso con
CreateProcess
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
//Cambio el flag para indicar que los handles indicados
son válidos
si.dwFlags |= STARTF_USESTDHANDLES;
//Redirecciono los handles del proceso a crear a los
creados anteriormente (debería enviarse a los ficheros)
si.hStdError = m_hstdErr;
si.hStdInput = m_hstdIn;
si.hStdOutput = m_hstdOut;
ZeroMemory( &pi, sizeof(pi) );

//Lanzo el proceso
CreateProcess(NULL,"c:\test.exe -l -
va",NULL,NULL,false,0,NULL,NULL,&si,&pi);

//Espero a que acabe el proceso
WaitForSingleObject(pi.hProcess, INFINITE);

//Cierro los handles del proceso
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
//Cierro los handles de los ficheros
CloseHandle(m_hstdErr);
CloseHandle(m_hstdIn);
CloseHandle(m_hstdOut);


(CODE END)

La información enviada por el proceso a stdout y stderr,
debería estar en los ficheros, pero éstos están vacíos.
Por otra parte, lo de redireccionar a ficheros lo hago a
modo de test, lo que en realidad necesito es
redireccionarlo a buffers internos de memoria, pero como
no creo que ésto se pueda, utilizaría los archivos
CMemFile.






En realidad lo que comunmente se hace es redireccionarlos a unos pipes, y
luego leer de los pipes la salida.

Tomas Restrepo

Preguntas similares