在一些安裝場景中,由于完整的安裝包很大,下載下傳時間長,且下載下傳後需要人工幹預來進行安裝,這樣會一定程度的降低使用者使用體驗;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往往能讓客戶對所安裝産品的印象更加深刻,更能展現出軟體服務商在使用者體驗上的專注與用心!希望我們的努力,能夠讓安裝包制作再容易一點,再快樂一點!
願天下沒有難做的安裝包!