NSIS是一款免费的制作windows安装包的工具,功能灵活强大。
关于NSIS基础的安装,语法结构,请自行百度,本文仅针对于一些比较特别的功能做一些备忘记录。
1. 多语言的支持
此处仅介绍按照最新版的 NSIS 3.0 版本,使用 ModernUI 载入多语言
!include "MUI2.nsh" ; 仅有2支持
; 语言选择窗口常量设置
; 在注册表中记录安装时选择的语言,卸载时就可以不再选择语言,直接显示对应语言的卸载程序
!define MUI_LANGDLL_REGISTRY_ROOT "${PRODUCT_ROOT_KEY}"
!define MUI_LANGDLL_REGISTRY_KEY "${PRODUCT_UNINST_KEY}"
!define MUI_LANGDLL_REGISTRY_VALUENAME "NSIS:Language"
; 证书页,不同语言载入不同的 license 文件
LicenseLangString License 1033 "license-english.txt"
LicenseLangString License 2052 "license-chinese.txt"
!define MUI_LICENSEPAGE_CHECKBOX
!insertmacro MUI_PAGE_LICENSE $(License)
; 列出支持语言
!insertmacro MUI_LANGUAGE "English"
!insertmacro MUI_LANGUAGE "SimpChinese"
; 无论如何,安装时都显示选择语言的选项
!insertmacro MUI_RESERVEFILE_LANGDLL
; 多语言文本定义
LangString ModuleMain ${LANG_SIMPCHINESE} "主程序"
LangString ModuleMain ${LANG_ENGLISH} "esreader main"
。
。
。
; .onInit 函数中引入显示语言选择框
Function .onInit
; 显示语言选项
!insertmacro MUI_LANGDLL_DISPLAY
FunctionEnd
; 使用多语言文本定义的变量,注意是 $() 而不是 ${}
Section "$(ModuleMain)" SEC01
。
。
。
SectionEnd
; 卸载时,在 un.onInit 函数载入注册表中记录的语言
Function un.onInit
!insertmacro MUI_UNGETLANGUAGE
FunctionEnd
其中需要特别注意的是,.onInit 以及 un.onInit 函数是在安装/卸载程序的UI出现之前就加载的,LangString 的定义是在UI出现之后,所以在 .onInit/un.onInit 中使用 LangString 不会生效
2. 自定义数据存储目录
。。。
; 选择安装目录页面
!insertmacro MUI_PAGE_DIRECTORY
; 自定义数据存储位置选择页面
Page custom chooseDataDirPage
。。。
; 选择文件存储位置页面
Function chooseDataDirPage
; 注册表中不存在安装位置,表示全新安装
; 如果是覆盖安装,则不需要选择数据存储目录,防止软件数据出问题
${If} $installPosition == ""
; 设置 dataDir 的默认值为 C:\akdata
StrCpy $dataDir "C:\akdata"
!insertmacro MUI_HEADER_TEXT "$(ChooseFileHeader1)" "$(ChooseFileHeader2)"
nsDialogs::Create /NOUNLOAD 1018
Pop $chooseDirDialog
${If} $chooseDirDialog == error
Abort
${EndIf}
${NSD_CreateDirRequest} 0 23u 225u 12u "$dataDir"
Pop $chooseDirDialog
${NSD_OnChange} $chooseDirDialog changeDir
${NSD_CreateBrowseButton} 235u 23u 45u 15u "$(ChooseFileBtn)"
Pop $chooseDirBtn
${NSD_OnClick} $chooseDirBtn showDialog
nsDialogs::Show
${EndIf}
FunctionEnd
; 目录改变时,将当前位置写入变量 dataDir
Function changeDir
${NSD_GetText} $chooseDirDialog $dataDir
FunctionEnd
; 显示文件选择对话框
Function showDialog
nsDialogs::SelectFolderDialog /NOUNLOAD "$(ChooseFileHeader2)" ""
Pop $dataDir
${If} $dataDir != error
${NSD_SetText} $chooseDirDialog $dataDir
${EndIf}
FunctionEnd
3. 安装包的一些基本信息
此处配置主要是为了修改生成的安装包的如下信息:
; 定义安装文件信息
VIProductVersion "${PRODUCT_VERSION}"
VIAddVersionKey /LANG=${LANG_SIMPCHINESE} FileDescription "${PRODUCT_NAME}"
VIAddVersionKey /LANG=${LANG_SIMPCHINESE} FileVersion "${PRODUCT_VERSION}"
VIAddVersionKey /LANG=${LANG_SIMPCHINESE} ProductName "${PRODUCT_NAME}"
VIAddVersionKey /LANG=${LANG_SIMPCHINESE} ProductVersion "${version}"
VIAddVersionKey /LANG=${LANG_SIMPCHINESE} LegalCopyright "Copyright(C) XXX. All rights reserved"
VIAddVersionKey /LANG=${LANG_SIMPCHINESE} CompanyName "${PRODUCT_PUBLISHER}"
4. 配合读取项目版本,作为安装包的版本
这里以读取比如 nodejs 项目中的 package.json 文件的版本号为例,需要先写一个 bat 或者 sh 脚本,从 package.json 文件中读取 version 字段,并且写入到 version.txt 文件中
@echo off
REM 获取版本号
for /f "tokens=1,2* delims=," %%a in (package.json) do (
echo %%a | findstr "version" >nul && set VERSION=%%a
)
echo !define version "%VERSION:~-6,5%" > version.txt
version.txt 文件中写入的内容是:
!define version "0.0.7"
然后,在 NSIS 脚本中,调用脚本,并且载入 version.txt 文件并使用 version 变量
!system "get-version.bat"
!include "version.txt"
; 使用 version 字段,就如同变量一样,用 ${version} 即可