我正在尝试编写一个 C++ 程序,可以通过双击可执行文件来启动该程序,例如explorer,或者可以从命令行调用,例如 powershell 或 cmd。
我希望应用程序在从 GUI 环境(单击资源管理器、桌面快捷方式等)调用时不要打开控制台。我确实希望它在从命令行调用时输出到控制台,以便为更有技术倾向的人提供有用的信息。我对 C++ 的 GUI 东西还很陌生,所以请温柔点。
详情:
我在网上寻找过类似的问题,但尚未找到。
我有一个实现此目的的工作示例,它在 cmd 中的行为与预期一致,但是当在 Powershell 中运行它时,Powershell 将在程序完成后覆盖输出,就好像程序从未将行打印到控制台一样。 (参见图片示例)。有趣的是,当我到达终端底部时,Powershell 确实按预期工作。由于这个问题的性质,我将包含图片,因为我没有看到一个好的替代方案来展示我的问题。此代码不会启动 GUI,但我的最终代码会启动 GUI,并且出现相同的问题。
无关:看来 stdin 在连接时仍会连接到 powershell。
Cmake 配置
cmake_minimum_required(VERSION 3.27)
project(consoletest)
set(CMAKE_CXX_STANDARD 23)
add_executable(consoletest main.cpp)
target_link_options(consoletest PRIVATE -mwindows)
代码
#include <iostream>
#define _WIN32_WINNT 0x0501
#include <windows.h>
int main() {
// Attach output to console if called from console.
AttachConsole(-1);
freopen("CONIN$", "r", stdin);
freopen("CONOUT$", "w", stdout);
freopen("CONOUT$", "w", stderr);
std::cout << "\nHello, World!" << std::endl;
std::cout << "Hello, World!" << std::endl;
std::cout << "Hello, World!" << std::endl;
std::cout << "Hello, World!" << std::endl;
std::cout << "Hello, World!" << std::endl;
std::cout << "Hello, World!" << std::endl;
std::cout << "Hello, World!" << std::endl;
// Send enter key hack for console mode to return to parent console
INPUT ip;
ip.type = INPUT_KEYBOARD;
ip.ki.time = 0;
ip.ki.dwFlags = KEYEVENTF_UNICODE;
ip.ki.wScan = VK_RETURN;
ip.ki.wVk = 0;
ip.ki.dwExtraInfo = 0;
SendInput(1, &ip, sizeof(INPUT));
return 0;
}
图片:
与
cmd.exe
不同,PowerShell 始终 在 Windows 上异步启动 Windows GUI 子系统应用程序,这会导致您看到的症状。
为了防止应用程序显式附加到调用者控制台,请通过管道连接到
Write-Output
,这会导致 PowerShell 切换到 同步 执行:
.\consoletestexe | Write-Output