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

发布于 2024-09-01 16:12:25 字数 340 浏览 3 评论 0原文

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

Is it possible to somehow change standart I/O functions handle on Windows? Language preffered is C++. If I understand it right, by selecting console project, compiler just pre-allocate console for you, and operates all standart I/O functions to work with its handle. So, what I want to do is to let one Console app actually write into another app Console buffer. I though that I could get first´s Console handle, than pass it to second app by a file (I don´t know much about interprocess comunication, and this seems easy) and than somehow use for example prinf with the first app handle. Can this be done? I know how to get console handle, but I have no idea how to redirect printf to that handle. Its just study-purpose project to more understand of OS work behind this. I am interested in how printf knows what Console it is assiciated with.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

执笏见 2024-09-08 16:12:25

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

If I understand you correctly, it sounds like you want the Windows API function AttachConsole(pid), which attaches the current process to the console owned by the process whose PID is pid.

迷你仙 2024-09-08 16:12:25

如果我理解正确,您可以在 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 调用的参数中稍微改变这一行为(但前提是您在代码中启动子进程)。您根据链接器开关 /subsystem 定义的 EXE 的 Subsystem 标志(请参阅 http://msdn.microsoft.com/en-us/library/fcc1zstk%28VS.80%29.aspx)。

If I understand you correct you can find the source code of application which you want to write in http://msdn.microsoft.com/en-us/library/ms682499%28VS.85%29.aspx. This example show how to write in stdin of another application and read it's stdout.

For general understanding. Compiler don't "pre-allocate console for you". Compiler use standard C/C++ libraries which write in the output. So if you use for example printf() the following code will be executed at the end will look like:

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 (
}

So if one changes the value of STD_OUTPUT_HANDLE all output will be go to a file/pipe and so on. If instead of WriteFile the program use WriteConsole function such redirection will not works, but standard C/C++ library don't do this.

If you want redirect of stdout not from the child process but from the current process you can call SetStdHandle() directly (see http://msdn.microsoft.com/en-us/library/ms686244%28VS.85%29.aspx).

The "allocating of console" do a loader of operation system. It looks the word of binary EXE file (in the Subsystem part of IMAGE_OPTIONAL_HEADER see http://msdn.microsoft.com/en-us/library/ms680339%28VS.85%29.aspx) and if the EXE has 3 on this place (IMAGE_SUBSYSTEM_WINDOWS_CUI), than it use console of the parent process or create a new one. One can change a little this behavior in parameters of CreateProcess call (but only if you start child process in your code). This Subsystem flag of the EXE you define with respect of linker switch /subsystem (see http://msdn.microsoft.com/en-us/library/fcc1zstk%28VS.80%29.aspx).

拧巴小姐 2024-09-08 16:12:25

如果您想将 printf 重定向到句柄(FILE*),只需执行

fprintf(handle, "...");

例如用 fprintf 复制 printf

fprintf(stdout, "...");

或错误报告

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

这也是如何你写入文件。 fprintf(file, "Blah.");

If you want to redirect printf to a handle (FILE*), just do

fprintf(handle, "...");

For example replicating printf with fprintf

fprintf(stdout, "...");

Or error reporting

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

This is also how you write to files. fprintf(file, "Blah.");

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文