为什么要制作安装包,是产品需求,还是让应用安装更简单?本文将结合一些流行的安装包制作工具和自定义方法,为你提供完整的参考。并就windows上经常遇到的exe依赖dll丢失问题,提供详尽的问题场景和解决思路,帮助你更顺利的制作安装包。
如果你只是想要简单的制作安装包,对于细节不是非常在意,Setup Factory就能帮你快速的把安装包制作出来。当然,也有InstallShield、NextInstaller这种用脚本控制安装流程的“工具”。
Setup Factory 是一个强大的安装程序制作工具。提供了安装制作向导界面,即使你对安装制作不了解,也可以生成专业性质的安装程序。可建立快捷方式,也可直接在 Windows 系统的注册表加入内容,还能在 Win.ini 和 System.ini 内加入设定值,更可以建立反安装选项等等。它内附的向导可以一步步的带领您做出漂亮又专业的安装程序。
更详尽的使用参考链接:https://www.cnblogs.com/lidabo/p/9809757.html
NextInstaller是一个简单的安装包制作工具. 支持windows系统的安装包制作,可注册动态库,支持安装到不同路径,支持数据库升级。有别于Setup Factory,NextInstaller使用Atscript语言(而非可视化交互)作为安装控制脚本,详细的脚本语言介绍就不在这里赘述。关于NextInstaller的使用原理,可以参考下面NextInstaller的事件控制方式流程图:
安装过程控制
反安装过程控制
Installshield是一个强大和易于使用,用于解决Windows软件安装包开发的制作工具。用它可以以传统MSI方式和虚拟格式,自动化地封装、捆绑和包装你的产品。Installshield是Microsoft Windows平台上应用程序安装打包领域,使用最广泛和市场认可度最高的一款安装打包工具软件,支持Windows(客户版本及服务器版本),Web服务和移动设备。InstallShield使用InstallScript作为安装控制脚本,同样,相关介绍就不赘述了。
为了更好的定制安装包,在实际项目中我们使用了MFC来开发安装、卸载程序。定制包括两方面,UI和安装流程。UI对于不同项目,可能差异较大,安装流程却是业界通用的。在这里,我简单介绍下一般定制安装包需要实现哪些核心步骤,及其负责的功能。
单实例判断: 如果已有安装程序在运行,需要将焦点转到该实例,并关闭自身。
管理员权限判断: 在XP系统上,需要判断是否有管理员权限,才能执行安装逻辑。
检查当前版本: 一般,如果已经安装了更高版本的应用程序就给予提示,并不需要继续执行安装逻辑。
解压安装文件: 一般,应用程序会用压缩工具进行压缩,相应的,在安装开始前,需要先把压缩包解压出来到一个临时目录。这个阶段解压出来的文件,包括应用程序压缩包、卸载程序、驱动文件等。并且,需要先检查临时路径的剩余空间,判断临时路径磁盘剩余空间是否足以安装应用程序。
初始化安装目录: 创建安装目录。
关闭相关程序: 需要考虑是否已有安装相同程序,且正在运行,为了避免某些正在使用的文件受安装过程影响,或是其它原因,一般需要关闭相同程序。
启动异步线程: 一般安装程序得允许用户安装过程中退出,因此需要创建一个异步线程来实现核心逻辑,避免阻塞UI。
解压应用及依赖项: 顾名思义,有别于前边的解压安装文件,这里解压的是真正运行的exe及其依赖项所在压缩包。
读取配置文件: 需要从配置文件中读取包括诸如应用程序名称、桌面快捷方式名称等信息。
拷贝应用程序: 一般平台可能有多种版本,比如windows有32位、64位、XP,每种“版本”对应的应用exe是不同的。拷贝程序,需要根据当前系统“版本”选择性的拷贝应用程序及依赖项。
安装驱动: 某些特定系统版本,比如XP会要求安装特定驱动才能正常运行应用程序。
创建快捷方式: 比如桌面快捷方式、工具栏、windows主窗口等。
创建注册表信息: 注册表信息,包括开机启动项、卸载快捷方式信息。
删除临时文件: 安装完适应于当前系统版本的应用程序及依赖项之后,其它文件(比如适应于其它系统版本的应用程序)就可以删除了。
回滚操作: 安装程序需要考虑到因为打包阶段遗漏依赖项、异常中止等情况,如果安装流程某个阶段被打断了,但不做任何处理的话就会出现注册表异常、程序无法再安装、无法正常卸载等情况。针对这类问题,在安装流程中,我们往往需要针对特定流程,实现特定的回滚方法。比较重要的回滚操作,包括
显示进度: 给用户显示当前安装进度,有助于提高用户体验。一般我们需要在安装流程的各个阶段,自己定义当前进度和阶段提示文本。
相信大家按照我介绍的流程、操作去实现,就能制作出一个非常完善的安装程序。
windows上的应用为了避免exe过大,会使用动态库dll。也许我们要负责制作安装包的程序,来自多个小组同事之手,各个模块依赖的dll及其兼容的系统版本也不一样。有些时候,可能需要我们自己查找exe依赖的dll,一般有哪些方法呢?
有些情况下,windows上运行exe如果缺少依赖的dll,系统就会明确提示缺少的dll名称,这时候直接去对应项目找到dll拷贝过去就行了。
不过需要注意同样名称的dll,不同系统版本、不同编译器版本编译的都不同,如果搞错了版本,可能就会提示如下错误。
这种情况你就耐心点在项目里(如果是自研项目)搜下接口名称,应该能找到依赖的是什么dll。那如果是第三方的,上相关网站论坛也能收到。事实上,绝大多数时候遇到的会是如下令人头疼的提示:
关于这个系统提示,如果你并非相当熟悉应用依赖项的人,基本上无法直接锁定缺少的那个dll(或者那批dll)。
Dependency Walker是一个免费的实用工具,它可以扫描任何32位/64位Windows模块(exe,dll,ocx,sys等),并建立所有相关模块的分层树形图。Dependency Walker对于排除加载和执行模块故障错误非常有用。Dependency Walker能检测出许多常见应用问题,例如缺少模块,无效的模块,导入/导出不匹配,循环依赖错误,不匹配的机器类型模块和模块初始化失败。Dependency Walker下载链接:http://www.dependencywalker.com/
Dependency Walker下载解压后就三个文件:
直接运行depends.exe即可使用。要检查某个exe(或dll),直接将exe拖入主界面即可,如果exe较大可能会卡一会儿,需要耐心等待(不是软件bug)。
上图,左边窗口树状图里面,表示MapNetHDD.exe的依赖关系,它依赖MPR.DLL,MPR.DLL又依赖其它dll。
树状图中标了黄色问号的,就是指缺少这个依赖的dll。
选中树状图中某个dll,右上方窗口(表示引用函数)如果标红,表示这个引用的函数在该dll中已不存在,这就是前面举例的系统提示“无法定位程序输入点xxx”对应的情况。
如果你的应用是Windows上基于Qt开发的应用,一定会需要windeployqt.exe的辅助。windeployqt.exe是Qt自带的工具,用于创建应用程序发布包。这个工具可以自动地将某程序依赖的库、资源拷贝到其所在目录,防止程序在其他电脑上运行报找不到库的错误。我们可以在项目属性的生成后事件中,编辑命令行脚本,使用windeployqt.exe将Qt依赖的所有dll一起打包到指定目录。
注意:1、使用windeployqt.exe得配合应用exe对应的Qt版本,Qt版本一般也是区分32位、64位的,且存在诸多大小版本。如果使用不对应,那么就无法保证拷贝的dll是应用exe依赖的dll。2、另外,windeployqt.exe不会覆盖指定目录下已存在同名dll的情况,如果已存在错误的dll,需要你额外指定清理命令,或者在windeployqt.exe执行命令后面增加 –force
详情可参见官网链接:https://doc.qt.io/qt-5/windows-deployment.html
相信看完本文,你对Windows上怎么制作安装包已经有了一个较为全面的了解,当然,还有更多的工具、方法待你去探索。如遇到Windows上应用的安装问题,欢迎讨论。