fub*_*bar 2 caching inno-setup
我会尽量简短,不附上所有相关的源文件。我已经尽可能多地追查这个问题了我的帕斯卡知识允许我......
我认为我发现在步骤ssInstall中发生了磁盘缓存问题。我有一个应用程序的安装程序,如果它发现安装了较旧的应用程序版本,它将调用如下卸载:
procedure CurStepChanged(CurStep: TSetupStep);
var
uninstallStr: String;
ResultCode: Integer;
begin
if (CurStep = ssInstall) and IsUpdatableApplicationInstalled() then
begin
uninstallStr := GetUninstallString();
uninstallStr := RemoveQuotes(uninstallStr);
Result := Exec(uninstallStr, '/SILENT /NORESTART /SUPPRESSMSGBOXES', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
if Result and (ResultCode = 0) then
Log('CurStepChanged = ssInstall; uninstall OK');
//-------------
//Sleep(30000);
//-------------
end;
Run Code Online (Sandbox Code Playgroud)
文件夹/文件的定义如下:
[Dirs]
Name: "{app}\db"; Flags: uninsalwaysuninstall
[Files]
Source: "..\bin\*"; DestDir: "{app}\bin"; Flags: ignoreversion createallsubdirs recursesubdirs
Source: "..\java\jre\*"; DestDir: "{app}\jre"; Flags: ignoreversion recursesubdirs createallsubdirs
blah...
Run Code Online (Sandbox Code Playgroud)
测试用例1;正常安装:一切顺利。日志文件部分:
Starting the installation process.
Creating directory: C:\Program Files <---
Creating directory: C:\Program Files\MyApp <---
Creating directory: C:\Program Files\MyApp\db <---
Creating directory: C:\Program Files\MyApp\jre <---
Creating directory: C:\Program Files\MyApp\jre\lib
Creating directory: C:\Program Files\MyApp\jre\lib\applet
Directory for uninstall files: C:\Program Files\MyApp
Creating new uninstall log: C:\Program Files\MyApp\unins000.dat <--- !!!
-- File entry --
Dest filename: C:\Program Files\MyApp\unins000.exe <--- !!!
blah...
Run Code Online (Sandbox Code Playgroud)
测试用例2;更新旧版本:当进入步骤ssInstall时,卸载程序启动,完成后开始安装。日志文件部分:
CurStepChanged = ssInstall; uninstall OK
Starting the installation process.
Creating directory: C:\Program Files\MyApp\jre\lib
Creating directory: C:\Program Files\MyApp\jre\lib\applet
Directory for uninstall files: C:\Program Files\MyApp
Creating new uninstall log: C:\Program Files\MyApp\unins001.dat <--- !!!
-- File entry --
Dest filename: C:\Program Files\MyApp\unins001.exe <--- !!!
blah...
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,某些文件夹未创建,并且我的应用程序稍后在尝试写入“db”文件夹时失败。
如果我取消注释Sleep()命令,一切都会顺利运行,并且两个日志文件都是相同的。
看来磁盘有足够的时间来刷新更改!不知何故,inno-setup 中一定缺少一个flush() 命令。
任何专家都可以发表评论或提供帮助吗?我可以调用flush()而不是sleep()吗?任何帮助表示赞赏。我只是想在提交错误请求之前确定一下。
只是总结一下这个问题的评论轨迹:
最好的解决方案是根本不运行卸载程序。您可以通过该部分删除多余的文件[InstallDelete];例如。要完全删除“jre”子文件夹(作为安装的一部分进行替换),请执行以下操作:
[InstallDelete]
Type: filesandordirs; Name: "{app}\jre"
Run Code Online (Sandbox Code Playgroud)
(仅对这样的子文件夹使用此功能,并且要谨慎使用;如果删除太多内容,您可能会给自己带来麻烦。)
对于以前版本安装的普通单个应用程序文件现在是多余的,您可以像这样删除它们:
[InstallDelete]
Type: files; Name: "{app}\redundant.dll"
Run Code Online (Sandbox Code Playgroud)
(如果安装时有“regserver”或“sharedfile”,您需要做一些更花哨的事情。)
卸载程序在运行时无法删除自身或它所在的文件夹。虽然 Inno 确实以能够删除卸载程序和文件夹的方式处理此问题,但这确实意味着您Exec对卸载程序的调用将在删除发生之前以及卸载过程实际完成之前返回。
卸载实际完成后,您将需要等待更长的时间Exec才能继续安装。使用睡眠非常简单,并且在大多数情况下都可以工作,但如果您想要获得最佳结果,则需要调用 WinAPI 来检查正在运行的进程列表。
此外,您应该使用PrepareToInstall事件函数来执行实际的卸载。这将允许您更好地处理卸载错误或卸载和重新安装之间需要重新启动等情况。(而且因为它在安装过程中的“正确”时间执行。)