NSIS 应用过程的坑

最近在工作中使用NSIS脚本维护现有的软件安装包,使用NSIS制作安装包,简单快捷,对于任何一个有编程经验的程序员来说都是非常容易上手的工具之一,灵活强大,官方文档是非常好的学习资料,但是很多在实际应用过程中的坑并没有记录在册,故写一篇博客记录开发过程中遇到的坑和经验。

版本

NSIS Unicode 版本号?

下面总结遇到的坑和建议

使用插件

使用插件之前一定要搞清楚插件是不是支持Unicode版本,网上有很国内多资源平台提供NSIS插件合集的下载,并非官方网站正规渠道,插件合计的提供者有时忽略记录插件对应NSIS版本信息。我就遇到这样一个情况,下载NSIS插件之后在正常版本(非Unicode版)下使用,但是在Unicode版本下无效。此处不对Unicode与ANSI做详细的介绍,如果不清楚可以自己百度。
建议:通过官方网站提供插件地址下载所需的插件。

语法:行跳转

NSIS使用StrCmp比较两个字符串的大小

函数原型:

跳转在NSIS脚本是比较常见的一种逻辑判断结果验证方式,相比于标签的方式容易出错,代码维护过程中容易遗忘。比如像在某一个逻辑段中使用DetailPrint打印一条日志消息,添加1行造成之前的跳转目标行减少1行,稍不留神就会出现bug
建议:1.使用跳转标签的方法代替goto跳转至某一行;2.使用???Logic.nsh???模块的${If}...${Else}...${endIf}方式进行逻辑处理。

cmd指令

cmd传参注意事项

命令行传参是注意.exe的路径必须使用""括起来,否则根据cmd的语法遇到空格时自动截取参数,传递参数无效导致命令执行失败,例如安装目录在默认系统目录C:\Program Files (x86),传参时不使用双引号,会出现要执行命令。
常用的执行命令行指令有:ExecWait, nsExec:Exec
建议:推荐使用nsExec:Exec,提供扩展参数。

sc指令操作服务

nsExec执行命令行指令虽然有/TIMEOUT=1000参数来设置超时时间,实际上sc指令在cmd中是一个异步指令,在执行sc stop ServiceName后实际上是给windows的服务管理工具发送停止ServiceName服务的消息,并立即返回。如果执行sc stop之后立即执行删除ServiceName服务的exe程序,实际上很多时候是无法删除的。
建议:每次执行sc指令操作服务后,使用Sleep 100睡眠一段时间,确保服务操作已经完成后继续执行后续指令。

taskkill指令失效

taskkill作为windows 提供的结束应用程序指令用来杀死正在运行中的进程,在一些特定操作系统环境下会出现无效的情况(即使使用cmd调用也无法成功删除进程),使用nsExec调用taskkill时超时时间参数/TIMEOUT一定不能设置时间过长。在工作中就遇到类似的情况,使用nsExec:Exec /TIMEOUT=60000 taskkill /F /IM test.exe杀死进程时出现taskkill无效的情况,安装过程等待指令超时60s,进度条长时间停在一个位置,被认为是安装包“卡死”,实际是因为超时时间设置过长导致。

杀死指定名称的进程:taskkill /F /IM process_name.exe

解决方案:使用NSIS插件结束运行中的进程KillProcess;或自定义插件封装TerminateProcess(windows API)结束进程。

根据安装日志卸载

实现脚本

官方提供日志内容删除安装的文件(包括释放文件、创建快捷方式),但是根据日志删除文件无法删除创建目录,删除目录需要自己实现。

同名目录升级安装

升级安装过程中,首先要卸载旧版本,考虑到新旧版本的兼容性问题,一般做法是检测到旧版本时调用卸载程序,卸载完成后执行安装脚本内容。
删除的调用过程无非是静默调用之前的卸载程序,

删除文件夹RMDIR

很多时候在编写脚本的过程中习惯使用RMDIR /r删除一个文件夹,有误/r参数差别很大,RMDIR只能删除非空文件夹,而/r参数则是删除文件夹及文件夹下的所有文件。故/r参数必须慎重使用,一旦出现传参失误,就会导致整个目录被波及。

工作中曾经有一个真实的“事故”。使用RMDIR /r删除安装过程中创建的快捷方式,一个bug出现传参时删除目录参数为空,导致开始菜单被清空,在用户的机器上出现上述结果,造成极大的影响。

建议:RMDIR慎用/r参数,必须保证参数传递正确。

文件重启后丢失(/REBOOT标记)

NSIS对于文件操作的函数Rename,Delete,RMDIR等提供扩展参数/REBOOT,此标记应用于操作文件被占用无法删除、或者目录无法删除时被标记为重启删除。
在相同安装目录覆盖升级安装过程中会出现文件在卸载时被占用,并标记为/REBOOT状态,同名文件无法成功替换,本次安装完成后一切正常,但是用户重启机器后文件被删除,出现部分文件或应用缺少文件无法启动的“诡异”情况。

同步等待静默卸载

静默卸载函数原型:

同步等待静默卸载结果时必须添加_?=制定路径参数,否则NSIS会创建临时的卸载程序副本到临时目录异步执行卸载过程,立即返回。

总结经验

版本比较

C++开发NSIS插件

根据NSIS安装目录下Example/Plugin目录提供的Demo,引用相关的静态库即可。

功能集锦

打开关闭日志(logset)

logset on/off 用于打开和关闭NSIS的默认日志输出功能。
打开日志后,DetailPrint输出的内容不仅会显示在默认安装界面的详细信息列表中,同时也会写入install.log文件;LogText只是输出日志。

参考资料

[1] NSIS学习笔记(二)-使用C++开发NSIS插件
http://blog.csdn.net/lee353086/article/details/46349157

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
NSIS是一种流行的开源脚本驱动的安装系统,它被广泛用于Windows操作系统上的软件安装程序的制作。NSIS资源(NSIS Resources)是指在NSIS安装脚本中使用的一些文件和组件,以提供更丰富和个性化的安装体验。 NSIS资源主要包括以下几种类型: 1. 图像文件:可以使用NSIS资源来包含软件安装过程中所需的图标、背景图片等文件,以增加安装界面的美观性和可视化效果。 2. 声音文件:NSIS资源可以用于嵌入音频文件,例如添加欢迎语音、按钮点击音效等,从而使用户在安装过程中得到更直观的反馈和体验。 3. 数据库文件:在某些需要数据库支持的软件安装过程中,NSIS资源可以用于嵌入数据库文件,确保在安装过程中正确地创建和配置数据库。 4. 外部插件:NSIS本身提供了一些基础功能和命令,但有时候我们还需要使用第三方插件来扩展NSIS的功能。NSIS资源可以用于嵌入这些外部插件的二进制文件,以方便在安装过程中调用插件函数。 5. 文本文件:NSIS资源还可以用于包含一些文本文件,如许可协议、帮助文档等,供用户阅读。 使用NSIS资源可以使安装程序更易于用户使用和个性化定制,同时也方便开发者在NSIS脚本中调用这些资源进行相应操作。这些资源文件可以通过NSIS的命令和函数进行访问和使用,从而实现安装过程的各种需求。总之,NSIS资源为开发者提供了丰富的选项,使他们能够更好地控制和定制软件的安装过程

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值