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

Win32 application write output to console using printf

本文关键字:输出 控制台 printf 应用程序 Win32      更新时间:2023-10-16

我使用Win32应用程序开发了一个EXE。当我运行时(双击)应出现EXE GUI,当我从命令提示符中调用EXE时,应出现在命令控制台中。

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

构建Wilx所说的话(对不起,我没有足够的声誉来对他的答案发表评论),您可以使用arthconsole(...);因此,仅在已经有一个可用的情况下,请连接到控制台,您可以使用以下内容:

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
    // ....
}
此外

这几乎可以做到您想要的:

// Win32Project1.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include <stdio.h>  // printf, _dup2
#include <io.h>     // _open_osfhandle
void SetupConsole()
{
    AttachConsole(ATTACH_PARENT_PROCESS);
    HANDLE hConIn = GetStdHandle(STD_INPUT_HANDLE);
    int fd0 = _open_osfhandle((intptr_t)hConIn, 0);
    _dup2(fd0, 0);
    HANDLE hConOut = GetStdHandle(STD_OUTPUT_HANDLE);
    int fd1 = _open_osfhandle((intptr_t)hConOut, 0);
    _dup2(fd1, 1);
    HANDLE hConErr = GetStdHandle(STD_ERROR_HANDLE);
    int fd2 = _open_osfhandle((intptr_t)hConErr, 0);
    _dup2(fd2, 2);
}
WNDPROC g_pOldProc;
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    if (uMsg == WM_CLOSE)
    {
        PostQuitMessage(0);
        return 0;
    }
    return CallWindowProc(g_pOldProc, hwnd, uMsg, wParam, lParam);
}
void GUI(HINSTANCE hInstance)
{
    HWND hWnd = CreateWindow(
                        _T("EDIT"),
                        _T("GUI"),
                        WS_OVERLAPPEDWINDOW|WS_VISIBLE,
                        100, 100, 200,200,
                        NULL,
                        NULL,
                        hInstance,
                        NULL
                        );
    g_pOldProc = (WNDPROC)SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)&WindowProc);
    SetWindowText(hWnd, _T("Hello world."));
    MSG m;
    while (GetMessage(&m, NULL, 0, 0))
    {
        DispatchMessage(&m);
    }
    DestroyWindow(hWnd);
}
void Console()
{
    SetupConsole();
    printf("Hello world.");
}
int APIENTRY _tWinMain(HINSTANCE hInstance,
                       HINSTANCE hPrevInstance,
                       LPTSTR    lpCmdLine,
                       int       nCmdShow)
{
    HANDLE hConOut = GetStdHandle(STD_OUTPUT_HANDLE);
    if (!hConOut)
        GUI(hInstance);
    else
        Console();
    return 0;
}

我在这里检查了所有提交的解决方案,它们对我不起作用。您始终可以创建(或更改为)控制台子系统。但是,如果您想从WIN32应用中启用写入控制台,而不是分类为控制台应用程序,则此代码将起作用。调用此功能后,您可以使用printf(或wprintf)。

我的代码使用slocconsole(),然后使用artachconsole(),pssing to to to当前过程ID(通过调用getProcessID获得)。

void enableConsole()
{
    AllocConsole();
    AttachConsole(GetCurrentProcessId());
    HWND Handle = GetConsoleWindow();
    freopen("CON", "w", stdout);
}

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


当我已经发布了答案时,TBH,我不确定我是否会完全理解您的问题。我有一些评论的代码(上方AllocConsole()

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

您确定您不能像我一样无条件地使用AllocConsole()吗?

尝试以下:

// 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;
}