Win32应用程序使用printf将输出写入控制台

时间:2015-05-07 10:20:08

标签: c++ windows winapi

我有一个使用win32应用程序开发的exe。当我运行(双击)时,应该出现exe GUI,当我从命令提示符调用exe时,输出应该出现在命令控制台中。

我的问题是如何使用printf将输出重定向到命令窗口?我可以使用AllocConsole()在命令窗口中打印,但是会创建新的命令窗口并将输出重定向到新窗口。我想在使用Win32应用程序调用exe的同一命令窗口中打印输出。任何帮助表示赞赏。

4 个答案:

答案 0 :(得分:3)

要建立在wilx所说的内容上(抱歉,我没有足够的声誉来评论他的回答)你可以使用AttachConsole(...);所以如果只有那里就附加到控制台已经有一个你可以使用的东西:

bool bAttachToConsole()
{
    if (!AttachConsole(ATTACH_PARENT_PROCESS))
    {
        if (GetLastError() != ERROR_ACCESS_DENIED) //already has a console
        {
            if (!AttachConsole(GetCurrentProcessId()))
            {
                DWORD dwLastError = GetLastError();
                if (dwLastError != ERROR_ACCESS_DENIED) //already has a console
                {
                    return false;
                }
            }
        }
    }

    return true;
}

然后在你的WinMain中你可以这样做:

if (bAttachToConsole())
{
    //do your io with STDIN/STDOUT
    // ....
}
else
{
    //Create your window and do IO via your window
    // ....
}

此外,您必须"修复"使用新控制台的c标准IO句柄请参阅以下write up以获取有关如何执行此操作的一个很好的示例。

答案 1 :(得分:1)

这几乎可以满足您的需求:

/usr/bin/play

答案 2 :(得分:0)

尝试使用AttachConsole(ATTACH_PARENT_PROCESS)(或使用PID)附加到现有控制台。

虽然我已经发布了我的答案,TBH,但我不确定我是否确切地理解了你的问题。我有一些代码有一条评论(上面是AllocConsole()

  

我们忽略了返回值。如果我们已经有一个控制台,它将失败。

您确定不能像我一样无条件地使用{{1}}吗?

答案 3 :(得分:0)

试试这个:

// Win32Project1.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include <stdio.h>  // printf
#include <io.h>     // _open_osfhandle, _dup2

void SetupConsole()
{
    BOOL bCreated = AllocConsole();
    if (!bCreated)
        return; // We already have a console.

    HANDLE hConOut = GetStdHandle(STD_OUTPUT_HANDLE);
    int fd = _open_osfhandle((intptr_t)hConOut, 0);
    _dup2(fd, 1);

}

int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPTSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
    SetupConsole();
    printf("Hello world!");
    Sleep(10000);

    return 0;
}