TauAutoUpgrader 組件在以前的 Delphi7 下用得好好的,現在估計大多數 Delphi 開發者都轉到 XE 版了吧?我在網上能找到的TauAutoUpgrader 組件最新版本是 Version 5.0.2 的,儘管在 Delphi XE 10.3 下也能編譯安裝,但更新測試的最終結果卻是——
通過網絡檢測和下載文件的步驟都能正確執行,但下載完成後卻無法替換掉主程序。
觀察主程序文件夾,發現下載的文件被命名爲 “主程序名.EXE.uTMP”,大小亦正確,但文件屬性被設爲隱藏。多方嘗試各種設置均無法解決(估計跟Windows10的權限需求有關?)只好想辦法手動完成剩餘步驟,即:
1、手動刪除主程序EXE文件(因自身正在運行,無法用常規方法刪除);
2、將下載文件改名爲原主程序名。
參考網上達人的文件操作方法,摸索出如下過程——
{-------------------------------------------------------------------------------
過程名: TfrmMain.replaceApp
說明: 手動替換主程序(解決升級未徹底完成的問題)
作者: Yunbing.com
日期: 2019.12.19
參數: 無
返回值: 無
-------------------------------------------------------------------------------}
procedure TfrmMain.replaceApp;
var
BatchFile: TextFile;
BatchFileName, AppFile, DownFile: string;
ProcessInfo: TProcessInformation;
StartUpInfo: TStartupInfo;
begin
//主程序和已下載文件名
AppFile := Paramstr(0);
DownFile := AppFile + '.uTMP';
if not FileExists(DownFile) then
Exit;
//生成批處理文件
BatchFileName := ChangeFileExt(Paramstr(0),'.bat');
AssignFile(BatchFile, BatchFileName);
Rewrite(BatchFile);
//刪除主程序文件的命令
Writeln(BatchFile, ':try');
Writeln(BatchFile, Format('del "%s"', [ParamStr(0)]));
//循環刪除,直至成功
Writeln(BatchFile, Format('if exist "%s" goto try', [ParamStr(0)]));
//將已下載的文件隱藏屬性去除,並改名爲主程序文件
Writeln(BatchFile, Format('attrib -h "%s"', [DownFile]));
Writeln(BatchFile, Format('rename "%s" "%s"', [DownFile, ExtractFileName(AppFile)]));
//啓動替換後的程序
Writeln(BatchFile, Format('start %s', [AppFile]));
//執行完成後,刪除臨時生成的批處理文件自身
Writeln(BatchFile, 'del %0');
CloseFile(BatchFile);
FillChar(StartUpInfo, SizeOf(StartUpInfo), $00);
StartUpInfo.dwFlags := STARTF_USESHOWWINDOW;
StartUpInfo.wShowWindow := SW_HIDE;
//創建隱藏的進程
if CreateProcess(nil,PChar
(BatchFileName),nil,nil,False,IDLE_PRIORITY_CLASS,nil,nil,StartUpInfo,ProcessInfo) then
begin
CloseHandle(ProcessInfo.hThread);
CloseHandle(ProcessInfo.hProcess);
end;
end;
刪除和更名過程其實都是通過新開的線程執行一個臨時生成的批處理文件來實現的。
將以上過程放在 auAutoUpgrader 組件的 EndUpgrade 事件下執行即可。如——
procedure TfrmMain.auAutoUpgrader1EndUpgrade(Sender: TObject;
var RestartImediately: Boolean);
begin
replaceApp;
RestartImediately := True;
end;
不過此法感覺有點美中不足:不知爲何,下載的這個主程序文件其日期時間信息竟然丟失,右擊查看屬性顯示創建和修改日期爲1601年4月12日,未知是否因自己的系統原因造成,沒有進一步測試查驗,反正我強迫症不是很嚴重。^_^
另外,此法儘管暫時解決了問題,始終“難登大雅之堂”。若有朋友知道異常原因或更好的解決之道,還望指教哈!
參考文章——
http://www.360doc.com/content/14/0730/13/9200790_398113114.shtml