可选择在C ++中写入控制台的Windows应用程序?

时间:2014-12-25 23:03:27

标签: c++ windows console crt

我想要一个具有以下行为的Windows应用程序:
1.如果它是从现有的命令行窗口(cmd.exe)启动,则将其stdout写入该控制台 2.如果通过双击其图标启动它,它不会打开新的控制台,也不会在任何地方写入它。

要实现1,我可以将/SUBSYSTEM链接器参数设置为CONSOLE但是如果我双击应用程序图标,则会打开一个新的控制台窗口。
要实现2,我将相同的参数设置为WINDOWS,但是如果我从控制台启动应用程序,则其stdout不会定向到控制台。
我希望同一个可执行文件同时具有这两种行为。

到目前为止,我发现我可以创建一个/SUBSYSTEM:WINDOWS可执行文件并执行此操作:

DWORD ret = AttachConsole(ATTACH_PARENT_PROCESS)
if (ret != 0) {  // succeeds only if the parent is cmd.exe
     HANDLE outh = GetStdHandle(STD_OUTPUT_HANDLE);
     WriteFile(outh, "Hello", 5, NULL, NULL);
}

如果进程从一个进程启动,则将Hello写入控制台,否则不执行任何操作 现在只有让CRT将outh作为stdout的HANDLE的问题。我怎么能这样做?

此选项的另一个问题是cmd.exe在启动的进程上没有阻塞。启动新进程后,cmd.exe将返回到提示符,并在提示符处出现Hello字符串。如果用户在控制台上按Enter,则会出现另一个提示。关于如何防止这种情况的任何想法?

1 个答案:

答案 0 :(得分:1)

在这里找到答案:http://dslweb.nwnexus.com/~ast/dload/guicon.htm

DWORD ret = AttachConsole(-1);
if (ret != 0) {
   HANDLE lStdHandle = GetStdHandle(STD_OUTPUT_HANDLE);
   int hConHandle = _open_osfhandle((intptr_t)lStdHandle, 0);
   FILE* fp = _fdopen( hConHandle, "w" );
   *stdout = *fp;
}

至于使cmd.exe等待,这似乎不可能: http://blogs.msdn.com/b/oldnewthing/archive/2009/01/01/9259142.aspx