一般下载文件我们使用 NSIS Inetc插件。官网文档:https://nsis.sourceforge.io/Inetc_plug-in
但是此插件并没有下载进度等信息,此文将讨论如何实现 NSIS制作在线安装包。
By the way,在研究学习过程中我发现了 Installer Studio 这个打包软件,非常好,忍不住要说一下。在线安装包大小只有2MB,断点续传重试啥都有,支持任何类型的应用打包。1分钟即可完成软件打包。支持离线/在线/静默安装包的制作,基于近百个模板快速构建高质量安装包,支持自定义注册表,环境变量,快捷方式以及Java,.Net等环境的安装。也支持国际化,非常契合我们产品出海的诉求。
官网地址:https://installerstudio.online
言归正传,以下是一个使用 NSIS(Nullsoft Scriptable Install System)脚本来实现下载文件的基本示例代码,它可以在安装程序制作过程中完成从指定网址下载文件到本地的功能,这里假设你要从某个网络地址下载一个文件到本地指定目录。
我们以下载 .NET Framework 为例
; 引入必要的NSIS库文件,LogicLib.nsh用于一些逻辑处理相关的辅助,inetc.nsh用于支持InetC下载插件
!include "LogicLib.nsh"
!include "inetc.nsh"
; 设置安装程序的基本信息
Name "MyDownloader"
OutFile "MyDownloader.exe"
InstallDir "$PROGRAMFILES\DownloadedFiles"
; 页面相关设置,这里简单设置了选择安装目录页面和显示安装进度页面
Page directory
Page instfiles
; 定义变量来存储远程下载文件的URL地址以及本地保存的文件路径
Var URL
Var LocalFile
Function.onInit
; 给URL变量赋值为要下载文件的具体网址,此处替换为你指定的Visual Studio文件下载链接
StrCpy $URL "https://download.visualstudio.microsoft.com/download/pr/014120d7-d689-4305-befd-3cb711108212/0fd66638cde16859462a6243a4629a50/ndp48-x86-x64-allos-enu.exe"
; 设置本地保存文件的路径,这里将文件保存到安装目录下,文件名保持和远程文件一致,你可按需调整
StrCpy $LocalFile "$INSTDIR\ndp48-x86-x64-allos-enu.exe"
FunctionEnd
Function DownloadFile
; 使用InetC插件开始下载文件,传递远程URL和本地保存路径作为参数
InetC::get $URL $LocalFile
Pop $0
; 根据返回值判断下载是否成功,返回值为0表示成功,非0表示失败
${If} $0!= 0
MessageBox MB_OK "文件下载失败,请检查网络连接或文件地址是否正确!"
${Else}
MessageBox MB_OK "文件下载成功!已保存至 $LocalFile"
${EndIf}
FunctionEnd
Function.onInstSuccess
; 在安装成功这个阶段调用下载文件的函数,你可以根据需求调整调用时机
Call DownloadFile
FunctionEnd
Section
; 此处可添加其他安装相关操作,比如解压下载后的文件等,当前示例暂未添加其他操作
SectionEnd
但是官方插件没有进度回调怎么办,当我们使用自定义界面制作安装包时,遇到下载文件较大或网络不稳定的情况下,应当向用户展示下载文件的进度信息,增加用户体验。
我们基于 NSIS Inetc插件 扩展来实现进度回调
扩展后的插件
扩展后的插件,提供传入一个回调函数,通过回调函数,可以获取到当前下载的进度信息,提供如下信息:
- 当前进度(百分比)
- 累计大小
- 已下载大小
- 下载速度
- 剩余时间(秒)
插件源码
github:https://github.com/zhaobangyu/NSIS/tree/PluginCode
使用示例代码
可以根据需要实现断网重试以及断点续传来实现在线安装包
#Net包下载地址
!define NET_PACK_DL_URL "https://download.visualstudio.microsoft.com/download/pr/014120d7-d689-4305-befd-3cb711108212/0fd66638cde16859462a6243a4629a50/ndp48-x86-x64-allos-enu.exe"
#Net包名称
!define NET_PACK_NAME "ndp48-x86-x64-allos-enu.exe"
; Net安装包下载回调
Function NetPackDownLoadCallBack
; 0-当前进度(百分比)
Pop $0
; 1-累计大小
Pop $1
; 2-已下载大小
Pop $2
; 3-下载速度
Pop $3
; 4-剩余时间
Pop $4
FunctionEnd
;下载 .NET Framework 4.0
Function DownloadNetFramework4
GetFunctionAddress $R9 NetPackDownLoadCallBack
inetc::get "${NET_PACK_DL_URL}" "$TEMP\${NET_PACK_NAME}" $R9
; 读取值
Pop $1
; 写入值
Push $1
FunctionEnd