如何在Inno Setup的Pascal Script中添加文件提取前执行的Sleep延迟
适配需求的两种实现方案
你可以根据自己的使用场景选择以下任意一种方案,都可以解决服务删除未完成导致的文件删除权限报错问题。
方案1:安装包提取文件前触发延迟(通用性更强)
该方案的延迟触发时机刚好在旧版本卸载全流程(含[UninstallRun]所有命令执行)完成后、新版本安装文件提取写入前,完全匹配你的需求,无需修改旧版本的安装包配置。
直接在你的Inno Setup脚本中添加如下代码段即可:
[Code] function PrepareToInstall(var NeedsRestart: Boolean): String; begin // 固定等待15秒,确保系统完成服务删除及后台进程回收 Sleep(15 * 1000); Result := ''; end;
方案2:[UninstallRun]节点所有进程执行完后触发延迟
如果要把延迟逻辑内置在卸载流程中,你可以在[UninstallRun]节点的末尾添加一条系统静默等待命令,所有之前的卸载命令执行完成后才会触发该延迟:
[UninstallRun] ; 你原有卸载命令放在该位置,比如删除服务的命令 Filename: "service.exe"; Parameters: "remove"; Flags: waituntilterminated ; 末尾新增15秒静默延迟命令 Filename: "{cmd}"; Parameters: "/c timeout /t 15 /nobreak > nul"; Flags: runhidden waituntilterminated
优化建议:动态检测服务状态,避免无效等待
如果不想固定等待15秒,可以通过代码动态检测服务是否完全删除,最多等待30秒,服务删除完成就直接继续后续流程,比固定时长更高效:
[Code] function ServiceExists(const SvcName: string): Boolean; var SCMgr, SvcHandle: DWORD; begin Result := False; SCMgr := OpenSCManager('', '', GENERIC_READ); if SCMgr = 0 then Exit; SvcHandle := OpenService(SCMgr, PChar(SvcName), GENERIC_READ); if SvcHandle <> 0 then begin Result := True; CloseServiceHandle(SvcHandle); end; CloseServiceHandle(SCMgr); end; function PrepareToInstall(var NeedsRestart: Boolean): String; var WaitTime: Integer; begin WaitTime := 0; // 替换为你实际的服务名称,最多等待30秒 while ServiceExists('你的服务名') and (WaitTime < 30) do begin Sleep(1000); WaitTime := WaitTime + 1; end; Result := ''; end;
内容的提问来源于stack exchange,提问作者Pushpender Singh
相关产品推荐
相关产品推荐

