應用程式有時需要自我重啟(如更新完成、設定變更需重載、異常恢復)。在 C++ Builder 中,利用 Windows API CreateProcess 啟動自身新執行個體,然後結束目前程序,即可實現乾淨的重啟。本文提供最小化、可直接套用的實作碼。
WinMain)結束前,檢查全域旗標 g_bIsRunAgainCreateProcess 啟動同一執行檔(Application->ExeName)#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {
try {
Application->Initialize();
Application->CreateForm(__classid(TfrmMain), &frmMain);
Application->Run();
}
catch (Exception &exception) {
Application->ShowException(&exception);
}
catch (...) {
try { throw Exception(""); }
catch (Exception &exception) {
Application->ShowException(&exception);
}
}
// === 自我重啟邏輯 ===
if (g_bIsRunAgain) {
AnsiString exePath = Application->ExeName;
STARTUPINFO si = {0};
PROCESS_INFORMATION pi = {0};
si.cb = sizeof(STARTUPINFO);
if (!::CreateProcess(
exePath.c_str(), // 應用程式名稱
NULL, // 命令列參數
NULL, NULL, // 程序/執行緒安全屬性
FALSE, // 不繼承控制代碼
NORMAL_PRIORITY_CLASS,
NULL, NULL, // 環境區塊/當前目錄
&si, &pi)) // 啟動資訊/程序資訊
{
return 0; // 啟動失敗
}
// 可選:CloseHandle(pi.hProcess); CloseHandle(pi.hThread);
}
return 0;
}
// 全域旗標宣告
extern bool g_bIsRunAgain;
class TfrmMain : public TForm {
// ...
void __fastcall btnCloseClick(TObject *Sender);
void __fastcall btnReExecuteClick(TObject *Sender);
};
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TfrmMain *frmMain;
// 全域旗標定義
bool g_bIsRunAgain = false;
//---------------------------------------------------------------------------
void __fastcall TfrmMain::btnCloseClick(TObject *Sender) {
Close(); // 正常關閉
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::btnReExecuteClick(TObject *Sender) {
g_bIsRunAgain = true; // 設定重啟旗標
Close(); // 觸發關閉流程,WinMain 會檢查旗標並重啟
}
g_bIsRunAgain 需在 WinMain 可見範圍,故置於 Unit1.cpp 並 extern 供標頭檔引用lpApplicationName:用 Application->ExeName 取得完整執行檔路徑lpCommandLine:NULL 表示使用預設命令列(同原啟動參數)bInheritHandles:FALSE 避免控制代碼洩漏dwCreationFlags:NORMAL_PRIORITY_CLASS 一般優先權CreateProcess 失敗時直接返回,不重啟PROCESS_INFORMATION 中的控制代碼若不需等待新程序,應呼叫 CloseHandle 釋放若需重啟時傳遞參數(如 /restarted 標記):
AnsiString cmdLine = exePath + " /restarted";
if (!::CreateProcess(
NULL, // 模組名稱設 NULL
cmdLine.c_str(), // 完整命令列
NULL, NULL, FALSE,
NORMAL_PRIORITY_CLASS,
NULL, NULL, &si, &pi)) { ... }
新程序啟動時可解析 ParamStr(1) 判斷是否為重啟啟動。