8

我想在静默模式下调用多个 .msi 文件,如果有任何失败,则停止整个安装。

是否可以从 [run] 部分调用 msiexec.exe 的返回码?

目前我只能在 windows 事件查看器中看到错误消息。

4

2 回答 2

5

目前无法检查[Run]条目是否成功执行。该代码仅记录进程退出代码并继续下一个条目(可以在 Inno Setup 源文件Main.pas中检查,函数是ProcessRunEntry(),从当前版本 5.2.3 中的第 3404 行开始)。

如果您需要确保 msiexec 的多次执行都成功,您将需要编写一个中间层。这可以像在 [Run] 条目中执行的小存根一样简单,并使用正确的参数启动 msiexec.exe,等待进程完成,然后将返回代码写入文件。

检查此类安装步骤是否成功的另一种方法是使用AfterInstall参数为每​​个[Run]条目添加自定义过程调用。例如,在这样的功能中,您可以检查 OCX 控件是否已成功安装:

[Run]
Filename: "{tmp}\MyInstallation1.exe"; Parameters: "/foo"; AfterInstall: AfterMyInstallation1

[Code]
var
  MyInstallation1Success: boolean;

procedure AfterMyInstallation1;
var
  V: Variant;
begin
  try
    V := CreateOleObject('MyInstallation.InstalledOcxControl.1');
    MyInstallation1Success := True;
  except
    MyInstallation1Success := False;
  end;
end;

或者依赖项的目录和注册表项是否都在那里。

每个[Run]条目仅在其可选的Check参数返回 true 时才会执行。因此,根据您的需要,您可以一个接一个地启动所有静默安装,并在最后一个完成后执行脚本函数以检查所有依赖项是否已成功安装;或者您可以为每个依赖项安装编写一个检查函数,然后返回 false 并因此在第一次失败后跳过所有其他安装。

但是请注意,所有[运行]条目都是在文件复制、注册表写入等步骤完成后执行的,因此您基本上已经完成了安装。如果您只想在正确安装所有依赖项时才真正执行所有安装步骤,那么您必须在该过程的早期执行此操作,此时仍然可以取消安装。

编辑:查看问题“如何使 Inno Setup 在执行长执行时看起来不冻结?” 其中给出了一些信息,并链接了一个示例脚本,以使用Exec()函数安装依赖项。因此,如果您不使用[Run]条目,则很有可能实现您想要的。

于 2009-02-24T17:03:05.867 回答
1

您可以使用对类似问题的回答在 [Run] 部分安全地运行命令,并提供适当的通知和错误回滚。

上面的链接提供了完整的解决方案,但想法如下:

1) 使用 InnoSetup 的 BeforeInstall 参数将错误消息写入临时文件 {tmp}\install.error。

2) 使用 Windows 命令外壳“cmd.exe /s /c”运行所需程序。还可以使用带有“&&”的“del”命令的条件执行 - http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/ntcmds_shelloverview.mspx?mfr=true。因此,如果命令成功(退出代码 0),错误消息文件将被删除。请注意“cmd.exe /s /c”中的特殊引号处理。

3) 使用 InnoSetup 的 AfterInstall 参数检查错误消息文件 {tmp}\install.error 的存在,并通过适当的通知或确认(以及可选的日志文件显示)中止安装并使用 Exec(ExpandConstant('{uninstallexe}') 执行回滚, ...

4) 应该做一些额外的步骤,比如覆盖 InnoSetup 的 ShouldSkipPage(PageID: Integer) 函数以隐藏最终页面等。

于 2014-06-20T08:42:17.003 回答