1、什么是NSIS
NSIS(Nullsoft Scriptable Install System)是一個開源的 Windows 系統下安裝程序制作程序。它提供了安裝、卸載、系統設置、文件解壓縮等功能。這如其名字所指出的那樣,NSIS 是通過它的腳本語言來描述安裝程序的行為和邏輯的。NSIS 的腳本語言和通常的編程語言有類似的結構和語法,但它是為安裝程序這類應用所設計的。
特點:
—開銷小,一個完整功能的安裝程序僅需要 34k 的額外開銷。
—支持大多數 Windows 平台,包括:Windows 9.x,Windows NT,Windows 2000,Windows XP,Windows 2003
—支持三大壓縮算法:ZLib,BZip2, LZMA
—支持
腳本
—支持多語言
—支持安裝界面定制
—提供可擴展的
插件接口
—支持網絡安裝、
補丁
—支持無人值守的安裝模式
—此外,NSIS的license允許任何用途免費使用。
以上引自: 百度百科
2、我與NSIS的際遇
接觸NSIS是因為工作的需要,因為公司做的項目以winform為主,而winform開發這塊就我一個人負責,程序開發我一個人完成,做出來了,打包怎么辦呢?小公司沒有什么專業弄打包這塊的,所以自己想辦法唄,反正老板只要結果。沒辦法,只好自己硬着頭皮上咯。網上搜了些NSIS的資料,找到了一個學習NSIS打包的一個比較好的博客(地址:輕狂志),也學習到了一些東西。想起自己來博客園兩年了,還從未在博客園上發表過自己的博客文章,所以本着突破自己的心情,也是表示向我的老鄉晴天豬學習的決心,所以發表了此文,借此分享給那些需要的人吧!
3、廢話不多說,直接上源碼
以下是我為我公司打包的一個廣告制作管理軟件的打包源碼,包含mysql數據打包安裝。由於怕別人說我是做廣告來的,所以將公司名字給用XX注釋掉了,打包完整源碼如下:
; 該腳本使用 HM VNISEdit 腳本編輯器向導產生 ; 安裝程序初始定義常量 !define PRODUCT_NAME "XX廣告制作軟件" !define PRODUCT_VERSION "2.2" !define PRODUCT_PUBLISHER "XX.com, Inc." !define PRODUCT_WEB_SITE "http://www.1bsoft.com" !define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\YBest.Ads.exe" !define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" !define PRODUCT_UNINST_ROOT_KEY "HKLM" SetCompressor lzma ; ------ MUI 現代界面定義 (1.67 版本以上兼容) ------ !include "MUI.nsh" !include "WordFunc.nsh" ; MUI 預定義常量 !define MUI_ABORTWARNING !define MUI_ICON "ybkj.ico" !define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico" ; 歡迎頁面 !insertmacro MUI_PAGE_WELCOME ; 許可協議頁面 !insertmacro MUI_PAGE_LICENSE "Readme.txt" ; 安裝目錄選擇頁面 !insertmacro MUI_PAGE_DIRECTORY ; 安裝過程頁面 !insertmacro MUI_PAGE_INSTFILES ; 安裝完成頁面 !define MUI_FINISHPAGE_RUN "$INSTDIR\YBest.Ads.exe" !insertmacro MUI_PAGE_FINISH ; 安裝卸載過程頁面 !insertmacro MUI_UNPAGE_INSTFILES ; 安裝界面包含的語言設置 !insertmacro MUI_LANGUAGE "SimpChinese" ;文件版本聲明 VIProductVersion "2.2.0.0" VIAddVersionKey /LANG=2052 "ProductName" "XX廣告制作軟件" VIAddVersionKey /LANG=2052 "Comments" "軟件版權歸XX軟件所有,他人不得復制或二次開發本程序。" VIAddVersionKey /LANG=2052 "CompanyName" "www.XX.com" VIAddVersionKey /LANG=2052 "LegalTrademarks" "XX軟件" VIAddVersionKey /LANG=2052 "LegalCopyright" "XX.com" VIAddVersionKey /LANG=2052 "FileDescription" "XX廣告制作軟件安裝程序" VIAddVersionKey /LANG=2052 "FileVersion" "2.2.0.0" ; 安裝預釋放文件 !insertmacro MUI_RESERVEFILE_INSTALLOPTIONS ; ------ MUI 現代界面定義結束 ------ Name "${PRODUCT_NAME} ${PRODUCT_VERSION}" OutFile "YBSetup.exe" InstallDir "$PROGRAMFILES\XX廣告制作軟件" InstallDirRegKey HKLM "${PRODUCT_UNINST_KEY}" "UninstallString" ShowInstDetails show ShowUnInstDetails show BrandingText "XX軟件 www.XX.com" DirText "安裝向導將把 $(^NameDA) 安裝在下列文件夾,如果要安裝到其他文件夾請單擊 [瀏覽(B)] 進行選擇。" Section "MainSection" SEC01 SetOutPath "$INSTDIR" SetOverwrite ifnewer CreateDirectory "$SMPROGRAMS\XX廣告制作軟件" CreateShortCut "$SMPROGRAMS\XX廣告制作軟件\XX廣告制作軟件.lnk" "$INSTDIR\YBest.Ads.exe" CreateShortCut "$DESKTOP\XX廣告制作軟件.lnk" "$INSTDIR\YBest.Ads.exe" File "DevComponents.DotNetBar2.dll" File "DevComponents.DotNetBar2.xml" File "LitJSON.dll" File "MySql.Data.dll" File "NPOI.dll" File "ybkj.ico" File "YBest.Ads.exe" File "YBest.Ads.exe.config" File "YBest.BLL.dll" File "YBest.Common.dll" File "YBest.DAL.dll" File "YBest.DBUtility.dll" File "YBest.Model.dll" File "Readme.txt" File "MqttLib.dll" File "PullService.dll" SetOutPath "$INSTDIR\XmlConfig" SetOverwrite ifnewer File /r "XmlConfig\*" SetOutPath "$INSTDIR\images" SetOverwrite ifnewer File /r "images\*" SetOutPath "$INSTDIR\mysql5.1" SetOverwrite ifnewer File /r "mysql5.1\*" ;安裝mysql服務 call installMysql SectionEnd Section -AdditionalIcons WriteIniStr "$INSTDIR\${PRODUCT_NAME}.url" "InternetShortcut" "URL" "${PRODUCT_WEB_SITE}" CreateShortCut "$SMPROGRAMS\XX廣告制作軟件\XX軟件官網.lnk" "$INSTDIR\${PRODUCT_NAME}.url" CreateShortCut "$SMPROGRAMS\XX廣告制作軟件\卸載${PRODUCT_NAME}.lnk" "$INSTDIR\uninst.exe" SectionEnd Section -Post WriteUninstaller "$INSTDIR\uninst.exe" WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\AdsBow.exe" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninst.exe" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\AdsBow.exe" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}" WriteRegDword HKLM "${PRODUCT_DIR_REGKEY}" "Installed" 1 WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "InstalledPath" "$INSTDIR" WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "version" "${PRODUCT_VERSION}" ;寫入版本號 SectionEnd Section -.NET Call GetNetFrameworkVersion Pop $R1 ${If} $R1 < '2.0.50727' SetDetailsPrint textonly DetailPrint "正在安裝 .NET Framework 2.0,這個可能需要幾分鍾,請耐心等待..." SetDetailsPrint listonly SetOutPath "$TEMP" SetOverwrite on File "NetFx20SP2_x86.exe" ExecWait '$TEMP\NetFx20SP2_x86.exe /quiet /norestart' $R1 Delete "$TEMP\NetFx20SP2_x86.exe" ${EndIf} SectionEnd /****************************** * 以下是安裝程序的卸載部分 * ******************************/ Section Uninstall Delete "$INSTDIR\${PRODUCT_NAME}.url" Delete "$INSTDIR\uninst.exe" Delete "$INSTDIR\YBest.Ads.exe" Delete "$INSTDIR\YBest.Ads.exe.config" Delete "$INSTDIR\YBest.BLL.dll" Delete "$INSTDIR\YBest.Common.dll" Delete "$INSTDIR\YBest.DAL.dll" Delete "$INSTDIR\YBest.DBUtility.dll" Delete "$INSTDIR\YBest.Model.dll" Delete "$INSTDIR\DevComponents.DotNetBar2.dll" Delete "$INSTDIR\DevComponents.DotNetBar2.xml" Delete "$INSTDIR\LitJSON.dll" Delete "$INSTDIR\MySql.Data.dll" Delete "$INSTDIR\NPOI.dll" Delete "$INSTDIR\ybkj.ico" Delete "$INSTDIR\Readme.txt" Delete "$INSTDIR\MqttLib.dll" Delete "$INSTDIR\PullService.dll" ;停止mysql服務 並移除服務 call un.removeService ; 循環刪除文件直至刪除文件夾 RMDir /r "$INSTDIR\images" RMDir /r "$INSTDIR\XmlConfig" RMDir /r "$INSTDIR\mysql5.1" Delete "$SMPROGRAMS\XX廣告制作軟件\卸載${PRODUCT_NAME}.lnk" Delete "$SMPROGRAMS\XX廣告制作軟件\XX軟件官網.lnk" Delete "$DESKTOP\XX廣告制作軟件.lnk" Delete "$SMPROGRAMS\XX廣告制作軟件\XX廣告制作軟件.lnk" RMDir "$SMPROGRAMS\XX廣告制作軟件" RMDir "$INSTDIR" DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY}" SetAutoClose true SectionEnd #-- 根據 NSIS 腳本編輯規則,所有 Function 區段必須放置在 Section 區段之后編寫,以避免安裝程序出現未可預知的問題。--# Function GetNetFrameworkVersion ;獲取.Net Framework版本,支持 Push $1 Push $0 ReadRegDWORD $0 HKLM "SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.5" "Install" ReadRegDWORD $1 HKLM "SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.5" "Version" StrCmp $0 1 KnowNetFrameworkVersion +1 ReadRegDWORD $0 HKLM "SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.0\Setup" "InstallSuccess" ReadRegDWORD $1 HKLM "SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.0\Setup" "Version" StrCmp $0 1 KnowNetFrameworkVersion +1 ReadRegDWORD $0 HKLM "SOFTWARE\Microsoft\NET Framework Setup\NDP\v2.0.50727" "Install" ReadRegDWORD $1 HKLM "SOFTWARE\Microsoft\NET Framework Setup\NDP\v2.0.50727" "Version" StrCmp $1 "" +1 +2 StrCpy $1 "2.0.50727.832" StrCmp $0 1 KnowNetFrameworkVersion +1 ReadRegDWORD $0 HKLM "SOFTWARE\Microsoft\NET Framework Setup\NDP\v1.1.4322" "Install" ReadRegDWORD $1 HKLM "SOFTWARE\Microsoft\NET Framework Setup\NDP\v1.1.4322" "Version" StrCmp $1 "" +1 +2 StrCpy $1 "1.1.4322.573" StrCmp $0 1 KnowNetFrameworkVersion +1 ReadRegDWORD $0 HKLM "SOFTWARE\Microsoft\.NETFramework\policy\v1.0" "Install" ReadRegDWORD $1 HKLM "SOFTWARE\Microsoft\.NETFramework\policy\v1.0" "Version" StrCmp $1 "" +1 +2 StrCpy $1 "1.0.3705.0" StrCmp $0 1 KnowNetFrameworkVersion +1 StrCpy $1 "not .NetFramework" KnowNetFrameworkVersion: Pop $0 Exch $1 FunctionEnd ;安裝mysql服務 Function installMysql Push "mysqld.exe" ProcessWork::existsprocess Pop $R0 IntCmp $R0 0 no_install ;判斷mysql是否已經安裝 ;寫入注冊表表示不是本程序安裝的mysql,卸載的時候不需要卸載mysql數據庫 WriteRegDword HKLM "${PRODUCT_DIR_REGKEY}" "MySqlInstalled" 0 MessageBox MB_OK|MB_ICONEXCLAMATION "本機已安裝了mysql數據庫,請手動導入數據信息,謝謝!" Goto done ;退出安裝mysql no_install: ;沒有安裝則安裝 ExecWait "$INSTDIR\mysql5.1\bin\mysqld --install mysql" ;設置mysql的環境變量到PATH路徑 ReadRegStr $0 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "Path" WriteRegExpandStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "Path" "$0;$INSTDIR\mysql5.1\bin\" ;刷新環境變量 SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" ;啟動服務 ExecWait "net start mysql" ;寫入注冊表表示是本程序安裝的mysql,方便卸載的時候卸載mysql數據庫 WriteRegDword HKLM "${PRODUCT_DIR_REGKEY}" "MySqlInstalled" 1 ;完成 done: FunctionEnd Function .onInit InitPluginsDir ;創建互斥防止重復運行 System::Call 'kernel32::CreateMutexA(i 0, i 0, t "YBSetup") i .r1 ?e' Pop $R0 StrCmp $R0 0 +3 MessageBox MB_OK|MB_ICONEXCLAMATION "有一個YBSetup安裝向導已經運行!" Abort ;禁止多次安裝實例 start ReadRegDWORD $0 HKLM '${PRODUCT_DIR_REGKEY}' "Installed" IntCmp $0 +1 +4 MessageBox MB_OK|MB_USERICON '$(^Name) 已安裝在計算機中。如需重新安裝,請卸載已有的安裝。' Quit nop ;禁止多次安裝實例 end FunctionEnd ;--------------- 移除mysql服務 ---------------- Function un.removeService ;讀取是否是本程序安裝mysql ReadRegDWORD $0 HKLM '${PRODUCT_DIR_REGKEY}' "MySqlInstalled" IntCmp $0 1 0 clearDb ;停止mysql服務 ExecWait "net stop Mysql" ;移除mysql服務 ExecWait "$INSTDIR\mysql5.1\bin\mysqld --remove Mysql" ;移除環境變量 ReadRegStr $R0 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "Path" ${WordReplace} $R0 ";$INSTDIR\mysql5.1\bin\" "" "+" $R1 ;MessageBox MB_OK|MB_USERICON '$R0 - $INSTDIR - $R1 ' WriteRegExpandStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "Path" "$R1" ;清除數據庫信息 clearDb: FunctionEnd ;--------------------------------- Function un.onInit FindProcDLL::FindProc "YBest.Ads.exe" Pop $R0 IntCmp $R0 1 0 no_run MessageBox MB_ICONSTOP "安裝程序檢測到 $(^Name) 正在運行,請退出程序后重試" Quit no_run: MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "您確實要完全移除 $(^Name) ,及其所有的組件?" IDYES +2 Abort FunctionEnd Function un.onUninstSuccess HideWindow MessageBox MB_ICONINFORMATION|MB_OK "$(^Name) 已成功地從您的計算機移除。" FunctionEnd
歡迎大家批評指正,共同進步!謝謝!