在一些安装场景中,由于完整的安装包很大,下载时间长,且下载后需要人工干预来进行安装,这样会一定程度的降低用户使用体验;nsNiuniuSkin安装包制作解决方案提供了一种在线版本的安装包,支持将实际要安装的内容放到服务器上,由安装包程序下载至本地并自动进行安装;制作出来的在线安装包,体积可以控制在1M以内,能够非常方便的进行分发推广。
实现原理
在nsNiuniuSkin安装包制作解决方案中,在线安装的脚本与完整安装的脚本是同一套,区别在于打包编译时指定了宏:INSTALL_DOWNLOAD_7Z(通过bat脚本动态的传入,无需修改脚本);当这个宏被定义时,安装过程中将会插入下载的过程,下载过程中,我们将显示安装文件总大小,文件下载速度,下载完成百分比等信息,通过进度条来体现下载进度;同时在下载安装后,对下载的文件进行解压,并提供安装进度,无缝的衔接好下载与安装的两个流程。
值得一提的是,我们所下载的程序是一个7z文件(它是由所有待安装文件列表(即:FilesToInstall目录下所有文件)经过7z压缩而得到),在安装程序下载至本地后,通过nsis7zU插件解压来进行安装。
!ifdef INSTALL_DOWNLOAD_7Z
#在线安装包
nsNiuniuSkin::SetControlAttribute $hInstallDlg "slrProgress" "value" "0"
nsNiuniuSkin::SetControlAttribute $hInstallDlg "progress_pos" "text" ""
nsNiuniuSkin::SetControlAttribute $hInstallDlg "progress_tip" "text" "[msg.downloading]"
#开始下载在线数据包
GetFunctionAddress $0 DownloadFile
BgWorker::CallAndWait
Pop $R4
#取回下载的结果,判断是否下载成功且校验通过
${If} "$R4" != "0"
Pop $R5
StrCpy $R5 "[msg.downloadfailed]: $R5"
nsNiuniuSkin::SetControlAttribute $hInstallDlg "progress_tip" "text" "$R5"
nsNiuniuSkin::SetControlAttribute $hInstallDlg "progress_tip" "textcolor" "#fff43a3a"
nsNiuniuSkin::SetControlAttribute $hInstallDlg "btnClose" "enabled" "true"
StrCpy $InstallState "2"
goto InstallAbort
${EndIf}
!endif
#重置进度条,开始进行安装
nsNiuniuSkin::SetControlAttribute $hInstallDlg "slrProgress" "value" "0"
nsNiuniuSkin::SetControlAttribute $hInstallDlg "progress_pos" "text" ""
nsNiuniuSkin::SetControlAttribute $hInstallDlg "progress_tip" "text" "[msg.installing]"
#启动一个低优先级的后台线程
GetFunctionAddress $0 ExtractFunc
BgWorker::CallAndWait
前提条件
所谓在线安装,就是要从服务器上下载实际的数据包来进行安装,那么这里必需要有一个服务器,支持http或https下载即可。
由于在线安装文件的下载可能因为种种原因出现错误,所以我们会在下载完成后,对文件的md5以及大小进行校验,以避免文件下载缺失或错误,所以在真正下载7z文件前,我们需要先下载一个配置文件,用于标识软件包的名称、大小以及md5值(后续具体配置体现,也可以不校验)。
在下载过程中,我们分成了如下几步:
- 下载config.ini
- 根据config.ini中指定的文件名称进行文件下载,并实时的显示进度
- 下载到文件后,取文件大小以及md5值,与配置文件中的值进行校验,如果不正确,则报错;如果正确,再进一步对文件进行解压安装
假设此处的服务器上用于存放config.ini和app.7z的url路径为:http://www.ggniu.cn/test_online_install/ 那么我们接下来要将生成的文件上传到 http://www.ggniu.cn/test_online_install/ 对应的服务器目录下。
实际应用
为了使在线安装包的体积尽可能小,我们并没有将卸载程序直接打包到安装包中,而是将其打包进数据文件app.7z中;有了服务器环境,接下来我们开始实际打包,在线安装包的打包过程中,我们会做以下几件事:
- 自动生成uninst.exe文件,复制到FilesToInstall目录下
- 将FilesToInstall下的文件(包含uninst.exe)打包成app.7z,存放至Output目录下
- 根据app.7z,生成config.ini,其中包含app.7z的大小以及md5值
- 生成不包含uninst.exe以及其他任何待安装文件的在线安装包并签名
打包前的配置准备
在实际打包前,我们需要将前面描述过的服务器url路径配置好,在nsi文件中,有相应的宏来控制在线安装包数据文件的下载路径:
# ====================== 自定义宏 在线安装包控制项=======================
!define INSTALL_DOWNLOAD_BASEURL "http://www.ggniu.cn/test_online_install/"
!define INSTALL_DOWNLOAD_CONFIG "config.ini"
免校验配置 如果在下载过程中,不需要校验安装包的大小和md5值,那么配置如下:
# ====================== 自定义宏 在线安装包控制项=======================
!define INSTALL_DOWNLOAD_BASEURL "http://www.ggniu.cn/test_online_install/"
!define INSTALL_DOWNLOAD_CONFIG "config.ini"
!define INSTALL_DOWNLOAD_IGNOREMD5 0 #如果此开头打开,则不读取配置,不校验MD5,直接下载
!define INSTALL_DOWNLOAD_SERVERFILENAME "app1.7z" #此数据为服务器上的文件名,将追加到BASEURL后下载
!define INSTALL_DOWNLOAD_INITSIZE 80102400 #不校验的情况下的服务器文件大概大小,用于显示进度
配置好后,就可以直接相应的bat脚本(文件名中带online字样的bat脚本),编译生成在线安装包以及在线安装的数据文件包了,只要将数据文件包和配置文件(app.7z与config.ini)上传到服务器指定目录下,整个流程就完成了,接下来可以使用在线安装包来安装了。
注:
在线安装包与数据包并不要求一对一匹配,即两次打包的在线安装包和数据包,均可相互应用;后续要升级在线安装包时,如果界面与下载逻辑不变,那么只需要更新数据包即可!
安装效果
可以看到,打好的在线安装包的体积大概是860KB:
以下是在线安装的完整效果:
更多灵活扩展
目前我们的下载与安装是共用的同一个进度条,即下载进度从1-100%;下载完成后,进度条清零,然后安装进度又从1-100%进行呈现。
如果您希望下载只占用前50%,安装占用后50%的话,只需要在进度回调显示那里进行少量改动即可。
结语
在安装包安装过程中,精美的UI往往能让客户对所安装产品的印象更加深刻,更能体现出软件服务商在用户体验上的专注与用心! 希望我们的努力,能够让安装包制作再容易一点,再快乐一点!
愿天下没有难做的安装包!