在 Inno Setup 中加载具有依赖项的 DLL 在 "Cannot import DLL" 的卸载程序中失败,但在安装程序中有效
Loading DLL with dependencies in Inno Setup fails in uninstaller with "Cannot import DLL", but works in the installer
卸载程序时出现此错误:
Cannot import dll: <utf8>c:\TestProg\IsStart.dll
我做错了什么?谁能帮我解决这个问题?
CheckO4TaskMngrSvcStopAndUninstall
停止并删除 O4TaskManager Service
:
代码如下:
[Files]
Source: "IsStartServer.dll"; DestDir: "{tmp}"; DestName: IsStart.dll
Source: "IsStartServer.dll"; DestDir: "{app}"; DestName: IsStart.dll
Source: "sqlite3x86.dll"; DestDir: "{src}"; DestName: sqlite3.dll
Source: "sqlite3x86.dll"; DestDir: "{app}"; DestName: sqlite3.dll
Source: "sqlite3x64.dll"; DestDir: "{app}"
[Code]
function TaskMngrInst: LongBool;
external 'CheckO4TaskMngrSvcStopAndUninstall@files:IsStart.dll,sqlite3.dll stdcall loadwithalteredsearchpath setuponly';
function TaskMngrUninst: LongBool;
external 'CheckO4TaskMngrSvcStopAndUninstall@{app}\IsStart.dll stdcall uninstallonly';
procedure CurStepChanged(CurStep: TSetupStep);
begin
if CurStep = ssInstall then
begin
TaskMngrInst();
end;
end;
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
if CurUninstallStep = usUninstall then
begin
TaskMngrUninst();
DeleteFile(ExpandConstant('{app}\sqlite3.dll'));
DeleteFile(ExpandConstant('{app}\IsStart.dll'));
RenameFile('{app}\sqlite3x64.dll)', '{app}\sqlite3.dll');
end;
end;
IsStart.dll 取决于 sqlite3.dll?可能它不知道什么是 sqlite3x86.dll。在带有一些插件的totalcmd中,你可以查看丢失的dll
我相信有一系列不同的问题(其中一些确实是基于我的错误建议)。
正确的代码是,imo:
[Files]
Source: "IsStartServer.dll"; DestDir: "{app}"; DestName: IsStart.dll
Source: "sqlite3x86.dll"; DestDir: "{app}"; DestName: sqlite3.dll
[Code]
function TaskMngrInst: LongBool;
external 'CheckO4TaskMngrSvcStopAndUninstall@files:IsStart.dll,sqlite3.dll stdcall loadwithalteredsearchpath setuponly';
function TaskMngrUninst: LongBool;
external 'CheckO4TaskMngrSvcStopAndUninstall@{app}\IsStart.dll stdcall loadwithalteredsearchpath uninstallonly';
要点:
- 您最初的问题是卸载程序的导入声明中缺少
loadwithalteredsearchpath
flag。您需要它来加载依赖项 (sqlite3.dll
)。
- 您需要将依赖项 (
sqlite3.dll
) 安装到 {app}
以供卸载程序使用。
- 已安装的依赖项副本必须与主 DLL 查找的名称相匹配(
sqlite3.dll
,而不是 sqlite3x86.dll
)。
external
声明中的 DLL 名称必须与目标文件名(DestName: IsStart.dll
、DestName: sqlite3.dll
)相匹配,而不是原始文件名。
- 仅当从安装程序(使用
files:
前缀)加载 DLL 时,依赖项必须并且可以在声明中列出。从物理路径 ({app}\IsStart.dll
) 加载 DLL 时不是。列出依赖项的唯一目的是让安装程序提取它(它不加载它,主 DLL 加载它,因此是前一点)。加载物理文件时不需要列出它,因为所有文件都(必须)已经安装。如果您使用 {app}\primary.dll,{app}\dependency.dll
,卸载程序实际上会尝试加载名称为 {app}\primary.dll,{app}\dependency.dll
的文件 – 显然会失败。
- 在
{tmp}
或 {src}
上安装任何东西都没有意义。
卸载程序时出现此错误:
Cannot import dll: <utf8>c:\TestProg\IsStart.dll
我做错了什么?谁能帮我解决这个问题?
CheckO4TaskMngrSvcStopAndUninstall
停止并删除 O4TaskManager Service
:
代码如下:
[Files]
Source: "IsStartServer.dll"; DestDir: "{tmp}"; DestName: IsStart.dll
Source: "IsStartServer.dll"; DestDir: "{app}"; DestName: IsStart.dll
Source: "sqlite3x86.dll"; DestDir: "{src}"; DestName: sqlite3.dll
Source: "sqlite3x86.dll"; DestDir: "{app}"; DestName: sqlite3.dll
Source: "sqlite3x64.dll"; DestDir: "{app}"
[Code]
function TaskMngrInst: LongBool;
external 'CheckO4TaskMngrSvcStopAndUninstall@files:IsStart.dll,sqlite3.dll stdcall loadwithalteredsearchpath setuponly';
function TaskMngrUninst: LongBool;
external 'CheckO4TaskMngrSvcStopAndUninstall@{app}\IsStart.dll stdcall uninstallonly';
procedure CurStepChanged(CurStep: TSetupStep);
begin
if CurStep = ssInstall then
begin
TaskMngrInst();
end;
end;
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
if CurUninstallStep = usUninstall then
begin
TaskMngrUninst();
DeleteFile(ExpandConstant('{app}\sqlite3.dll'));
DeleteFile(ExpandConstant('{app}\IsStart.dll'));
RenameFile('{app}\sqlite3x64.dll)', '{app}\sqlite3.dll');
end;
end;
IsStart.dll 取决于 sqlite3.dll?可能它不知道什么是 sqlite3x86.dll。在带有一些插件的totalcmd中,你可以查看丢失的dll
我相信有一系列不同的问题(其中一些确实是基于我的错误建议)。
正确的代码是,imo:
[Files]
Source: "IsStartServer.dll"; DestDir: "{app}"; DestName: IsStart.dll
Source: "sqlite3x86.dll"; DestDir: "{app}"; DestName: sqlite3.dll
[Code]
function TaskMngrInst: LongBool;
external 'CheckO4TaskMngrSvcStopAndUninstall@files:IsStart.dll,sqlite3.dll stdcall loadwithalteredsearchpath setuponly';
function TaskMngrUninst: LongBool;
external 'CheckO4TaskMngrSvcStopAndUninstall@{app}\IsStart.dll stdcall loadwithalteredsearchpath uninstallonly';
要点:
- 您最初的问题是卸载程序的导入声明中缺少
loadwithalteredsearchpath
flag。您需要它来加载依赖项 (sqlite3.dll
)。 - 您需要将依赖项 (
sqlite3.dll
) 安装到{app}
以供卸载程序使用。 - 已安装的依赖项副本必须与主 DLL 查找的名称相匹配(
sqlite3.dll
,而不是sqlite3x86.dll
)。 external
声明中的 DLL 名称必须与目标文件名(DestName: IsStart.dll
、DestName: sqlite3.dll
)相匹配,而不是原始文件名。- 仅当从安装程序(使用
files:
前缀)加载 DLL 时,依赖项必须并且可以在声明中列出。从物理路径 ({app}\IsStart.dll
) 加载 DLL 时不是。列出依赖项的唯一目的是让安装程序提取它(它不加载它,主 DLL 加载它,因此是前一点)。加载物理文件时不需要列出它,因为所有文件都(必须)已经安装。如果您使用{app}\primary.dll,{app}\dependency.dll
,卸载程序实际上会尝试加载名称为{app}\primary.dll,{app}\dependency.dll
的文件 – 显然会失败。 - 在
{tmp}
或{src}
上安装任何东西都没有意义。