Inno Setup:安装完成后无法卸载并删除{tmp}文件夹中的依赖DLL
解决Inno Setup临时DLL无法卸载导致临时文件夹删除失败的问题
首先咱们先定位问题根源:你用了delayload声明外部函数,Inno Setup会自动把这些DLL提取到{tmp}并加载,但直接在DeinitializeSetup里调用UnloadDll没生效,大概率是这几个原因:
- 调用
UnloadDll时没指定{tmp}下的完整DLL路径,只写了文件名 DeinitializeSetup的执行时机偏晚,此时安装程序内部可能还在占用DLL- 外部函数声明存在拼写错误(比如你代码里的
SetupUtilitie...明显是截断了,这会影响DLL的追踪)
接下来给你一步步的修复方案:
1. 确保UnloadDll调用的是完整路径
你的DLL被提取到{tmp}目录下,调用卸载时必须传入该目录下的完整路径,不能只写文件名。示例代码如下:
procedure DeinitializeSetup(); var TempPath: String; begin TempPath := ExpandConstant('{tmp}'); // 按加载顺序反向卸载,确保依赖关系正确 UnloadDll(TempPath + '\SetupUtilities.dll'); UnloadDll(TempPath + '\unzipper.dll'); end;
2. 提前卸载时机:用CurStepChanged替代DeinitializeSetup
DeinitializeSetup执行时,安装程序的临时文件清理流程已经启动,可能导致DLL还被占用。你可以在ssPostInstall步骤(安装完成、临时文件夹删除前)执行卸载:
procedure CurStepChanged(CurStep: TSetupStep); var TempPath: String; begin if CurStep = ssPostInstall then begin TempPath := ExpandConstant('{tmp}'); UnloadDll(TempPath + '\SetupUtilities.dll'); UnloadDll(TempPath + '\unzipper.dll'); end; end;
3. 检查外部函数声明的正确性
确保函数名、DLL名完全匹配,比如你截断的那行代码应该修正为:
function IsDirectX10Installed_(): boolean; external 'IsDirectX10Installed@files:SetupUtilities.dll stdcall delayload';
拼写错误会导致Inno Setup无法正确追踪DLL的引用关系,自然无法正常卸载。
4. 万不得已的兜底方案:强制删除(谨慎使用)
如果上面的方法都无效,可以尝试卸载后强制删除文件,但前提是必须确保DLL已完全释放:
procedure CurStepChanged(CurStep: TSetupStep); var TempPath: String; DllPath1, DllPath2: String; begin if CurStep = ssPostInstall then begin TempPath := ExpandConstant('{tmp}'); DllPath1 := TempPath + '\SetupUtilities.dll'; DllPath2 := TempPath + '\unzipper.dll'; UnloadDll(DllPath1); UnloadDll(DllPath2); // 尝试删除文件 DeleteFile(DllPath1); DeleteFile(DllPath2); end; end;
最后提醒:还要确保你的InstallDirectX等调用DLL的过程执行完毕后,没有残留的引用(比如DLL内的函数是否持有全局资源未释放)。
内容的提问来源于stack exchange,提问作者Bug Raptor
相关产品推荐
相关产品推荐

