windows console createprocess

windows - Hacer CreateProcess heredar la consola del proceso de llamada



console (4)

Lo he hecho pasando las canalizaciones para hStdInput , hStdOutput y hStdError y enrutando manualmente los datos de los hStdOutput y hStdError a la consola.

Cuando llamo a CreateProcess en Windows, el nuevo proceso no parece heredar la consola del proceso de llamada. Hice un programa de prueba que ejecuta "ruby xtest", xtest es una secuencia de comandos que escribe "hola" a la salida estándar. Ejecuté este programa de prueba de Emacs y no obtuve ningún resultado. También probé el siguiente código llamando a GetStdHandle, pero nuevamente, sin salida. Luego intenté pasar CREATE_NEW_CONSOLE en dwCreationFlags a CreateProcess, que creó una nueva ventana con la salida de Ruby. Finalmente, hice un sencillo programa de prueba fork / exec y lo compilé usando Cygwin''s GCC. Este programa funcionó: la salida de Ruby apareció en Emacs como se esperaba. Traté de descifrar el código fuente de Cygwin en http://cygwin.com/cgi-bin/cvsweb.cgi/src/winsup/cygwin/spawn.cc?rev=1.268&content-type=text/x-cvsweb-markup&cvsroot= src pero falló. Entonces, ¿cómo hace que el nuevo proceso herede la consola del proceso principal de modo que la salida del hijo aparezca como se esperaba?

STARTUPINFO si; PROCESS_INFORMATION pi; memset(&si, 0, sizeof(si)); memset(&pi, 0, sizeof(pi)); si.dwFlags |= STARTF_USESTDHANDLES; si.hStdInput = GetStdHandle(STD_INPUT_HANDLE); si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); si.hStdError = GetStdHandle(STD_ERROR_HANDLE); if(!CreateProcess(0, "ruby xtest", 0, 0, 1, 0, 0, 0, &si, &pi)) die("CreateProcess");


No estoy seguro de si deboige alguna vez ha resuelto esto, pero necesitaba lo mismo, pero poner en marcha otro hilo para escuchar la salida de stdout, solo para ponerlo en stdout me pareció una locura.

Lo siguiente funciona para mí, y es ligeramente diferente de lo que publicó originalmente. Al principio pensé que no funcionaría si no configuras si.cb, pero cuando comencé a comentar eso en la mía, funcionó, así que ... YMMV.

STARTUPINFO siStartInfo; ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) ); siStartInfo.cb = sizeof(STARTUPINFO); siStartInfo.hStdError = GetStdHandle(STD_OUTPUT_HANDLE); siStartInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); siStartInfo.hStdInput = g_hChildStd_IN_Rd; // my outgoing pipe siStartInfo.dwFlags |= STARTF_USESTDHANDLES; // Create the child process. bSuccess = CreateProcess( NULL, szCmdline, NULL, NULL, TRUE, 0, NULL, NULL, &siStartInfo, &piProcInfo);


Según la documentación de Microsoft, lpCommandLine (2. parámetro):

La versión Unicode de esta función, CreateProcessW, puede modificar el contenido de esta cadena. Por lo tanto, este parámetro no puede ser un puntero a la memoria de solo lectura (como una variable const o una cadena literal). Si este parámetro es una cadena constante, la función puede causar una infracción de acceso.

Cuando dejé de usar una constante aquí funcionó para mí. No necesitaba las cosas STARTF_USESTDHANDLES y GetStdHandle.

Este código de una consola prg se ejecuta y genera otro exe de consola en la misma consola:

FillChar(SI, SizeOf(SI), 0); SI.cb:=SizeOf(SI); FillChar(PI, SizeOf(PI), 0); if CreateProcess(nil, CmdLineVar, nil, nil, False, 0, nil, nil, SI, PI) then ...


Lo sé, este hilo es bastante viejo, sin embargo, me encontré con el mismo problema.

Al igual que para el TS, el mango de la consola se heredaba y funcionaba bien bajo Cygwin, pero no en una consola de Windows. En cambio, la salida en stdout no se mostró ni se informó ningún error. Los mangos de tubería heredados funcionaron bien.

Me tomó algo de tiempo identificar el problema (ahora obvio): CreateProcess () se llamó con CREATE_NO_WINDOW. Al soltar esta bandera, la salida de la consola está bien. (Aunque, de acuerdo con el código del TS, nunca establecieron esta bandera en primer lugar).

Espero que esto sea útil para las personas que también tropiezan con este hilo, como yo.