#include #include #include #include #include #include // for strstr #include #include #include #include #include #include #include #include #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; DWORD i; // Get the device information set for all present devices. hDevInfo = SetupDiGetClassDevs(&GUID_DEVCLASS_PORTS, NULL, NULL, DIGCF_PRESENT); if (hDevInfo == INVALID_HANDLE_VALUE) { printf("SetupDiGetClassDevs 失败: %ld\n", GetLastError()); return; } // Enumerate through all devices in the set. DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); i++) { DWORD DataT; char buffer[4096]; DWORD buffersize = sizeof(buffer); // Get the friendly name of the device. if (SetupDiGetDeviceRegistryPropertyA(hDevInfo, &DeviceInfoData, SPDRP_FRIENDLYNAME, &DataT, (PBYTE)buffer, buffersize, &buffersize)) { if (strstr(buffer, portName) != NULL) { printf("Found COM port: %s\n", buffer); // Disable the device. DEVINST devInst = DeviceInfoData.DevInst; CONFIGRET status = CM_Disable_DevNode(devInst, 0); if (status != CR_SUCCESS) { printf("CM_Disable_DevNode failed: %d\n", status); } else { printf("Device disabled successfully.\n"); } break; } } } if (GetLastError() != NO_ERROR && GetLastError() != ERROR_NO_MORE_ITEMS) { printf("SetupDiEnumDeviceInfo failed: %ld\n", GetLastError()); } // Cleanup SetupDiDestroyDeviceInfoList(hDevInfo); } static void EnableComPort(const char* portName) { HDEVINFO hDevInfo; SP_DEVINFO_DATA DeviceInfoData; DWORD i; // Get the device information set for all present devices. hDevInfo = SetupDiGetClassDevs(&GUID_DEVCLASS_PORTS, NULL, NULL, DIGCF_PRESENT); if (hDevInfo == INVALID_HANDLE_VALUE) { printf("SetupDiGetClassDevs 失败: %ld\n", GetLastError()); return; } // Enumerate through all devices in the set. DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); i++) { DWORD DataT; char buffer[4096]; DWORD buffersize = sizeof(buffer); // Get the friendly name of the device. if (SetupDiGetDeviceRegistryPropertyA(hDevInfo, &DeviceInfoData, SPDRP_FRIENDLYNAME, &DataT, (PBYTE)buffer, buffersize, &buffersize)) { if (strstr(buffer, portName) != NULL) { printf("Found COM port: %s\n", buffer); // Disable the device. DEVINST devInst = DeviceInfoData.DevInst; CONFIGRET status = CM_Enable_DevNode(devInst, 0); if (status != CR_SUCCESS) { printf("CM_Enable_DevNode failed: %d\n", status); } else { printf("Device Enable successfully.\n"); } break; } } } if (GetLastError() != NO_ERROR && GetLastError() != ERROR_NO_MORE_ITEMS) { printf("SetupDiEnumDeviceInfo failed: %ld\n", GetLastError()); } // Cleanup SetupDiDestroyDeviceInfoList(hDevInfo); } static bool isRunAsAdmin() { BOOL fIsRunAsAdmin = FALSE; PSID pAdministratorsGroup = NULL; // Allocate and initialize a SID of the administrators group. SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY; if (!AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pAdministratorsGroup)) { return false; } // Determine whether the SID of administrators group is enabled in the primary access token of the process. if (!CheckTokenMembership(NULL, pAdministratorsGroup, &fIsRunAsAdmin)) { fIsRunAsAdmin = FALSE; } // Free the allocated SID. if (pAdministratorsGroup) { FreeSid(pAdministratorsGroup); } return fIsRunAsAdmin; } static void restartAsAdmin() { TCHAR szPath[MAX_PATH]; if (GetModuleFileName(NULL, szPath, ARRAYSIZE(szPath))) { SHELLEXECUTEINFO sei = { sizeof(sei) }; sei.lpVerb = TEXT("runas"); sei.lpFile = szPath; sei.hwnd = NULL; sei.nShow = SW_NORMAL; if (!ShellExecuteEx(&sei)) { DWORD dwError = GetLastError(); if (dwError == ERROR_CANCELLED) { //std::cout << "The user refused to allow privileges elevation.\n"; } } } } // 解析 .lnk 文件,获取目标路径 static QString getShortcutTarget(const QString& shortcutPath) { HRESULT hres; CoInitialize(NULL); IShellLink* psl; QString targetPath; hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl); if (SUCCEEDED(hres)) { IPersistFile* ppf; hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf); if (SUCCEEDED(hres)) { WCHAR wsz[MAX_PATH]; shortcutPath.toWCharArray(wsz); wsz[shortcutPath.length()] = 0; hres = ppf->Load(wsz, STGM_READ); if (SUCCEEDED(hres)) { char szTarget[MAX_PATH]; WIN32_FIND_DATA wfd; if (SUCCEEDED(psl->GetPath(szTarget, MAX_PATH, &wfd, SLGP_UNCPRIORITY))) { targetPath = QString::fromLocal8Bit(szTarget); } } ppf->Release(); } psl->Release(); } CoUninitialize(); return targetPath; } // 获取目标文件图标 static QIcon getFileIcon(const QString& filePath, const QSize& size) { QFileIconProvider iconProvider; QFileInfo fileInfo(filePath); QIcon icon = iconProvider.icon(fileInfo); QPixmap pixmap = icon.pixmap(size); return QIcon(pixmap); } static bool restartProgram(bool asAdmin = false, bool exitCurrent = true, int delayMs = 0) { wchar_t exePath[MAX_PATH]; if (GetModuleFileNameW(nullptr, exePath, MAX_PATH) == 0) { return false; } int argc = 0; LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc); std::wstring params; if (argv && argc > 1) { for (int i = 1; i < argc; ++i) { const wchar_t* arg = argv[i]; bool needQuote = wcspbrk(arg, L" \t\"'") != nullptr; if (i > 1) params.push_back(L' '); if (needQuote) { params.push_back(L'"'); for (const wchar_t* p = arg; *p; ++p) { if (*p == L'"') params.push_back(L'\\'), params.push_back(L'"'); else params.push_back(*p); } params.push_back(L'"'); } else { params.append(arg); } } } if (argv) LocalFree(argv); if (delayMs <= 0) { SHELLEXECUTEINFOW sei{}; sei.cbSize = sizeof(sei); sei.lpVerb = asAdmin ? L"runas" : L"open"; sei.lpFile = exePath; sei.lpParameters = params.empty() ? nullptr : params.c_str(); sei.nShow = SW_SHOWNORMAL; if (!ShellExecuteExW(&sei)) return false; if (exitCurrent) ExitProcess(0); return true; } else { std::wstring exeEsc; for (const wchar_t* p = exePath; *p; ++p) { if (*p == L'\'') exeEsc.push_back(L'\''); // duplicate single quote for PS literal exeEsc.push_back(*p); } std::wstring argsEsc; if (!params.empty()) { for (const wchar_t* p = params.c_str(); *p; ++p) { if (*p == L'\'') argsEsc.push_back(L'\''); argsEsc.push_back(*p); } } std::wstring psParam = L"-NoProfile -WindowStyle Hidden -Command \"Wait-Process -Id "; psParam += std::to_wstring(GetCurrentProcessId()); psParam += L"; Start-Sleep -Milliseconds "; psParam += std::to_wstring(delayMs); psParam += L"; Start-Process -FilePath '"; psParam += exeEsc; psParam += L"'"; if (!argsEsc.empty()) { psParam += L" -ArgumentList '"; psParam += argsEsc; psParam += L"'"; } psParam += L"\""; SHELLEXECUTEINFOW sei{}; sei.cbSize = sizeof(sei); sei.lpVerb = asAdmin ? L"runas" : L"open"; sei.lpFile = L"powershell.exe"; sei.lpParameters = psParam.c_str(); sei.nShow = SW_HIDE; if (!ShellExecuteExW(&sei)) return false; if (exitCurrent) ExitProcess(0); return true; } } struct memUsage { DWORDLONG totalPhys;//总物理内存大小 DWORDLONG availPhys;//可用物理内存大小 DWORDLONG usedPhys;//已使用物理内存大小 DWORDLONG totalVir;//总虚拟内存大小 DWORDLONG availVir;//可用虚拟内存大小 DWORDLONG usedVir;//已使用虚拟内存大小 DWORDLONG totalMem;//总物理+虚拟内存大小 DWORDLONG availMem;//可用物理+虚拟内存大小 DWORDLONG usedMem;//已使用物理+虚拟内存大小 double usedPhysPercent;//已使用物理内存大小的百分比 double usedMemPercent;//已使用物理+虚拟内存大小的百分比 }; static memUsage getMemUsage() { memUsage result; MEMORYSTATUSEX memInfo; memInfo.dwLength = sizeof(memInfo); if (GlobalMemoryStatusEx(&memInfo)) { result.totalPhys = memInfo.ullTotalPhys; result.availPhys = memInfo.ullAvailPhys; result.usedPhys = result.totalPhys - result.availPhys; result.totalVir = memInfo.ullTotalPageFile - memInfo.ullTotalPhys; result.availVir = memInfo.ullAvailPageFile - memInfo.ullAvailPhys; result.usedPhys = result.totalVir - result.availVir; result.totalMem = memInfo.ullTotalPageFile; result.availMem = memInfo.ullAvailPageFile; result.usedMem = result.totalMem - result.availMem; result.usedPhysPercent = (double)result.usedPhys / (double)result.totalPhys; result.usedMemPercent = (double)result.usedMem / (double)result.totalMem; } return result; } #pragma once