在 Inno Setup 中为卸载过程加载外部 DLL
Load external DLL for uninstall process in Inno Setup
我正在尝试加载 VclStylesInno.dll Inno Setup 的卸载形式。
下一个代码在 [Code]
部分的中间声明:
procedure uLoadVCLStyle(VClStyleFile: String);
external 'LoadVCLStyleW@{app}/VclStylesInno.dll stdcall';
但是我遇到了一个错误
An attempt was made to expand the "app" constant before it was initialized
为卸载过程加载 DLL 的最佳方法是什么?
我假设您在启动安装程序时遇到错误,而不是卸载程序。
安装程序启动时,{app}
显然是未知的。
但是因为你只需要导入卸载程序,它知道 {app}
,你可以添加 uninstallonly
option:
procedure uLoadVCLStyle(VClStyleFile: String);
external 'LoadVCLStyleW@{app}\VclStylesInno.dll stdcall uninstallonly';
虽然它并没有真正的帮助,因为卸载程序会想要删除 DLL,但失败了,因为它已将 DLL 自身锁定。
解决方法很简单,按照官方的instructions for uninstalling the VCL Styles for Inno Setup.
您基本上需要将 DLL 安装在 {app}
之外的其他位置,并在卸载时留下 DLL。这实际上是一个丑陋的解决方案,恕我直言,这并不能证明样式化的卸载程序是合理的。但这是你的选择。
按照您的建议,您可以将 DLL 复制到 Windows 临时文件夹,从那里加载它并希望 Windows 最终在临时目录清理期间删除 DLL。
应该这样做(注意 delayload
option):
[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%
) 的其他进程。
另一种解决方案(更好但实施起来更复杂),请参阅
How keep uninstall files inside uninstaller?
我正在尝试加载 VclStylesInno.dll Inno Setup 的卸载形式。
下一个代码在 [Code]
部分的中间声明:
procedure uLoadVCLStyle(VClStyleFile: String);
external 'LoadVCLStyleW@{app}/VclStylesInno.dll stdcall';
但是我遇到了一个错误
An attempt was made to expand the "app" constant before it was initialized
为卸载过程加载 DLL 的最佳方法是什么?
我假设您在启动安装程序时遇到错误,而不是卸载程序。
安装程序启动时,{app}
显然是未知的。
但是因为你只需要导入卸载程序,它知道 {app}
,你可以添加 uninstallonly
option:
procedure uLoadVCLStyle(VClStyleFile: String);
external 'LoadVCLStyleW@{app}\VclStylesInno.dll stdcall uninstallonly';
虽然它并没有真正的帮助,因为卸载程序会想要删除 DLL,但失败了,因为它已将 DLL 自身锁定。
解决方法很简单,按照官方的instructions for uninstalling the VCL Styles for Inno Setup.
您基本上需要将 DLL 安装在 {app}
之外的其他位置,并在卸载时留下 DLL。这实际上是一个丑陋的解决方案,恕我直言,这并不能证明样式化的卸载程序是合理的。但这是你的选择。
按照您的建议,您可以将 DLL 复制到 Windows 临时文件夹,从那里加载它并希望 Windows 最终在临时目录清理期间删除 DLL。
应该这样做(注意 delayload
option):
[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%
) 的其他进程。
另一种解决方案(更好但实施起来更复杂),请参阅
How keep uninstall files inside uninstaller?