msi在Inno Setup中返回代码

时间:2009-02-24 16:29:43

标签: windows-installer inno-setup

我想以静默方式调用多个.msi文件,如果失败则暂停整个安装。

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

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

2 个答案:

答案 0 :(得分: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,从而在第一个失败之后跳过所有其他安装。

但请注意,在完成文件复制,注册表编写等步骤后,所有 [Run] 条目都会执行,因此您基本上已经完成了安装。如果您只想在正确安装所有依赖项的情况下真正执行所有安装步骤,那么在安装仍然可以取消时,您必须在此过程中提前执行此操作。

修改:查看问题"How do you make Inno Setup not look frozen while performing a long Exec?",其中提供了一些信息,并且示例脚本链接到使用 Exec()函数来安装依赖项。因此,如果您不使用 [Run] 条目,那么很有可能实现您想要的目标。

答案 1 :(得分:1)

您可以使用my answer类似问题在[运行]部分安全地运行命令,并在出错时正确通知和回滚。

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

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

2)使用Windows命令shell“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)函数来隐藏最终页面等。