Inno Setup - 多次执行 AfterInstall 操作

Inno Setup - AfterInstall action executed multiple times

我的脚本中有以下 运行 代码:

procedure AddRulesToFirewall();
var
  ResultCode: Integer;
begin
  Exec('netsh.exe','advfirewall firewall add rule name="MyApplication" dir=in program="{app}\MyApplication.exe" security=notrequired action=allow protocol=tcp','',SW_SHOW, ewWaitUntilTerminated, ResultCode);
end;

我有以下 AfterInstall 操作:

Source:{#OutputBinaries}\Company*.dll; DestDir: {app}; Components: binaries; AfterInstall: AddRulesToFirewall()

但是 AfterInstall 操作被执行了很多次,因此我假设它 运行 是此命令下分组的每个二进制文件的 AfterInstall 操作。

我的问题是,我应该如何更改它以便 AddRulesToFirewall 代码在安装二进制文件后仅 运行 一次?

我意识到我可以在文件部分单独列出所有二进制文件,并且只在最后一个二进制文件上使用 AfterInstall,但是由于有很多二进制文件,我不想使用这种方法。

为什么要用AfterInstall参数?防火墙规则与 DLL 文件有什么关系?

改用CurStepChanged(ssPostInstall)

procedure CurStepChanged(CurStep: TSetupStep);
begin
  if CurStep = ssPostInstall then
  begin
    AddRulesToFirewall;
  end;
end;

不过,如果您出于某种原因确实需要使用 AfterInstall,您可以使用 CurrentFileName 魔法变量,前提是您知道最后一个与通配符匹配的文件。

procedure AddRulesToFirewall();
var
  ResultCode: Integer;
begin
  if ExtractFileName(CurrentFileName) = 'CompanyLast.dll' then
  begin
    Exec(
      'netsh.exe',
      'advfirewall firewall add rule name="MyApplication" dir=in ' +
        'program="{app}\MyApplication.exe" security=notrequired action=allow protocol=tcp',
      '', SW_SHOW, ewWaitUntilTerminated, ResultCode);
  end;
end;

虽然这可能不可靠。


另一种选择是,如果通配符条目不是最后一个,则使用下一个条目的 BeforeInstall 参数。

Source: Company*.dll; DestDir: {app}
Source: AnotherFile.dat; DestDir: {app}; BeforeInstall: AddRulesToFirewall()