3

我正在尝试为 Inno Setup 的卸载形式加载 VclStylesInno.dll。下一段代码在[Code]部分中间声明:

procedure uLoadVCLStyle(VClStyleFile: String);
    external 'LoadVCLStyleW@{app}/VclStylesInno.dll stdcall';

但我遇到了一个错误

在初始化之前尝试扩展“app”常量

为卸载过程加载 DLL 的最佳方法是什么?

4

1 回答 1

1

我假设您在启动安装程序时遇到错误,而不是卸载程序。

当安装程序启动时,{app}显然是未知的。

但是由于您只需要为卸载程序导入,它知道{app},您可以添加uninstallonly选项

procedure uLoadVCLStyle(VClStyleFile: String); 
  external 'LoadVCLStyleW@{app}\VclStylesInno.dll stdcall uninstallonly';

虽然它并没有真正帮助,因为卸载程序会想要删除 DLL,但失败了,因为它自己锁定了 DLL。

解决方法很简单,按照官方说明卸载 VCL Styles for Inno Setup 即可

您基本上需要将 DLL 安装在 DLL 之外的其他位置,{app}并在卸载时将 DLL 留在后面。这实际上是一个丑陋的解决方案,恕我直言并不能证明风格化的卸载程序是合理的。但这是你的选择。


正如您所建议的,您可以将 DLL 复制到 Windows 临时文件夹,从那里加载并希望 Windows 在临时目录清理期间最终删除 DLL。

这应该这样做(注意delayload选项):

[Files]
Source: VclStylesInno.dll; DestDir: {app}
Source: skin.vsf; DestDir: {app}
[Code]

procedure LoadVCLStyle_UnInstall(VClStyleFile: String); 
  external 'LoadVCLStyleW@{%TEMP}\VclStylesInno.dll stdcall uninstallonly delayload';

function InitializeUninstall: Boolean;
begin
  if FileCopy(ExpandConstant('{app}\VclStylesInno.dll'),
              ExpandConstant('{%TEMP}\VclStylesInno.dll'), False) and
     FileCopy(ExpandConstant('{app}\skin.vsf'),
              ExpandConstant('{%TEMP}\skin.vsf'), False) then
  begin
    LoadVCLStyle_UnInstall(ExpandConstant('{%TEMP}\skin.vsf'));
  end;
end;

虽然我没有对其进行测试,但使用它可能会更好{tmp}{%TEMP}在卸载完成后,文件可能会被卸载程序父进程删除 - 您不会干扰可能想要存储VclStylesInno.dll到的其他进程%TEMP%)。


对于另一种解决方案(更好但实施起来更复杂),请参阅
如何将卸载文件保留在卸载程序中?

于 2016-04-29T15:05:31.010 回答