使CreateProcessinheritance调用进程的控制台

当我在Windows中调用CreateProcess时,新进程似乎不会inheritance调用进程的控制台。 我做了一个运行“ruby xtest”的testing程序,xtest是一个将“hello”写入标准输出的脚本。 我从Emacs运行这个testing程序,并没有输出。 我也尝试了下面的代码调用GetStdHandle,但是再次没有输出。 然后,我尝试将dwCreationFlags中的CREATE_NEW_CONSOLE传递给CreateProcess,它使用Ruby输出创build了一个全新的窗口。 最后,我做了一个简单的fork / exectesting程序,并使用Cygwin的GCC进行编译。 这个程序的工作:Ruby的输出显示在Emacs的预期。 我尝试破译Cygwin源代码http://cygwin.com/cgi-bin/cvsweb.cgi/src/winsup/cygwin/spawn.cc?rev=1.268&content-type=text/x-cvsweb-markup&cvsroot= src但失败。 那么,如何使新进程inheritance父进程的控制台,以便subprocess的输出按预期显示?

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

我知道,这个线程比较老,但是我碰到了同样的问题。

就像TS一样,控制台句柄在Cygwin下被继承并正常工作,但在Windows控制台上却不能。 相反,标准输出没有显示,也没有报告任何错误。 继承管道手柄仍然正常工作。

我花了一些时间来确定(现在很明显)的问题:使用CREATE_NO_WINDOW调用CreateProcess()。 放弃这个标志,控制台输出是好的。 (根据TS的代码,他们从来没有设置这个标志。)

希望这可能对那些也偶然发现这个线索的人有帮助,就像我自己一样。

根据Microsoft文档, lpCommandLine (2.参数):

此函数的Unicode版本CreateProcessW可以修改此字符串的内容。 因此,这个参数不能是指向只读内存的指针(如const变量或文字串)。 如果此参数是一个常量字符串,该函数可能会导致访问冲突。

当我在这里停止使用一个常量,它为我工作。 我不需要STARTF_USESTDHANDLES和GetStdHandle的东西。

从控制台prg这个代码运行并输出在同一控制台中的另一个控制台exe:

 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 ... 

我已经通过传入hStdInputhStdOutputhStdError管道,并将数据从hStdOutputhStdError管道手动路由到控制台来完成此操作。

不知道debeige是否解决了这个问题,但是我需要同样的东西,但是启动另一个线程来监听stdout输出,只是把它放在stdout上似乎对我来说很难。

以下这些对我来说是有用的,而且与他原先的发布略有不同。 如果你没有设置si.cb,我想一开始是行不通的,但是当我评论说在我的时候,它仍然有效,所以… 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);