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