参考“ NSIS用户手册”,NSIS脚本语言中有三个指令可以执行外部程序:

  • Exec :执行一个指定的程序并且立即继续安装。如: Exec '"$INSTDIR\command.exe" 参数'
  • ExecShell :使用Windows的外壳关联来执行一个指定的程序,并且立即继续安装。类似于我们在Windows目录浏览窗口以默认打开方式来执行文件。如: ExecShell "open" "$INSTDIR\command.exe"
  • ExecWait :执行一个指定的程序并且等待运行处理结束,再继续安装。如: ExecWait '"$INSTDIR\command.exe" 参数' $0 ($0当产生错误时设置为错误标记,未产生错误则为未指定)
  • 以上命令当不能被运行时则会置一个错误标记,如果命令包含有空格,则要用引号把他们包括起来。

    如果我们的安装程序需要执行一些后台命令,使用上面的指令时会出现命令行窗口,显得很不和谐,我们就可以使用 nsExec 。具体的有三种用法: nsExec::Exec/ nsExec::ExecToLog/ nsExec::ExecToStack ,不同的是 nsExec::ExecToLog 会把结果输出到日志窗口, nsExec::ExecToStack 会把结果输出到堆栈中。

    例如: nsExec::ExecToStack '"$INSTDIR\command.exe" 参数'

    具体到我们需要执行PowerShell 命令文件,则 nsExec::ExecToStack 'powershell -inputformat none -ExecutionPolicy RemoteSigned -File "${PSFile}"  '

    PowerShell封装

    NSIS网站上有有对PowerShell的支持,请参见 PowerShell support ,把其中的脚本保存为"psexec.nsh"文件,在需要使用的“*.nsi”文件中引用该头文件( !include psexec.nsh )。

  • Powershell命令调用例子
  • ${PowerShellExec} "Get-WmiObject -Class Win32_ComputerSystem"
    Pop $R1
    detailprint "PowerShell命令执行结果:$R1"
  • Powershell文件调用例子
  • InitPluginsDir
    SetOutPath $PLUGINSDIR\Powershell
    File script.ps1
    ${PowerShellExecFileLog} "$PLUGINSDIR\Powershell\script.ps1"

    像上面介绍的"psexec.nsh"文件那样头文件能在一定程度上扩展NSIS脚本语言的功能,但遇到复杂的情况,更高级的就是使用插件来扩展它的功能。

    插件可以使用其他编程语言来写(如:C、C++等),里面有公开的函数,编译后生成DLL文件,把DLL文件放在NSIS安装目录的Plugins文件夹下(如:C:\Program Files (x86)\NSIS\Plugins),NSIS脚本语言使用时通过 dll::function“参数” 进行调用(如: MSSQL_OLEDB::SQL_Execute "CREATE DATABASE [MyTestDB]" )。 当 NSIS 编译器开始时它会扫描插件目录的 DLL 文件并且列出找到的插件和输出的函数,在编译时如果遇到有序的冒号如 fred::flintstone编译器将会作为关键字在该列表中查找,如果列表项列入了 fred.dll 并输出 flintstone 则 NSIS 将会把 fred.dll 文件打包到安装程序里。当插件命令执行时 NSIS 将会解压所需的插件 DLL 文件到一个临时目录 ($PLUGINSDIR),把指定的参数全部压入(从右到左次序),然后执行 DLL 函数。

    如果你想调用一个用户硬盘或其他地方里的插件,你可以使用CallInstDLL,从一个 NSIS 扩展动态链接库里调用一个函数,需要自行把函数的参数全部压入堆栈,扩展动态链接库可以访问堆栈和变量,如下例子:

    Push "参数"
    Push "另一个参数"
    CallInstDLL $INSTDIR\somedll.dll somefunction

    其中用C++写的一个例子 Contrib/ExDLL 可以参考。另外NSIS网站提供了一些插件,请参见 Category:Plugins ,这里面包括我们接下章节要讲解的 访问数据库 的插件。