Windows 系統的核心配置資訊分散儲存於 system.dat、user.dat(登錄檔)、win.ini 和 system.ini 等檔案中。對這些關鍵資料進行備份,能有效避免系統損壞時需重新安裝的繁瑣過程。雖然 Windows 內建備份功能,但操作不便。本文將詳細介紹如何自行開發一套系統救援程式,實現系統資訊的自動備份、還原與救援盤製作。
常用 WinExec()、ShellExecute()、CreateProcess() 三種方式啟動外部程式,但無法直接呼叫 DOS 內部命令或 sys.com 等特定外部命令。解決方案是先建立批次檔(.bat),再以隱藏模式呼叫該批次檔,從而在使用者無感知的情況下利用系統現有功能。
可呼叫 Windows 目錄下 command\scanreg.exe 配合 /backup 參數,將系統檔案壓縮為 CAB 檔案儲存於 windows\sysbckup\ 目錄,檔名自動命名為 rb000.cab、rb001.cab 等。若需更大彈性,亦可使用同目錄下的 extract.exe 手動建立 CAB 檔。注意:為確保通用性,Windows 目錄路徑應透過 GetWindowsDirectory() 動態取得,而非硬式編碼。
登錄檔還原必須在純 DOS 環境下進行,因此程式需觸發系統重啟(ExitWindowsEx()),並在進入 Windows 前完成還原。透過修改 autoexec.bat 實現:若備份用 scanreg /backup,還原時在 autoexec.bat 加入 scanreg /restore;若用 extract 備份,則加入類似 extract /Y /L C:\windows myBackedFile.cab *.* 的指令。純 DOS 環境通常不支援長檔名,寫入 autoexec.bat 前需以 GetShortPathName() 轉換為短路徑。
救援盤需具備兩大功能:啟動系統與儲存備份檔。可使用 sys.com(如 sys c: a:)將軟盤製作成啟動盤,並將備份檔案複製至軟盤,以便在無法進入 Windows 時由軟盤啟動並執行還原。
// 取得 Windows 目錄
CString m_strWinDir(' ', _MAX_DIR);
GetWindowsDirectory(m_strWinDir.GetBuffer(0), _MAX_DIR);
m_strWinDir.ReleaseBuffer();
// 取得程式所在目錄
CString CRescueSysDlg::getMyDir() {
TCHAR sFilename[_MAX_PATH], sDrive[_MAX_DRIVE], sDir[_MAX_DIR];
TCHAR sFname[_MAX_FNAME], sExt[_MAX_EXT];
GetModuleFileName(AfxGetInstanceHandle(), sFilename, _MAX_PATH);
_tsplitpath(sFilename, sDrive, sDir, sFname, sExt);
CString homeDir = CString(sDrive) + CString(sDir);
if (homeDir.Right(1) != _T("\\")) homeDir += _T("\\");
return homeDir;
}
// 長路徑轉短路徑
CString CRescueSysDlg::toShortPath(CString m_inDir) {
char strBuffer[_MAX_PATH];
GetShortPathName(m_inDir, strBuffer, _MAX_PATH);
return CString(strBuffer);
}
「開始備份」按鈕響應函數:讀取歷史備份記錄,提示使用者輸入備份名稱,建立批次檔呼叫 scanreg.exe /backup,監控備份進度並更新進度條,備份完成後將產生的 rb000.cab 重新命名並移動至程式目錄保存。
「開始還原」按鈕:讓使用者選擇要還原的備份檔,修改 autoexec.bat 寫入還原指令,備份原 autoexec.bat,重啟系統進入 DOS 執行還原。
「建立救援盤」按鈕:格式化軟盤、寫入系統啟動檔、複製備份檔案與還原腳本至軟盤,製作完成後可在系統損壞時由軟盤啟動自動還原。