C++检测子进程并重启对应exe程序出现编译报错如何解决
C++ 进程检测重启程序编译问题排查与修复方案
报错原因及对应修复方案
1. 警告 C4244:= 赋值时 int 转 float 可能丢失数据
- 原因:代码中
last_hwnd_time定义为float类型,但赋值的timeinfo->tm_sec是int类型,存在隐式类型转换风险,且该变量仅用于存储秒级时间戳,完全不需要浮点类型。 - 修复:将
static float last_hwnd_time = 0.f;修改为static int last_hwnd_time = 0;即可。
2. 错误 C4996:localtime 函数不安全
- 原因:MSVC默认禁用了传统的非线程安全时间函数,要求使用安全增强版本
localtime_s,或者通过宏关闭安全警告。 - 修复方案(推荐使用安全函数,避免宏关闭警告带来的潜在风险):
- 将原代码中
struct tm* timeinfo;修改为struct tm timeinfo; - 将
timeinfo = localtime(&rawtime);修改为localtime_s(&timeinfo, &rawtime); - 将代码中所有
timeinfo->的指针调用语法,替换为结构体实例调用语法timeinfo. - 额外注意:原代码仅在循环外获取了一次时间,死循环中时间不会更新,需要将
time(&rawtime);和localtime_s两行代码移动到for死循环内部,每次循环更新当前时间。
- 将原代码中
3. 警告 C4244:参数从wchar_t转const _Elem可能丢失数据
- 原因:代码中将
std::wstring类型的sane_title直接迭代构造为std::string,宽字符(2字节)强制转窄字符(1字节)会丢失高位数据,且构造的Title、Song两个变量后续完全没有被使用,属于冗余代码。 - 修复:直接删除以下三行无用代码即可:
std::string Title = " "; std::string Song(sane_title.begin(), sane_title.end()); Title += Song;
其他隐藏问题修复
sane_filename.find的返回值判断错误:sane_filename是std::wstring类型,应该匹配std::wstring::npos,而非std::string::npos,否则会出现类型不匹配的潜在BUG。OpenProcess返回值未做非空判断,若打开进程失败,后续调用K32GetModuleFileNameExW会触发异常,需要增加空判断逻辑。- 死循环无休眠会导致CPU占用过高,可适当增加
Sleep调用降低资源消耗。
修复后完整代码
#include <iostream> #include <windows.h> #include <cstdlib> #include <fstream> #include <Psapi.h> int main() { for (; ;) { time_t rawtime; struct tm timeinfo; time(&rawtime); localtime_s(&timeinfo, &rawtime); static HWND Program_hwnd = nullptr; static int last_hwnd_time = 0; int text_width = 0; if ((!Program_hwnd || Program_hwnd == INVALID_HANDLE_VALUE) && last_hwnd_time < timeinfo.tm_sec) { for (HWND hwnd = GetTopWindow(0); hwnd; hwnd = GetWindow(hwnd, GW_HWNDNEXT)) { last_hwnd_time = timeinfo.tm_sec ; if (!(IsWindowVisible)(hwnd)) continue; int length = (GetWindowTextLengthW)(hwnd); if (length == 0) continue; WCHAR filename[300]; DWORD pid; (GetWindowThreadProcessId)(hwnd, &pid); const auto Program_handle = (OpenProcess)(PROCESS_QUERY_INFORMATION, FALSE, pid); if (Program_handle == nullptr) { continue; } (K32GetModuleFileNameExW)(Program_handle, nullptr, filename, 300); std::wstring sane_filename{ filename }; (CloseHandle)(Program_handle); if (sane_filename.find(L"Program.exe") != std::wstring::npos) Program_hwnd = hwnd; } } else if (Program_hwnd && Program_hwnd != INVALID_HANDLE_VALUE) { WCHAR title[300]; if (!(GetWindowTextW)(Program_hwnd, title, 300)) { Program_hwnd = nullptr; } else { std::wstring sane_title{ title }; if (sane_title.find(L"EX") != std::wstring::npos) { system("taskkill /IM Program.exe /F"); system("start C:\\Program.exe"); } } } Sleep(1000); } }
内容的提问来源于stack exchange,提问作者Soup Man
相关产品推荐
相关产品推荐

