windows - getstdhandle - allocconsole include



CreateProcess erben die Konsole des aufrufenden Prozesses (3)

Wenn ich CreateProcess in Windows aufrufen, scheint der neue Prozess die Konsole des aufrufenden Prozesses nicht zu erben. Ich habe ein Testprogramm erstellt, das "ruby xtest" ausführt, wobei xtest ein Skript ist, das "Hallo" in die Standardausgabe schreibt. Ich habe dieses Testprogramm von Emacs ausgeführt und bekomme keine Ausgabe. Ich habe auch den folgenden Code ausprobiert, der GetStdHandle aufruft, aber wieder keine Ausgabe. Dann habe ich versucht, CREATE_NEW_CONSOLE in dwCreationFlags an CreateProcess zu übergeben, wodurch ein ganz neues Fenster mit der Ruby-Ausgabe entstanden ist. Schließlich habe ich ein einfaches fork / exec-Testprogramm erstellt und mit Cygwins GCC kompiliert. Dieses Programm hat funktioniert: Die Ruby-Ausgabe wurde wie erwartet in Emacs angezeigt. Ich habe versucht, den Cygwin-Quellcode in http://cygwin.com/cgi-bin/cvsweb.cgi/src/winsup/cygwin/spawn.cc?rev=1.268&content-type=text/x-cvsweb-markup&cvsroot= zu entschlüsseln src aber fehlgeschlagen. Also, wie lässt der neue Prozess die Konsole des übergeordneten Prozesses erben, sodass die Ausgabe des untergeordneten Elements wie erwartet angezeigt wird?

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

Ich habe dies getan, indem ich Pipes für hStdInput , hStdOutput und hStdError und Daten manuell von den hStdOutput und hStdError zur Konsole hStdError .


Ich bin mir nicht sicher, ob Debeige das jemals gelöst hat, aber ich brauchte das gleiche, aber einen anderen Thread zu starten, um die Ausgabe von stdout zu hören, nur um es auf Standard zu setzen, schien mir verrückt zu sein.

Das Folgende funktioniert für mich und ist etwas anders als das, was er ursprünglich gepostet hat. Ich dachte zuerst, es würde nicht funktionieren, wenn du si.cb nicht einstellst, aber als ich das in meiner kommentiert habe, hat es immer noch funktioniert, also ... 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); 

Ich weiß, dieser Thread ist ziemlich alt, aber ich stieß nur auf das gleiche Problem.

Genau wie für den TS wurde das Konsolen-Handle geerbt und funktioniert unter Cygwin, aber nicht auf einer Windows-Konsole. Stattdessen wurde die Ausgabe von stdout weder angezeigt noch wurde ein Fehler gemeldet. Vererbte Pfeifengriffe funktionierten noch gut.

Ich nahm mir etwas Zeit, um das (jetzt offensichtliche) Problem zu identifizieren: CreateProcess () wurde mit CREATE_NO_WINDOW aufgerufen. Wenn Sie dieses Flag verlassen, ist die Konsolenausgabe in Ordnung. (Nach dem Code des TS haben sie diese Flagge jedoch nie gesetzt.)

Ich hoffe, dass dies hilfreich für Leute sein kann, die auch über diesen Thread stolpern, wie ich.





createprocess