如何防止 Powershell 覆盖使用 AttachConsole() 的 C++ 程序完成后的输出

问题描述 投票:0回答:1

我正在尝试编写一个 C++ 程序,可以通过双击可执行文件来启动该程序,例如explorer,或者可以从命令行调用,例如 powershell 或 cmd。

我希望应用程序在从 GUI 环境(单击资源管理器、桌面快捷方式等)调用时不要打开控制台。我确实希望它在从命令行调用时输出到控制台,以便为更有技术倾向的人提供有用的信息。我对 C++ 的 GUI 东西还很陌生,所以请温柔点。

详情:

  • c++ 23
  • 使用cmake和mingw构建,
  • 使用 Clion 进行编码。
  • 使用 Windows 11。

我在网上寻找过类似的问题,但尚未找到。

我有一个实现此目的的工作示例,它在 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;
}

图片:

Powershell when there is space left below

Powershell with no space left

CMD works as expected

c++ windows powershell user-interface console
1个回答
0
投票

cmd.exe
不同,PowerShell 始终 在 Windows 上异步启动 Windows GUI 子系统应用程序,这会导致您看到的症状。

为了防止应用程序显式附加到调用者控制台,请通过管道连接到

Write-Output
,这会导致 PowerShell 切换到 同步 执行:

.\consoletestexe | Write-Output
© www.soinside.com 2019 - 2024. All rights reserved.