赞
踩
通常一个需要发布的程序都需要使用安装包进行安装,不可能给客户发送一套程序和依赖性文件,这样如果需要桌面添加软件的快捷方式,就得让客户自己添加(因为每台电脑、每个用户的桌面路径是不一样的),非常的麻烦,而且占用空间非常大,十分不方便,我们需要把他们打包成一个安装包,让用户运行这个安装包进行安装,而且像360软件管家这样的程序也可以识别,就可以通过其他渠道卸载。
本文需要阅读时间:20分钟
我们需要用到的工具有:
1、NSIS安装包制作程序
2、VNISEdit安装包制作程序扩展软件
这两个软件在网上随便一搜就能搜到,比如以下网址,这个网址可以下载到增强版,而且压缩包是整理过的,里面还有其他比较强大的软件:
https://www.onlinedown.net/soft/22742.htm
注意:要使用压缩包内VNISEdit目录下的VNISEdit.exe来制作安装包,而不是外面的NSISEdit.exe,这个有bug,而且功能没有VNISEdit那么强大。
这个压缩包里面含有:
1、NSIS核心编译制作器
2、VNISEdit编译环境
3、NotePad代码编辑器(并非知名的NotePad++,支持各种编程语言和NSIS Script)
4、NSISEditor编译环境(通过向导制作脚本有bug,但可以编辑脚本)
5、zip2exe简易安装包制作器,可以将zip文件做成简单的exe自解压文件。
6、INI2NSI简易ini转nsi的程序
7、修改默认NSIS Script编辑器的程序(没什么用) 8、Reg2nsi注册表转nsi的程序
9、NSISDialogDesigner界面设计程序(需要Microsoft .NET 2.0 及以上环境)
仔细数数,里面能用的东西还是很多的,非常建议大家下载。
NSIS使用代码执行安装过程,这个代码是它独有的,是一个编译型语言,并不是很难,使用的都是比较简单的英语单词,语法也不是非常复杂,可供使用的模块基本帮你做完了很多。但是需要记住的常用函数和关键字很多,一定要有所了解。
由于我们安装了VNISEdit,我们不需要系统地学习NSIS语法和代码,我们可以借助VNISEdit安装包制作向导进行,这样代码和实际效果就能结合起来,我们就能更快的熟悉代码。当我们需要做出一些特殊调整的时候,我们才去手动编辑代码(有些强大设置向导里面是不会给你自定义的)。
首先我们找到VNISEdit软件,Win10的请注意,要始终使用管理员模式打开此程序(等会会展示这个问题),否则使用“编译并运行”只能为你做编译这件事,需要你自己到文件夹里面去双击打开。那如果用管理员模式就可以避免这个小问题。
我们找到上面一栏的向导按钮,就可以按照向导进行制作:
然后点击下一步,去填写应用程序基本信息:
其中必填的是程序名称和版本,其他没有的话是可以不填的。应用程序标志会显示在安装包界面下沿,可以写上版权信息,或者是公司信息。好了之后点击下一步:
这一栏的表单非常重要,决定了安装程序语言,但是我们发现安装语言上什么都没有,然而这又是必填的,出现这种状况的原因是VNISEdit调用NSIS核心,但语言文件并不属于VNISEdit,而是NSIS,所有的安装语言的文件都必须让VNISEdit找到,我们需要调整VNISEdit默认读取路径,找到上面一栏的NSIS,然后点击配置:
这里最重要的是这个编译器选项,必须要定位到一个叫makensis.exe的程序,这个就是核心编译器,这个程序就在NSIS安装目录。点击“应用”,再回到原来的步骤:现在我们就看到语言设置了,你可以勾选你需要的语言,在这里你要注意,如果是单独从网上下载的VNISEdit,可能生成的脚本文件只包含嵌入的语言,但是没有给你选择语言的界面。 如果是按照本文给的网址下载的话就不会有这样的bug。如果不想重装,也可以继续阅读,等会我会给出添加选择语言界面的方法。
安装程序图标可以自己设置,安装程序文件指的是安装包的文件名,图形界面基本上现代界面就行了,如果你想要用古典界面加XP外观也没问题。
压缩算法可以自己选择,有很多种选法,有zlib,lzma,bzip2和它们的固实(Solid)模式,还有“极限压缩”模式,本质上就是固实lzma模式。
接下来下一步是闪屏、音乐等设置,可以设置在安装时候播放音乐,如果你有闲功夫这样做,可以自行研究,我这里不放图片了。
再下一步:
这里的第一行非常重要,决定了你的程序一堆文件默认装在哪里,默认地址最好选择 $PROGRAMFILES\你的程序名文件夹,不存在时将被创建,这里的 $PROGRAMFILES每台电脑都不一样,但是都是系统识别的位置, $是一个转义符, $PROGRAMFILES代表程序安装目录,除此之外还有其他地址代号,代表不同的意思。
给大家列举一些常用的地址代号,排除了不常用的代号:
代号 | 意义 |
---|---|
$PROFRAMFILES | 代表系统安装目录,在此目录下安装的程序能够被360软件管家、Windows“卸载或更改程序”等检测到存在 |
$SMPROGRAMS | 代表开始菜单目录,一般放置软件快捷方式,Win10不能在开始菜单放置卸载和帮助文档的快捷方式,这是Win10的规定,如果设置了是会被自动删除的 |
$INSTDIR | 代表这一步中设定的“应用程序默认目录”,也就是安装目录,如果用户更改安装目录,它将指向用户指定的目录(可以设置不允许用户改变安装目录) |
这三个是最常用的,其他还有一些代号,但是你在编辑的时候通常是不需要使用的。
第二个许可证协议可以放置协议,可以设置三种同意的方式的一种。如果你不需要协议,可以通过删代码来实现,请参照后面的内容。
需要注意的是,中文的协议会乱码,最好使用英文协议或者改变编码形式:
接下来我们进入下一步:
这一步中我们加入需要自解压的文件,可以更改每个组件的的名字和包含的内容,上面自动会写上两个项目,这两个项目仅仅指示你这里应该加入程序文件,可以把它移除。
左边可以加入每个模块的描述,通常来说,只有一个模块的程序通常不允许也不需要用户选择安装的组件,你可以设置一个主程序模块,其他模块包含一些扩展文件什么的。
注意:如果你的程序目录下还有文件夹的话,一定要选择包含子目录,否则包在文件夹的文件不会被打包。
目的目录要根据你的需要设置,如果你的各个组件彼此独立,最好每个组件目标目录设置为$INSTDIR\你的独立组件名文件夹,不存在时将被创建,这样就可以做到彼此独立,但是如果各个组件互相依赖,最好放进一个目录下,装进同一组件,解压到同一目录。
做好了组件和目录之后就能进入下一步了:
接下来是开始菜单文件夹名称,NSIS会在开始菜单加入一个文件夹,用来放你的程序的快捷方式,如果只需要一个快捷方式,不需要设置文件夹,在$SMPROGRAMS放入一个快捷方式就行了,这一点可以在代码中实现,等会继续介绍。通常不需要用户更改开始菜单文件夹名称,如果支持更改的话,可以自己研究,也是非常简单的。
注:为了关照残疾人,Win10不希望在开始菜单发现卸载程序和帮助文件的快捷方式,我们可以解除勾选第三个选项。如果你有写网站的话,你可以勾选第二项。
下一步:
可以设置安装完成后自动运行程序,实际上它会给用户一个勾选框,征求用户的意见。
如果你的程序是带参数运行的,那么,可以加入参数(就是在cmd运行时的给定的参数),自述文件就是ReadMe.txt之类的文件,如果你在程序目录下写了自述文件,会打开它,同样也会征求用户意见。
再下一步:
这一步可以设置解除安装程序,可以设定卸载时你对用户说的话,解除安装的方式有两种,如果你的NSIS没有日志记录功能,下面会提示你不能使用安全方式,一般来说不移动安装目录的情况下选择简易模式就够了,安全模式会多出一些复杂的代码。
之后我们就完成了:
转换文件路径为相对路径视自己需要设置。
单纯的靠向导制作安装包是不够的,更为强大的内容在于脚本。
我们经过向导的制作,已经生成了一个脚本,接下来我们来比较一下脚本和我们刚才进行的向导。这里的示例是一个测试包,以下是生成的代码:
#该脚本使用 HM VNISEdit 脚本编辑器向导产生 #安装程序初始定义常量 !define PRODUCT_NAME "测试包" !define PRODUCT_VERSION "1.0" !define PRODUCT_PUBLISHER "My company, Inc." !define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" !define PRODUCT_UNINST_ROOT_KEY "HKLM" !define PRODUCT_STARTMENU_REGVAL "NSIS:StartMenuDir" SetCompressor /SOLID lzma #------ MUI 现代界面定义 (1.67 版本以上兼容) ------ !include "MUI.nsh" #MUI 预定义常量 !define MUI_ABORTWARNING !define MUI_ICON "H:\编程\素材\文件处理器.ico" !define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico" #语言选择窗口常量设置 !define MUI_LANGDLL_REGISTRY_ROOT "${PRODUCT_UNINST_ROOT_KEY}" !define MUI_LANGDLL_REGISTRY_KEY "${PRODUCT_UNINST_KEY}" !define MUI_LANGDLL_REGISTRY_VALUENAME "NSIS:Language" #欢迎页面 !insertmacro MUI_PAGE_WELCOME #许可协议页面 !define MUI_LICENSEPAGE_CHECKBOX !insertmacro MUI_PAGE_LICENSE "H:\编程\素材\licence_English.txt" #组件选择页面 !insertmacro MUI_PAGE_COMPONENTS #安装目录选择页面 !insertmacro MUI_PAGE_DIRECTORY #开始菜单设置页面 var ICONS_GROUP !define MUI_STARTMENUPAGE_NODISABLE !define MUI_STARTMENUPAGE_DEFAULTFOLDER "测试包开始菜单" !define MUI_STARTMENUPAGE_REGISTRY_ROOT "${PRODUCT_UNINST_ROOT_KEY}" !define MUI_STARTMENUPAGE_REGISTRY_KEY "${PRODUCT_UNINST_KEY}" !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "${PRODUCT_STARTMENU_REGVAL}" !insertmacro MUI_PAGE_STARTMENU Application $ICONS_GROUP #安装过程页面 !insertmacro MUI_PAGE_INSTFILES #安装完成页面 !define MUI_FINISHPAGE_RUN "$INSTDIR\test.exe" !define MUI_FINISHPAGE_SHOWREADME "$INSTDIR\使用方法.txt" !insertmacro MUI_PAGE_FINISH #安装卸载过程页面 !insertmacro MUI_UNPAGE_INSTFILES #安装界面包含的语言设置 !insertmacro MUI_LANGUAGE "English" !insertmacro MUI_LANGUAGE "TradChinese" !insertmacro MUI_LANGUAGE "French" !insertmacro MUI_LANGUAGE "SimpChinese" !insertmacro MUI_LANGUAGE "Korean" !insertmacro MUI_LANGUAGE "Thai" !insertmacro MUI_LANGUAGE "German" !insertmacro MUI_LANGUAGE "Greek" !insertmacro MUI_LANGUAGE "Russian" !insertmacro MUI_LANGUAGE "Italian" !insertmacro MUI_LANGUAGE "Afrikaans" !insertmacro MUI_LANGUAGE "Portuguese" !insertmacro MUI_LANGUAGE "SpanishInternational" !insertmacro MUI_LANGUAGE "Japanese" #安装预释放文件 !insertmacro MUI_RESERVEFILE_LANGDLL !insertmacro MUI_RESERVEFILE_INSTALLOPTIONS #------ MUI 现代界面定义结束 ------ Name "${PRODUCT_NAME} ${PRODUCT_VERSION}" OutFile "Setup.exe" InstallDir "$PROGRAMFILES\测试包" ShowInstDetails show ShowUnInstDetails show BrandingText "安装程序" Section "HxDTool主模块" SEC01 SetOutPath "$INSTDIR" SetOverwrite ifnewer File /r "H:\HxDTool\*.*" #创建开始菜单快捷方式 !insertmacro MUI_STARTMENU_WRITE_BEGIN Application CreateShortCut "$DESKTOP\测试包.lnk" "$INSTDIR\test.exe" !insertmacro MUI_STARTMENU_WRITE_END SectionEnd Section -AdditionalIcons !insertmacro MUI_STARTMENU_WRITE_BEGIN Application CreateDirectory "$SMPROGRAMS\$ICONS_GROUP" CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\Uninstall.lnk" "$INSTDIR\uninst.exe" !insertmacro MUI_STARTMENU_WRITE_END SectionEnd Section -Post WriteUninstaller "$INSTDIR\uninst.exe" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninst.exe" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}" SectionEnd #-- 根据 NSIS 脚本编辑规则,所有 Function 区段必须放置在 Section 区段之后编写,以避免安装程序出现未可预知的问题。-- #区段组件描述 !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN !insertmacro MUI_DESCRIPTION_TEXT ${SEC01} "HxDTool" !insertmacro MUI_FUNCTION_DESCRIPTION_END Function .onInit !insertmacro MUI_LANGDLL_DISPLAY FunctionEnd #以下是安装程序的卸载部分 Section Uninstall !insertmacro MUI_STARTMENU_GETFOLDER "Application" $ICONS_GROUP Delete "$INSTDIR\uninst.exe" Delete "$SMPROGRAMS\$ICONS_GROUP\Uninstall.lnk" Delete "$DESKTOP\测试包.lnk" RMDir "$SMPROGRAMS\$ICONS_GROUP" RMDir "$INSTDIR" DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" SetAutoClose true SectionEnd #-- 根据 NSIS 脚本编辑规则,所有 Function 区段必须放置在 Section 区段之后编写,以避免安装程序出现未可预知的问题。--# Function un.onInit !insertmacro MUI_UNGETLANGUAGE MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "您确实要完全移除 $(^Name) ,及其所有的组件?" IDYES +2 Abort FunctionEnd Function un.onUninstSuccess HideWindow MessageBox MB_ICONINFORMATION|MB_OK "$(^Name) 已成功地从您的计算机移除。" FunctionEnd
在这里为了方便大家识别,我这里使用了其他编程语言来高亮这些文字。我们翻译一下这些简单的英语单词就能知道它的含义。
我们需要注意每行的第一个单词,它们在VNISEdit中高亮为蓝色,这些就相当于一个封装好的函数,可以直接使用,而且不需要我们在意太多的压缩和解压细节。
函数 | 意义 |
---|---|
Section | 最基础的函数,表示一个部门,用来代表一个需要安装的组件,Section中的内容是整个程序除了卸载以外最后执行的部分,但是编译时会第一个检查,如果程序中没有任何Section或Function,将会终止编译,Section内的代码块需要缩进2空格 |
Function | 执行的函数,同样需要缩进,它的函数名会被识别,如果识别为特殊名称,将会在特定情况下进行,下面还会讲解 |
SectionEnd | 表示部门结束,不缩进于Section内部 |
FunctionEnd | 表示函数结束,同上 |
SetCompressor | 设置压缩算法,后面可用的参数就是向导中的压缩算法,固实的用/SOLID作为前缀,例:固实lzma算法记作/SOLID lzma |
SetCompressor | 设置压缩分卷大小,后接一个数字,通常不写是没关系的 |
OutFile | 决定编译好的安装包的路径(是指未来的安装包的路径,而不是放在哪个文件夹) |
Name | 设置产品的名称,通常是向导第一步中写的应用程序名称+应用版本 |
InstallDir | 表示默认的安装路径,即向导第四步第一行填入的内容,决定了$INSTDIR的值 |
ShowInstDetails | 表示是否显示安装细节,参数不是简单的true和false,而是show,hide和nevershow,分别表示自动显示细节、用户按键显示细节、不允许看到安装细节 |
ShowUnInstDetails | 表示是否显示卸载细节,参数同上 |
BrandingText | 显示安装包下沿的信息,即向导第一步最后一行自定义文本,可以接受两个参数,一个是要显示的文字,还有可选参数是/TRIM,可以决定文字对齐方向(LEFT,RIGHT或者CENTER,默认为LEFT,必须写作/TRIMLEFT、/TRIMRIGHT或/TRIMCENTER,中间没有任何分隔) |
SetOutPath | 只能写在Section中第一行,决定了所属Section表示的组件的安装位置,不同于InstallDir,SetOutPath可以让不同的组件安装在总安装目录的不同子目录下,建议设置为$INSTDIR\组件名称的文件夹(或者如果组件互相依赖,可以另行调整组件路径) |
SetOverWrite | 只能写在Section中,用来设置已安装时是否覆盖,参数可以设置为始终覆盖(on),始终不覆盖(off),较新时覆盖(ifnewer),文件内容不同时覆盖(ifdiff)和尝试覆盖(try),对应向导第五步>编辑目录项目 |
File | 只能写在Section中,表示该Section包含并打包的文件,/r转义参数代表包含子目录的文件和文件夹,对应的向导步骤同上;/x参数用来排除文件,可以写/x “*.ico” “xxx\*”,分别表示排除ico文件和排除xxx子目录下的所有文件,对应向导第五步 |
CreateDictionary | 创建一个文件夹,后面加上的是文件夹的完整路径或相对路径 |
CreateShortcut | 创建一个快捷方式,第一个是快捷方式的路径(后缀.lnk),第二个是快捷方式指向文件的路径,对应向导第六步下面部分 |
WriteUninstaller | 创建解除安装程序,后面接卸载程序的路径名 |
WriteRegStr | 写入注册表,这一般不需要进行更改,按照向导生成的就行了 |
Delete | 通常在卸载Section中,删除单个文件,后接删除的文件的路径,由于删除的是单个文件,所以不能加/r |
RMDir | 通常在卸载Section中,删除目录和目录下的所有文件,后接删除的目录的路径,前面一般需要手动加上转义/r,向导没给你加,不加会卸载残留,最好每个子目录写一次这个指令,都要加上/r,最后移除总目录RMDir “$INSTDIR” |
DeleteRegKey | 删除注册表信息,一般按照向导生成就行了 |
SetAutoClose | 只能写在Section中,表示安装完成之后是否自动跳到完成界面,参数为true和false |
AutoCloseWindow | 似乎并没有什么作用,功能看似和上一个是相同的,但是可以写在Section以外,参数同上 |
Messagebox | 消息框,只能写在Section或Function中,参数有很多,包括显示信息、显示警告、问yes no,问okcancelretry等,VNISEdit中输入Messagebox可以获得全部参数列表,后面再接消息框显示的内容 |
Abort | 阻塞,等待用户回答 |
HideWindow | 隐藏窗口,通常用于卸载Section中,卸载程序先删除自己,再删除其他文件(没错,程序还在运行),删除了之后要自动关掉窗口 |
我们点击编译运行,如果你不需要协议部分,你在向导应该填写一个不存在的路径,然后让它编译报错,找到license界面的部分,把它删掉:
通常要删掉一行到两行,根据不同的同意协议的方式,有不同的行数,你只要根据上面的注释删除相应的部分代码,就比如说这个是点击古典按钮的方式同意协议并进入下一步,所以只有一行。
按照我给的网址下载下来的VNISEdit会自动写上语言选择界面的,但是单独下载VNISEdit编出来的可能不会自动添加,导致安装包不能选择语言,对于打包安装包之后不能显示选择语言界面的,我们可以看到,刚才的那张图片,在欢迎界面的上方,就定义了语言选择界面的窗口,把那三行抄下来,放在欢迎界面前面就可以实现:
#语言选择窗口常量设置
!define MUI_LANGDLL_REGISTRY_ROOT "${PRODUCT_UNINST_ROOT_KEY}"
!define MUI_LANGDLL_REGISTRY_KEY "${PRODUCT_UNINST_KEY}"
!define MUI_LANGDLL_REGISTRY_VALUENAME "NSIS:Language"
这样我们就实现了多语言安装包。
我们需要注意的是,如果你没有用管理员模式运行VNISEdit的话,Win10一般“编译并运行”会报这个错误:
但是这不影响编译,编译是成功的,我们可以自己到输出目录去找,然后手动运行,如果用管理员模式运行就能够支持自动运行安装包,通常这个错误没有大问题。
再给大家附上Messagebox的参数列表:
后面还有一个MB_YESNOCANCEL,这上面看不到。
那么今天为大家的讲解就到这里结束了,遇到任何问题大家可以在评论区留言,拓宽大家的视野。
本文为作者原创,未经作者允许,禁止转载。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。