NSIS脚本对于传参的支持不好,当传入参数时需要手动push参数(类似汇编)。
例如以下的函数常用于在安装时杀死进程:
Function ForceKillProcessImp
Pop $1 ; exe name
try_kill_one:
KillProcDLL::KillProc "$1"
Pop $R0
IntCmp $R0 0 try_kill_one ; 返回0表示杀进程成功,则应继续杀此进程名的其它进程
IntCmp $R0 603 check_no_more ; 返回603表示没找到此进程,有两种情况:a) 确实没有此进程 b) 因权限等原因无法访问此进程,如果第2种,应认为杀进程失败,所以需要进一步检查
fail_to_kill: ; KillProc返回值非0非603,或返回603但实际上此进程仍存在,均表示杀进程失败
MessageBox MB_ICONQUESTION|MB_YESNO "无法终止$1,是否重试?" IDYES try_kill_one IDNO fail_quit
fail_quit:
Quit
check_no_more:
FindProcDLL::FindProc "$1"
Pop $R0
IntCmp $R0 1 fail_to_kill ; 如果FindProc结果为1,表示找到了程序,说明杀进程失败,否则继续
FunctionEnd
这个函数被设计为传入一个参数,将参数指定的进程杀死。
需要这样调用:
$0 = "123456"
Push $0
Call ForceKillProcessImp
每一个进程都需要调用一次,当某些产品的相关进程很多,或者时要在多个地方判断时就会非常不方便。可以使用宏将改进以上代码使得更简洁方便,如下:
!macro ForceKillProcess EXEName
push ${EXEName}
Call ForceKillProcessImp
!macroend
这样,在需要杀死进程的地方做如下调用即可:
!insertmacro ForceKillProcess "task1.exe"
!insertmacro ForceKillProcess "task2.exe"
!insertmacro ForceKillProcess "task3.exe"
上面的!insertmacro这个指令告诉编译器将ForceKillProcess这个宏代表的指令插入到NSIS的源码中。
相当于:
push “task1.exe”
Call ForceKillProcessImp
push “task2.exe”
Call ForceKillProcessImp
push “task3.exe”
Call ForceKillProcessImp
对比以下可见使用宏的方式明显更加简单清晰。