2015-05-07 100 views
0

我有一個使用win32應用程序開發的exe。當我運行(雙擊)時,應該會出現exe圖形,並且當我通過命令提示符輸出exe時,應該會出現在命令控制檯中。Win32應用程序使用printf將輸出寫入控制檯

我的問題是我如何使用printf將輸出重定向到命令窗口?我可以使用AllocConsole()在命令窗口中打印,但是會創建新的命令窗口並將輸出重定向到新窗口。我想在使用Win32應用程序調用exe的相同命令窗口中打印輸出。任何幫助讚賞。

+3

[AttachConsole](https://msdn.microsoft.com/en-us/library/windows/desktop /ms681952.aspx)。 – IInspectable

+0

您是否問過如何從命令提示符運行時像命令行程序一樣運行,並在雙擊時使用GUI運行? – crashmstr

+0

不完全重複,但非常密切相關http://stackoverflow.com/questions/24171017/win32-console-application-that-c​​an-open-windows/29687965#29687965 –

回答

0

嘗試使用AttachConsole(ATTACH_PARENT_PROCESS)(或使用PID)連接到現有控制檯。


雖然我已經發布了我的答案,TBH,我不確定我是否完全理解您的問題。我有一個評論,說(如上AllocConsole()一些代碼:。

在這裏,我們忽略了返回值,如果我們已經有一個控制檯,它會失敗

你肯定你不能只需使用AllocConsole()無條件地像我這樣做?

+0

AllocConsole僅在您想要創建新控制檯時纔有用。 OP想要使用現有的控制檯(如果有的話)或根本沒有控制檯(如果沒有)。 –

+0

我嘗試使用AttachConsole(ATTACH_PARENT_PROCESS),它將打開新的cmd窗口。我的問題陳述是我打開一個cmd窗口,並去我的exe文件存在的位置(C:\ test.exe),然後從相同的cmd窗口運行exe文件。 On包括AttachConsole()輸出顯示在新的cmd窗口中。 – user1881297

+0

@ user1881297:好吧,那不應該發生。 AttachConsole()不應該創建一個新的控制檯!你能給我們[一個MCVE](http://stackoverflow.com/help/mcve)嗎? –

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

問題是命令行界面不知道等待您的程序退出,因此您的輸出將與命令行提示混合在一起。如果您需要輸入,問題會更加嚴重。 –

+0

好點的哈利。從控制檯應用程序開始,並通過參數隱藏控制檯可能是唯一的方法來獲得一個exe的關閉。 – Dustin

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; 
} 
+0

AllocConsole僅在您想要創建新控制檯時纔有用。 OP想要使用現有的控制檯(如果有的話)或根本沒有控制檯(如果沒有)。 –

+0

我嘗試使用AttachConsole(ATTACH_PARENT_PROCESS),它將打開新的cmd窗口。我的問題陳述是我打開一個cmd窗口,並去我的exe文件存在的位置(C:\ test.exe),然後從相同的cmd窗口運行exe文件。 On包括AttachConsole()輸出顯示在新的cmd窗口中。 – user1881297

0

這幾乎做你想做的:

// 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; 
} 
相關問題