背景:
InnoSetup是一款Delphi语言开发的开源安装包制作工具,支持安装脚本配置,并且可以在脚本中嵌入Delphi代码。
问题:
前几天在做一个客户端项目的安装包程序时,因为卸载时需要先调用自己的DLL关闭守护服务,然后杀进程,卸载程序;所以用到了在卸载时调用DLL的功能。
如下配置DLL导出函数:
function StopServiceuninst(ServiceName: AnsiString): Boolean;
external 'StopService@ICSetup.dll stdcall delayload uninstallonly';
但是在实际执行卸载时却无法调用此函数。
为此尝试了多种函数导出的配置,都无法正常调用。
解决:
最后在http://blog.csdn.net/dsp_daiyujie/article/details/11945871 的博客中看到一个卸载时调用DLL的配置。
function KillTaskU(ExeFileName: string): Integer;
external 'KillTask@{app}/ISTask.dll stdcall delayload uninstallonly';
发现两者的区别在于后者的配置中,DLL名前增加了绝对路径名。
于是重新配置了一下:
function StopServiceuninst(ServiceName: AnsiString): Boolean;
external 'StopService@{app}\{#ProductDir}\uninst\ICSetup.dll stdcall delayload';
安装运行时发现会报错:“试图在常量初始化之前使用常量app”。
这是因为在安装包安装之前,因为安装路径未指定,{app}常量是未经初始化的,而卸载时因为已经安装完毕,所以此常量是会初始化好的。
所以只要增加uninstallonly标签即可。而因为此DLL是存在与运行目录的,所以delayload标签不加也可以。
最终配置如下:
function StopServiceuninst(ServiceName: AnsiString): Boolean;
external 'StopService@{app}\{#ProductDir}\uninst\ICSetup.dll stdcall uninstallonly';