在軟體開發中,實現程式的自動更新功能一直是個熱門話題。雖然網路上有許多關於版本比較的討論,但核心難點在於如何妥善處理「檔案自我銷毀與替換」的問題。傳統做法通常需要準備兩個執行檔互相更新(A 更新 B,B 更新 A),流程繁瑣且不夠優雅。
本文分享一種更簡潔的實作方式:利用 C++ 動態生成批次檔(.bat)來完成自我更新。具體流程如下:
GetModuleFileName 取得自身完整路徑CFileVersion 類別比較本地版本與伺服器共享資料夾中的最新版本update.bat,內容包含刪除舊檔、複製新檔、重新啟動程式三個步驟ShellExecute 隱藏執行批次檔,主程式隨即退出#include "FileVersion.h"
char sPath[255];
DWORD dwSize = 255;
GetModuleFileName(NULL, sPath, dwSize); // 取得當前執行檔完整路徑
CFileVersion fv;
fv.Open((LPTSTR)sPath);
CString szcurfileVer = fv.GetFileVersion();
CString szcurprdctVer = fv.GetProductVersion();
fv.Close();
CString szServerFile = _T("\\\\主機名\\共享路徑\\exe檔案"); // 更新來源路徑
if (fv.Open(szServerFile)) {
CString szsrcfileVer = fv.GetFileVersion();
CString szsrcprdctVer = fv.GetProductVersion();
fv.Close();
// 版本不一致時觸發更新
if (szcurfileVer != szsrcfileVer || szcurprdctVer != szsrcprdctVer) {
CStdioFile f(_T("C:\\update.bat"), CFile::modeCreate | CFile::modeWrite);
f.WriteString(_T("del "));
f.WriteString(sPath);
f.WriteString(_T("\n")); // 刪除舊檔
f.WriteString(_T("copy ") + szServerFile + _T(" "));
f.WriteString(sPath);
f.WriteString(_T("\n")); // 複製新檔
f.WriteString(sPath);
f.WriteString(_T("\n")); // 重新啟動更新後的程式
f.Close();
ShellExecute(NULL, NULL, _T("C:\\update.bat"), NULL, NULL, SW_HIDE);
exit(0); // 退出主程式,讓批次檔接手後續工作
}
} else {
AfxMessageBox(_T("獲取更新檔案失敗,請確認網路連線!"));
}
優點:無需額外的更新程式,單一執行檔即可完成自我更新;邏輯直觀,易於維護。
注意事項:
\\\\)copy 指令這個技巧適用於 MFC 應用程式,特別適合內部部署環境,透過共享資料夾即可實現輕量級的自動更新機制。