代码之家  ›  专栏  ›  技术社区  ›  B.Gen.Jack.O.Neill

更改默认控制台I/O功能句柄

  •  0
  • B.Gen.Jack.O.Neill  · 技术社区  · 15 年前

    是否可以通过某种方式更改Windows上的Standart I/O函数句柄?语言预置为C++。如果我理解的正确,通过选择控制台项目,编译器只需为您预先分配控制台,并操作所有Standart I/O函数来处理它的句柄。所以,我想做的是让一个控制台应用程序实际写入另一个应用程序控制台缓冲区。我认为我可以得到第一个控制台句柄,而不是通过一个文件把它传递给第二个应用程序(我对进程间通信不太了解,而且这看起来很容易),也不至于以某种方式使用第一个应用程序句柄,例如prinf。能做到吗?我知道如何获取控制台句柄,但我不知道如何将printf重定向到该句柄。它只是一个研究目的的项目,目的是更深入地了解操作系统背后的工作。我对printf如何知道它与哪个控制台相关感兴趣。

    3 回复  |  直到 15 年前
        1
  •  0
  •   Oleg    15 年前

    如果我理解你的正确,你可以找到你想写的应用程序的源代码。 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 所有输出将转到文件/管道等。如果不是 WriteFile 程序使用 WriteConsole 这样的重定向函数不起作用,但是标准的C/C++库不这样做。

    如果你想重定向 标准输出 不是从子进程,而是从当前进程调用 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 )如果这个地方有3个( IMAGE_SUBSYSTEM_WINDOWS_CUI ,而不是使用父进程的控制台或创建新进程。我们可以在以下参数中稍微改变这种行为: CreateProcess 调用(但仅当您在代码中启动子进程时)。这个 Subsystem 针对链接器开关/子系统定义的exe的标志(请参见 http://msdn.microsoft.com/en-us/library/fcc1zstk%28VS.80%29.aspx )

        2
  •  1
  •   Jon Purdy    15 年前

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

        3
  •  0
  •   LukeN    15 年前

    如果你想重定向 printf 对于句柄(文件*),只需执行

    fprintf(handle, "...");
    

    例如复制 普林特 具有 fprintf

    fprintf(stdout, "...");
    

    或错误报告

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

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