首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

軟體看門狗機制:防止程式無響應、自動重啟與進程監控實戰

     編輯:關於C++

概述

關鍵業務程式必須長期穩定運行,但死鎖、無響應等問題難以完全避免。當修復 Bug 時間緊迫且問題難以重現時,「軟體看門狗」可作為臨時保護機制。其核心需求包括:隱藏運行介面、定時檢測目標進程存活、判斷程式無響應並強制終止、超過閾值自動重啟系統。

核心技術預備知識

1. 判斷程式「無響應」的關鍵 API

Windows 提供兩個未文檔化函數(位於 User32.dll):

  • Win2K/NT:IsHungAppWindow(HWND) - 以視窗句柄為參數
  • Win9x:IsHungThread(DWORD threadId) - 以執行緒 ID 為參數

需動態載入:

if (m_hUser32 == NULL)
    m_hUser32 = GetModuleHandle("USER32.DLL");

if (m_hUser32) {
    m_IsHungNT = (HUNG_FUNNT)GetProcAddress(m_hUser32, "IsHungAppWindow");
    m_IsHung9X = (HUNG_FUN9X)GetProcAddress(m_hUser32, "IsHungThread");
}

2. 隱藏主視窗(任務列不顯示)

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) {
    if (!CFrameWnd::PreCreateWindow(cs)) return FALSE;
    cs.dwExStyle |= WS_EX_TOOLWINDOW; // 不在任務列顯示
    cs.style = WS_POPUP;              // 隱藏主視窗
    return TRUE;
}

3. 確保單一實例運行(互斥體)

bool CWatchDogApp::IsUniqueCopyInProc() {
    m_Mutex = CreateMutex(NULL, TRUE, "System Watch Dog");
    return GetLastError() != ERROR_ALREADY_EXISTS;
}

// InitInstance 中調用
if (!IsUniqueCopyInProc()) return FALSE;

4. 判斷作業系統版本

bool CWatchDogApp::IsWinNT() {
    OSVERSIONINFO osvi = { sizeof(OSVERSIONINFO) };
    GetVersionEx(&osvi);
    return osvi.dwPlatformId == VER_PLATFORM_WIN32_NT;
}

5. 系統重啟實現(權限提升)

if (IsWinNT()) {
    HANDLE hToken; TOKEN_PRIVILEGES tp; LUID luid;
    OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
    LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &luid);
    tp.PrivilegeCount = 1;
    tp.Privileges[0].Luid = luid;
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);
    return ExitWindowsEx(EWX_REBOOT | EWX_FORCE, 0);
}
return ExitWindowsEx(EWX_REBOOT | EWX_FORCE, 0);

6. 進程啟動與終止

// 啟動進程
CreateProcess(path, NULL, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi);

// 終止進程(謹慎使用,不會觸發 DLL 卸載通知)
TerminateProcess(hProcess, 0);

7. Win2K/NT 自動登入與自啟動設定

修改註冊表 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon:

  • AutoAdminLogon = "1"、DefaultUserName、DefaultPassword 實現自動登入
  • Shell 值從 explorer.exe 改為自訂程式絕對路徑,實現登入後直接啟動

功能演示流程

啟動 WatchDog 後,會自動啟動模擬無響應的 HungDemo 程式。WatchDog 檢測到無響應即終止並重啟,重複 6 次後觸發系統自動重啟。測試前請保存工作資料。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved