2010-05-12 79 views
0

是否有可能以某种方式更改Windows上的标准I/O功能句柄?提供的语言是C++。如果我理解正确,通过选择控制台项目,编译器只需为您预先分配控制台,并操作所有标准I/O函数以处理其句柄。所以,我想要做的是让一个控制台应用程序实际写入另一个应用程序控制台缓冲区。虽然我可以获得第一个控制台句柄,但是通过文件将其传递给第二个应用程序(我不太了解进程间通信,而且这看起来很简单),并且以某种方式用于第一个应用程序句柄的prinf。这可以做到吗?我知道如何获得控制台句柄,但我不知道如何将printf重定向到该句柄。它只是为了学习目的而更加了解OS背后的工作。我感兴趣的是printf如何知道它所控制的控制台。更改默认控制台I/O功能句柄

回答

0

如果我理解你正确,你可以在http://msdn.microsoft.com/en-us/library/ms682499%28VS.85%29.aspx找到你想写的应用程序的源代码。这个例子展示了如何写stdin的另一个应用程序,并阅读它的stdout

一般理解。编译器不会“为您预先分配控制台”。编译器使用在输出中写入的标准C/C++库。所以,如果你使用例如printf()下面的代码将在年底执行的样子:

void Output (PCWSTR pszwText, UINT uTextLenght) // uTextLenght is Lenght in charakters 
{ 
    DWORD n; 
    UINT uCodePage = GetOEMCP(); // CP_OEMCP, CP_THREAD_ACP, CP_ACP 
    PSTR pszText = _alloca (uTextLenght); 

    // in the console are typically not used UNICODE, so 
    if (WideCharToMultiByte (uCodePage, 0, pszwText, uTextLenght, 
          pszText, uTextLenght, NULL, NULL) != (int)uTextLenght) 
     return; 

    WriteFile (GetStdHandle (STD_OUTPUT_HANDLE), pszText, uTextLenght, &n, NULL); 
    //_tprintf (TEXT("%.*ls"), uTextLenght, pszText); 
    //_puttchar(); 
    //fwrite (pszText, sizeof(TCHAR), uTextLenght, stdout); 
    //_write (
} 

所以,如果一个人改变的STD_OUTPUT_HANDLE的值的所有输出将去一个文件/管材等。如果程序使用WriteConsole而不是WriteFile这样的重定向功能不起作用,但标准C/C++库不这样做。

如果您不想从子进程中重定向stdout,而是从当前进程中直接调用SetStdHandle()(请参阅http://msdn.microsoft.com/en-us/library/ms686244%28VS.85%29.aspx)。

“控制台分配”做一个操作系统的加载程序。它看起来是二进制EXE文件(IMAGE_OPTIONAL_HEADER的子系统部分,参见http://msdn.microsoft.com/en-us/library/ms680339%28VS.85%29.aspx),如果EXE在这个地方有3个(IMAGE_SUBSYSTEM_WINDOWS_CUI),它会使用父进程的控制台或创建一个新进程。可以在CreateProcess调用的参数中改变一点这种行为(但只有当您在代码中启动子进程时)。您在链接器开关/子系统方面定义的EXE标志(请参阅http://msdn.microsoft.com/en-us/library/fcc1zstk%28VS.80%29.aspx)。

0

如果你想printf重定向到一个手柄(FILE *),只是做

fprintf(handle, "..."); 

例如复制printffprintf

fprintf(stdout, "..."); 

或错误报告

fprintf(stderr, "FATAL: %s fails", "smurf"); 

这也是你写入文件的方式。 fprintf(file, "Blah.");

+0

谢谢。那么,fprintf是可重定向的printf?而且,printf如何知道它是默认的控制台? – 2010-05-13 15:57:37

+0

默认情况下,printf会转到“stdout”引用的任何标准输出。主要是控制台,或者重定向(“yourprogram> output.txt”)重定向的文件。 – LukeN 2010-05-13 16:16:53

1

如果我的理解正确,听起来好像您需要Windows API函数AttachConsole(pid),该函数将当前进程附加到PID为pid的进程所拥有的控制台。

+0

我认为你是对的。 http://msdn.microsoft.com/en-us/library/ms681952%28VS.85%29.aspx – dss539 2010-05-12 21:37:24