在NSIS中实现安装时取消并回滚(1)——现状
如果在Google上搜索”NSIS Cancel Install”会搜索到一些人问过同样的问题。有的从2003年就已经在问这个问题了。奇怪的是NSIS一直没有提供取消安装的内置的支持。在安装页面,所有的按钮都是禁用着的。而且看论坛上开发者的回复,也没有意思要在近期加入这个功能。
但是问题问题要解决的,总不能用NSIS开发到一半,发现不能简单地支持取消安装和自动回滚就不用NSIS开发了。INNO和MSI都是内置地支持取消并回滚的,希望NSIS也能加入这个功能的支持。不过在开发者完成这个功能之前,总要有个临时的解决办法吧。不幸的是,在Google上搜索了很久,也只能找到各式各样的提问,而没有一个像样的回答。
下面总结一下网上现有的资源。
Enable cancel button during install?
Afrow UK回复说:“You'd need to modify nsisunz to use an asynchronous thread and include a cancel flag.”nsisunz是什么?我也不知道,先不管了,继续找。
Red Wine回复说:“No possible to enable the cancel button on page InstFiles pre function, because if you do so, the nsisunz plugin refuses to load the zip file.”好么,连enable the cancel button都不行吗?
Cancelling the installation process as it happens
Darthvader给出了一个这个问题的官方补丁,很好的样子,不过很快就露馅了——太旧了。Kichik回复说:“Abortion isn't the same as the file open problem dialog. Those originate from two different threads. The naive implementation would actually only make it possible to abort in between File commands and not while extracting a big file.”看来不太好办啊。这个Kichik是NSIS的开发者,按他的说法,就算可以Abort,也只能按File指令的个数来取消。也就是说如果你之前用File *.*来压缩文件,现在可以改成有几个文件要打包就写几个File指令,在指令间检测是不是要取消安装。是个办法,不过也太恶心了吧。说像Wizou回复的:“I was just saying that rather than waiting 6+ months for a new "abort" feature fully implemented, that could be nice to start by having a quick implementation that would be already enough to answer the needs of 90% of NSIS users.”最后dmut说他用Multi-volume_Distribution插件把这个功能实现,可是没有具体说如何实现的……
Allow user to cancel during install?
Kichik直截了当地说:“You can't enable the cancel button yet. It was originally planned for v2 but it looks like it will have to wait for 2.1.”好在那是2003的事儿的,现在应该有所改观了吧?还说要在v2.1加入这个功能。现在都2.44了,还没有看见影呢。
How to enable the Cancel Button during install
Cancelling during MUI_PAGE_INSTFILES
这里给出了把INSTFILES页面里的取消按钮Enable的方法,和一个让上面提到的方式实现的取消安装。如果这个能满足需要,就将就着用吧。但是要自己写很多代码的。因为取消安装不是取消了就完事儿了,安装过的东西可是要删除干净的,就像是从来没有运行过这个安装程序一样。不过现在的安装包大多数基本上做不到这一点,还要用户给它擦屁股。
HOW to enable a cancel button on a uninstall MUI Page
可怜的人。没有人回答……
Problem with the UMUI cancel button not stopping the install process properly
不按NSIS的规矩做事,总是要还的。Cancel按钮可以启用,但是当对话框弹出来问用户是不是真的要Cancel的时候,后面的过程还在继续,要是用户点得慢点,没等点OK,安装就已经结束了!开发者这个汗啊。
这些只是网友提问的一部分,记得还有一个帖子给出了开启取消按钮的全部代码。也是遇到了和上面最后一个帖子一样的问题。不过那个帖子死活搜索不到了。
不知道NSIS的作者在研究什么高深的功能,需求这么广泛的取消功能,而且是两个竞争者都已经实现了的功能,却经历了6年时间还没有做出来。
笔者所在项目也是遇到了这样的问题。需求要有取消安装的功能,我们做了,但是后台的安装线程停不下来。上一篇制作NSIS命令行窗口输出插件中我们看到了如何制作一个插件,由于插件是用C++写的,所以理论上可以在里面做任何想做的事情。下一篇中,我们就将实现一个线程控制的插件。用插件把后台的安装线程停下来,为实现取消安装功能做准备。