This commit is contained in:
2025-10-28 17:29:39 +08:00
parent 4fe5cff926
commit 2a66d1d1f2
12 changed files with 113 additions and 36 deletions
+77
View File
@@ -12,6 +12,83 @@
#include <QFileInfo>
#pragma comment(lib, "setupapi.lib")
// 禁用控制台选择(快速编辑与鼠标输入)
static bool disableConsoleSelection() {
HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
if (hStdin == INVALID_HANDLE_VALUE || hStdin == NULL) return false;
DWORD mode = 0;
if (!GetConsoleMode(hStdin, &mode)) return false;
// 必须先设置 ENABLE_EXTENDED_FLAGS,再清除 ENABLE_QUICK_EDIT_MODE
DWORD newMode = mode | ENABLE_EXTENDED_FLAGS;
newMode &= ~(ENABLE_QUICK_EDIT_MODE | ENABLE_MOUSE_INPUT);
if (newMode == mode) return true; // 已经是期望模式
return SetConsoleMode(hStdin, newMode) != 0;
}
// 恢复控制台选择(快速编辑与鼠标输入)
static bool enableConsoleSelection() {
HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
if (hStdin == INVALID_HANDLE_VALUE || hStdin == NULL) return false;
DWORD mode = 0;
if (!GetConsoleMode(hStdin, &mode)) return false;
DWORD newMode = mode | ENABLE_EXTENDED_FLAGS | ENABLE_QUICK_EDIT_MODE | ENABLE_MOUSE_INPUT;
if (newMode == mode) return true;
return SetConsoleMode(hStdin, newMode) != 0;
}
// 是否运行在 Windows Terminal 主机(PowerShell/命令行在 Windows Terminal 中)
static bool isWindowsTerminalHost() {
// Windows Terminal 会设置 WT_SESSION 环境变量
return GetEnvironmentVariableW(L"WT_SESSION", nullptr, 0) > 0;
}
// 绑定 CRT 与标准句柄到当前控制台
static void bindCrtToConsoleIO() {
FILE* fp = nullptr;
freopen_s(&fp, "CONIN$", "r", stdin);
freopen_s(&fp, "CONOUT$", "w", stdout);
freopen_s(&fp, "CONOUT$", "w", stderr);
// 同步 C++ iostream 与 C stdio
std::ios::sync_with_stdio();
}
// 确保获得一个“不可选择”的控制台。
// 如果检测到 Windows Terminal/PowerShell 环境,则脱离父控制台并新建独立控制台,避免被宿主选择影响。
static bool ensureNoSelectionConsole(bool detachWhenWT = true) {
bool createdNew = false;
if (detachWhenWT && isWindowsTerminalHost()) {
FreeConsole(); // 脱离 PowerShell/WT 的控制台
if (AllocConsole()) {
bindCrtToConsoleIO();
createdNew = true;
}
} else if (GetConsoleWindow() == NULL) {
// GUI 子系统或当前无控制台时创建一个
if (AllocConsole()) {
bindCrtToConsoleIO();
createdNew = true;
}
} else {
// 已有控制台,仍然尝试绑定,避免句柄无效
bindCrtToConsoleIO();
}
// 禁用选择(对当前控制台生效)
bool ok = disableConsoleSelection();
// 保险:确保控制台窗口可见
if (HWND hWnd = GetConsoleWindow()) {
ShowWindow(hWnd, SW_SHOW);
}
return createdNew ? ok : ok;
}
static void DisableComPort(const char* portName) {
HDEVINFO hDevInfo;
SP_DEVINFO_DATA DeviceInfoData;