某些場景 (配置生效、插件更新、語言切換、崩潰恢復) 需要程式「自我重啟」。核心邏輯:設置重啟標誌 → 發送關閉訊息 → OnClose 中判斷標誌 → CreateProcess 啟動自身新實例 → 退出當前進程。
// 全域或 CWinApp 成員
BOOL g_bRestartRequested = FALSE;
void CMyDlg::OnBtnRestart() {
g_bRestartRequested = TRUE;
PostMessage(WM_CLOSE); // 非同步關閉,讓訊息隊列處理完畢
}
void CMyDlg::OnClose() {
if (g_bRestartRequested) {
// 1. 獲取自身完整路徑
TCHAR szPath[MAX_PATH];
GetModuleFileName(NULL, szPath, MAX_PATH); // 含 .exe
// 2. 啟動資訊
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi = {0};
// 3. 創建新進程 (同參數、同目錄、正常優先級)
BOOL ok = CreateProcess(
szPath, // lpApplicationName
NULL, // lpCommandLine (繼承原參數需自行傳遞)
NULL, NULL, // Process/Thread Security
FALSE, // bInheritHandles
NORMAL_PRIORITY_CLASS,
NULL, // Environment (繼承)
NULL, // Current Directory (繼承)
&si, &pi
);
if (ok) {
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
g_bRestartRequested = FALSE; // 重置
}
CDialog::OnClose(); // 基類處理銷毀
}
CreateProcess 第二參數 lpCommandLine 若為 NULL,新進程無參數。需保留原 __argv/GetCommandLine() 並傳遞:CreateProcess(szPath, GetCommandLine(), ...)。OnClose 釋放 Mutex 後再 CreateProcess。CreateProcess 繼承提權;若需提權重啟,需 SHELLEXECUTEINFO + lpVerb = "runas"。SaveConfig()、FlushLog() 等。CreateProcess。Windows Restart Manager API (RmStartSession, RmRegisterResources, RmShutdown, RmRestart) 提供系統級重啟支援 (含檔案鎖釋放、服務重啟),適用於安裝程式/自動更新器,但 API 較複雜。簡單自我重啟用 CreateProcess 即夠。
此模式簡潔可靠,廣泛用於桌面應用的「立即生效」重啟需求。