【问题标题】:How to get console output data into command prompt?如何将控制台输出数据输入命令提示符?
【发布时间】:2013-10-09 07:34:41
【问题描述】:

我有一个基于 Windows 的应用程序。我使它适用于GUI ModeConsole Mode。在GUI modeConsole mode 中,我使用AttachConsole() 附加Console,以将输出打印语句显示到控制台。现在的挑战是,当我在console modeCommand prompt 中使用它时,我不需要启动新控制台。 假设在命令提示符下,我将其运行为

d:\Project path > MyApp.exe consolemode**Enter**

然后由于Attachconsole(),它会打开另一个控制台。现在,当我禁用AttachConsole() 时,它不会打开新控制台,也不会在命令提示符中显示输出。但我的要求是在commandprompt 中显示输出,而不是在从 comamnd 提示符执行时调出新的控制台。

Myapp.cpp
Winmain()
{
....
...
AttachConsole();
cout << "Console Attached \n";
// Some more output
}

所以,当我从命令提示符运行 myapp.exe d:\Project path &gt; MyApp.exe consolemode**Enter** 它附加一个new console 并在新的控制台窗口中打印输出。现在我的要求是我需要禁用AttachConsole(); 并希望在命令提示符下查看输出。

Myapp.cpp
Winmain()
{
....
...
//AttachConsole(); //Now I an disabling console
cout << "Console Attached \n";
// Some more output
}

如果您查看上面的代码,我已禁用 AttachConsole()。现在想当我做,

d:\Project path &gt; MyApp.exe consolemode**Enter** 输出将出现在命令提示符下。如下所示

d:\Project path > MyApp.exe consolemode **Enter**
Console Attached
....
...
d:\Project path >

请帮帮我

【问题讨论】:

  • 你能提供一些最小的示例代码,演示问题吗?
  • @idji:我添加了更多输入,请检查
  • 我的意思是一些可以编译和运行的代码来演示问题。这样的例子至少可以在你的机器上这样做。
  • 我的猜测是,当您为以后的Attach 创建新的控制台对象时,您会弄乱默认输出。因此,在这种情况下,您还需要注释掉该行。
  • 澄清一下:如果您从现有控制台启动程序并调用 AttachConsole(ATTACH_PARENT_PROCESS),您会得到一个新控制台吗?我希望 AttachConsole 会使用以前的控制台(如果存在)。

标签: c++ visual-studio-2010 visual-c++ mfc console


【解决方案1】:

您应该获取当前正在运行的窗口的句柄并对其进行处理,这样您就不需要 allocconsole。此外,您必须找到光标所在的位置并指定您的输出应该写在那里。

HANDLE hStdout;
CONSOLE_SCREEN_BUFFER_INFO csbi; 

void cp( HANDLE hConsole,wchar_t* output )
{


    DWORD cCharsWritten; 
    COORD  crCurr;
    GetConsoleScreenBufferInfo(hStdout, &csbi);
    crCurr = csbi.dwCursorPosition;

    std::wstring ss;
    ss=output;

    if( !WriteConsoleOutputCharacter( hConsole,       
                                ss.c_str(),     
                                (DWORD)ss.length(), 
                                crCurr,     
                                &cCharsWritten ))
    {
      return;
    }

}

int main( void )
{

    hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
    GetConsoleScreenBufferInfo(hStdout, &csbi);

    function(hStdout,L"string");
    return 0;
}

【讨论】:

    【解决方案2】:

    一个进程只能有一个控制台。因此,如果已经有一个控制台,那么 AllocConsole 将失败,但如果您尚未附加到父进程的控制台,则 AttachConsole 将成功。如果您从命令提示符运行,您将已经附加到父控制台,即 cmd.exe,并且 AttachConsole 也会失败(除非您先调用 FreeConsole)。如果没有控制台(“GUI 模式”),则 AllocConsole 将成功(如果您知道具有可以附加到的控制台的进程的 PID 并且您有足够的访问权限,则 AttachConsole 也会成功)。所以你只需要首先尝试分配,如果失败则调用 AttachConsole(-1),如果失败则调用 AllocConsole(或 FreeConsole 然后 AttachConsole)。注意:如果您通过 AllocConsole 创建控制台,则不必同时调用 AttachConsole(AttachConsole 仅用于附加到不同的控制台,通常是不同进程的控制台)。

    如果不想在“控制台模式”下使用cmd.exe控制台,可以调用FreeConsole(看到AllocConsole失败确定已经有控制台后),那么AllocConsole就会成功。此 FreeConsole 不会影响父进程的控制台。

    如果您想使用标准输出函数(例如 printf 或 cout)写入您使用 AllocConsole 分配的控制台,或者在“GUI”模式下运行时使用 scanf 从控制台读取,您必须显式设置标准句柄,如下所示:

        freopen("CON", "w", stdout);
        freopen("CON", "w", stderr);
        freopen("CON", "r", stdin);
    

    不久前,我写了一篇关于如何做到这一点的博客文章。我意识到发布链接是不受欢迎的,但我认为你会发现它很有用。有一个完整的示例应用程序的 Visual Studio 解决方案,您可以下载:http://www.windowsinspired.com/how-to-add-a-debugging-console-to-a-windows-gui-application/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-06-23
      • 2019-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-11
      • 1970-01-01
      相关资源
      最近更新 更多