• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            大龍的博客

            常用鏈接

            統(tǒng)計(jì)

            最新評(píng)論

            使用NSIS (NullSoft Scriptable Install System)制作安裝程序快速指南 ---- 轉(zhuǎn)

            “用戶對(duì)你的第一印象是你的安裝程序”

            ——摘自NSIS網(wǎng)頁(yè)

            對(duì)于非技術(shù)用戶,例如兒童,家長(zhǎng),作家等等。如果他們無(wú)法很容易地安裝某個(gè)軟件,他們就會(huì)放棄這個(gè)軟件!而開(kāi)發(fā)者和大多數(shù)程序員,討厭制作Windows安裝程序,甚至討厭學(xué)習(xí)如何制作安裝程序。從10年前的Windows Installer Shield, Installer Shield Express等等,我從來(lái)沒(méi)有耐心下來(lái)搞清楚如何制作安裝程序。最近由于需要向兒童發(fā)布一個(gè)軟件,使得我不得不坐下來(lái)親自制作一個(gè)安裝程序。我沒(méi)有找到好的中文資料,只得自己摸索英文材料。所以我寫(xiě)這樣一個(gè)簡(jiǎn)易指南,希望能夠有所幫助。

            [Why NSIS]

            NSIS是免費(fèi)的,使用并且許多開(kāi)源軟件使用NSIS制作其安裝程序。NSIS最早是WinAMP用于為其播放器安裝皮膚的,后來(lái)成為了流行的安裝程序制作工具。它使用腳本來(lái)制作安裝程序,基本上比較小巧,并且易學(xué)易用。

            [寫(xiě)作方法]

            例子是最好的學(xué)習(xí)方法之一。本文不是一個(gè)關(guān)于NSIS的全面參考,我希望讀者能夠根據(jù)本文“照貓畫(huà)虎”,快速制作安裝程序,如果讀者遇到了某些特定問(wèn)題,可以通過(guò)NSIS附帶的用戶手冊(cè),或者通過(guò)網(wǎng)絡(luò)搜索引擎找到答案。

            [下載和準(zhǔn)備]

            首先需要下載NSIS,地址為:http://prdownloads.sourceforge.net/nsis/nsis-2.20-setup.exe?download

            如果該連接有變動(dòng),讀者可以自行到source forge下載,source forge的網(wǎng)址為:http://sourceforge.net/

            進(jìn)入后搜索nsis即可。下載后即可安裝NSIS。NSIS本身包括幫助手冊(cè),例子目錄,基本編譯器,和一些擴(kuò)展插件。基本工作原理是,開(kāi)發(fā)者將自己的程序準(zhǔn)備好,然后利用文本編輯工具寫(xiě)好安裝腳本,最后利用NSIS編譯器將腳本編譯,并和程序一起打包。可以用任何文本編輯器制作自己的腳本。這里我推薦一個(gè)Eclipse的NSIS插件[1]。其屏幕截圖如下:

             

             該插件可以直接從Eclipse安裝,需要預(yù)先安裝Eclipse GEF 3.1。在Eclipse的Update Manager中加入http://eclipsensis.sf.net/update后即可安裝相關(guān)插件。

            [編寫(xiě)腳本]

            為了不從0開(kāi)始制造輪子,我們利用NSIS的例子腳本,對(duì)其加以改動(dòng)。首先說(shuō)明一下我的安裝程序打算做什么事情。我打算制作一個(gè)Squeak 3.9[2]的安裝程序。它會(huì)從網(wǎng)絡(luò)上分別下載Squeak的虛擬機(jī)和映象文件共兩個(gè)zip包到用戶的計(jì)算機(jī)上。然后解開(kāi)這些zip包到用戶的指定目錄,例如C:\Program files\squeak3.9\下。最后在用戶的桌面和啟動(dòng)菜單建立squeak執(zhí)行程序的快捷方式以及將來(lái)卸載時(shí)用的程序。

            首先看一看NSIS的最簡(jiǎn)單的例子提供了什么,NSIS的Example目錄下有一個(gè)例子叫做:example1.nsi,用文本編輯器打開(kāi)它,其內(nèi)容為:

            ; 注釋說(shuō)明
            ;--------------------------------

            ; 安裝程序的名字,該名字會(huì)顯示在安裝程序?qū)υ捒虻臉?biāo)題中
            Name "Example1"

            ; 安裝程序的最終文件名,編譯后,所有文件被打包生成一個(gè)獨(dú)立的安裝程序,名叫example1.exe
            OutFile "example1.exe"

            ; 缺省安裝到的目錄,一般為C:\Program Files\Example1
            InstallDir $PROGRAMFILES\Example1

            ;--------------------------------
            ; 頁(yè),表示安裝程序的對(duì)話框一共會(huì)變化幾頁(yè),一般首頁(yè)是版權(quán)信息,然后第二頁(yè)讓用戶選擇安裝目錄,
            ; 接下來(lái)安裝文件等等。這個(gè)例子只有兩個(gè)頁(yè),選擇目錄,和復(fù)制文件。


            Page directory
            Page instfiles

            ;--------------------------------
            ; 每頁(yè)有若干節(jié)(section),各個(gè)節(jié)內(nèi)部才真正進(jìn)行各種操作

            Section "" ;由于沒(méi)有讓用戶選擇需要安裝的組件,所以節(jié)的名字可以忽略,腳本將從這里真正執(zhí)行

              ; 安裝程序解包后,將文件復(fù)制到OutPath中。本例將文件復(fù)制到用戶選擇的安裝目錄內(nèi)
              SetOutPath $INSTDIR

              ; 將與腳本處于同一目錄下的文件壓縮打包到安裝程序中,將來(lái)用戶安裝時(shí),
              ; 這些文件會(huì)被解包復(fù)制到OutPath里

              File example1.nsi ; 將腳本自己打包

            SectionEnd ; 本節(jié)結(jié)束

             

            這個(gè)例子非常簡(jiǎn)單,他把腳本自己打包進(jìn)example1.exe中,然后可以發(fā)布這個(gè)example1.exe,它本身是一個(gè)安裝程序。用戶在自己的計(jì)算機(jī)上一旦運(yùn)行此程序,就會(huì)出現(xiàn)一個(gè)對(duì)話框,讓用戶選擇安裝目錄,用戶選擇好后,其會(huì)將example1.nsi從包內(nèi)解出,并復(fù)制到用戶選擇好的安裝目錄內(nèi)。可以用這個(gè)腳本做一個(gè)測(cè)試,有兩個(gè)方法可以編譯腳本生成可執(zhí)行的安裝程序,一個(gè)方法時(shí)在這個(gè)腳本上點(diǎn)鼠標(biāo)右鍵,選擇“Compile NSIS script”,然后NSIS編譯器就會(huì)啟動(dòng),編譯腳本打包文件生成example1.exe,第二個(gè)方法是在Eclipse內(nèi)選擇菜單 EclipseNSIS | Compile Script,或者使用快鍵Alt+C,也會(huì)生成example.exe。雙擊這個(gè)exe就會(huì)運(yùn)行此安裝程序?qū)xample.nsi復(fù)制安裝的指定目錄。

            在這個(gè)例子的基礎(chǔ)上,很容易寫(xiě)出我自己的安裝程序。

            例子腳本和我的要求有若干不同,主要如下:

            1. 我需要從網(wǎng)絡(luò)下載zip到用戶計(jì)算機(jī)

            2. 我需要親自解開(kāi)zip包到用戶目錄

            3. 我需要建立桌面和程序快捷方式

            4. 我需要建立卸載程序

            首先針對(duì)第1點(diǎn)要求,經(jīng)過(guò)查閱資料,發(fā)現(xiàn)NSIS帶有一個(gè)下載插件可以完成此功能,其典型用法是:

            NSISdl::download http://www.yoursite.org/yourpack.zip "$INSTDIR\yourpack.zip"
            Pop $R0 ; 獲得下載結(jié)果的返回值
            StrCmp $R0 success download_ok
              SetDetailsView show
              DetailPrint "download failed: $R0"
              Abort
            download_ok:
              DetailPrint "download $R0 OK"

            上面這段代碼的意思是,首先調(diào)用NSISdl::download這個(gè)插件去網(wǎng)絡(luò)上下載yourpack.zip文件到用戶本地的安裝目錄下,并且文件名保持不變。是否下載成功的結(jié)果放在寄存器變量$R0中,如果下載成果這個(gè)變量中的指應(yīng)該是字符串success,所以StrCmp的作用就是比較返回結(jié)果是否成功,如果成功,就跳轉(zhuǎn)到download_ok標(biāo)記,否則如果下載失敗(包括網(wǎng)絡(luò)問(wèn)題等等),就打印出失敗信息,并且終止安裝。

            這段代碼具有一定的代表性,實(shí)際上可以利用它從網(wǎng)絡(luò)下載多個(gè)文件到用戶計(jì)算機(jī),唯一不同的就是下載地址和保存到本地的文件名。因此可以把它制作成一個(gè)函數(shù),如下:

            Function DownloadFile
              NSISdl::download $remote_zip_file "$INSTDIR\$local_zip_file"
                ; 略...
              download_ok:
                DetailPrint "download $R0 OK"
            FunctionEnd

            這個(gè)函數(shù)的參數(shù),用兩個(gè)全局變量$remote_zip_file$local_zip_file傳入。調(diào)用方法如下:

            Var remote_zip_file
            Var
            local_zip_file

            StrCpy $remote_zip_file "http://ftp.squeak.org/current_stable/win/Squeak-Win32-3.7.1-VM.zip"
            StrCpy $local_zip_file "Squeak-Win32-3.7.1-VM.zip"
            Call DownloadFile

            NSIS中的變量用Var語(yǔ)句聲明,聲明時(shí)不帶有$前綴,使用時(shí),利用$前綴進(jìn)行引用,這一點(diǎn)和Unix的Shell一樣,賦值不采用等號(hào),而使用StrCpy語(yǔ)句,進(jìn)行字符串復(fù)制。

            至此第一個(gè)需求就可以得到完全滿足了,我可以分別下載Squeak的虛擬機(jī)和Squeak的映像到用戶的計(jì)算機(jī),此時(shí)的安裝腳本如下:

            ; 安裝程序的名稱
            Name "Squeak 3.9 Installer"

            ; 安裝程序的文件名
            OutFile "squeak3.9_win_installer.exe"

            ; 缺省安裝目錄
            InstallDir "$PROGRAMFILES\Squeak3.9"

            ;--------------------------------
            ; 安裝對(duì)話框包含的頁(yè)內(nèi)容
            ; Pages


            Page directory
            Page instfiles

            ;--------------------------------
            ; 自定義的全局變量

            Var remote_zip_file
            Var local_zip_file

            ; 安裝Section
            Section ""

              ; 安裝輸出的目錄
              SetOutPath $INSTDIR

              ; 從網(wǎng)絡(luò)分別下載虛擬機(jī)和映像
              Call DownloadVM
              Call DownloadImage

            SectionEnd ; Section結(jié)束
             

            ; 下載虛擬機(jī)
            Function DownloadVM
              StrCpy $remote_zip_file "http://ftp.squeak.org/current_stable/win/Squeak-Win32-3.7.1-VM.zip"
              StrCpy $local_zip_file "Squeak-Win32-3.7.1-VM.zip"
              Call DownloadFile
            FunctionEnd
             

            ; 下載映像
            Function DownloadImage
              StrCpy $remote_zip_file "http://ftp.squeak.org/3.9/Squeak3.9-RC2-7064.zip"
              StrCpy $local_zip_file "Squeak3.9-RC1-7064.zip"
              Call DownloadFile
              Call ExtractFile
            FunctionEnd
             

            ; 下載文件的通用函數(shù)
            Function DownloadFile
              NSISdl::download $remote_zip_file "$INSTDIR\$local_zip_file"
              Pop $R0 ; Get the return value
              StrCmp $R0 success download_ok
                SetDetailsView show
                DetailPrint "download failed: $R0"
                Abort
              download_ok:
                DetailPrint "download $R0 OK"
            FunctionEnd

            讀者可以使用NSIS編譯這個(gè)腳本并運(yùn)行安裝程序,它會(huì)將虛擬機(jī)和映像的zip文件下載到指定目錄下(例如C:\Program Files\Squeak3.9\)并結(jié)束。下面著手實(shí)現(xiàn)第二個(gè)需求,將zip包解開(kāi)。查閱NSIS手冊(cè),沒(méi)有發(fā)現(xiàn)類(lèi)似功能的函數(shù)或者插件。其原因是, NSIS在打包時(shí),會(huì)自動(dòng)將普通文件按照zip標(biāo)準(zhǔn)的壓縮算法打包,而執(zhí)行exe時(shí),則自動(dòng)解包。所以NSIS沒(méi)有考慮將zip再次打包,以及顯式解壓縮 zip文件的功能。經(jīng)過(guò)在網(wǎng)絡(luò)上使用搜索引擎查找,發(fā)現(xiàn)了一個(gè)第三方插件NsisUnz[3],其可以從這里下載http://home.no.net/nxs/nsis/nsisunz.7z,該文件是7zip格式,可以在這里下載其壓縮解壓縮工具:http://www.7-zip.org/。解開(kāi)軟件包后,將其中的nsisunz.dll復(fù)制到NSIS目錄下的Plugins子目錄下即可(例如C:\Program Files\NSIS\Plugins\),該P(yáng)lugin的使用方式為:

            nsisunz::UnzipToLog "$INSTDIR\myfile.zip" "$INSTDIR"

            若解壓縮成功,該命令返回字符串success,否則表示解壓縮失敗。因此可以仿照上面的下載函數(shù),寫(xiě)出一個(gè)通用的解壓縮函數(shù),它接受一個(gè)zip文件的文件名字符串,然后對(duì)其解壓縮,如下:

            Function ExtractFile
              nsisunz::UnzipToLog "$INSTDIR\$local_zip_file" "$INSTDIR"
              Pop $R0
              StrCmp $R0 "success" unzip_ok
                DetailPrint "$R0"
                Abort
              unzip_ok:
                DetailPrint "extract $R0 OK"
                Delete "$INSTDIR\local_zip_file"
            FunctionEnd

            這個(gè)解壓縮函數(shù)一旦成功,就會(huì)刪除原來(lái)下載的zip文件,以節(jié)約用戶空間。采用這個(gè)通用的解壓縮函數(shù),可以修改上面的虛擬機(jī)和映像下載函數(shù)為:

            Function DownloadVM
              StrCpy $remote_zip_file "http://ftp.squeak.org/current_stable/win/Squeak-Win32-3.7.1-VM.zip"
              StrCpy $local_zip_file "Squeak-Win32-3.7.1-VM.zip"
              Call DownloadFile
              Call ExtractFile
            FunctionEnd

            Function DownloadImage
              StrCpy $remote_zip_file "http://ftp.squeak.org/3.9/Squeak3.9-RC2-7064.zip"
              StrCpy $local_zip_file "Squeak3.9-RC1-7064.zip"
              Call DownloadFile
              Call ExtractFile
            FunctionEnd

            編譯這個(gè)改進(jìn)的腳本并運(yùn)行,可以發(fā)現(xiàn)zip被下載后解開(kāi)成各自的文件了。這里有一些小問(wèn)題,有些zip包里,就包含一些文件,但是有些zip包里,卻包含目錄,例如上面兩個(gè)zip包解開(kāi)后,在$INSTDIR下就會(huì)出現(xiàn)這樣的文件結(jié)構(gòu):

            +Squeak.exe
            +SqueakFFIPrims.dll
            +Squeak3.9-RC2-7064\
              +Squeak3.9-RC2-7064.image
              +Squeak3.9-RC2-7064.changes
              +SqueakV39.source
              +WelcomeSqueak39

            而我需要所有這6個(gè)文件,都在同一目錄下,因此需要使用NSIS的Rename函數(shù)移動(dòng)這些文件。為此修改DownloadImage函數(shù)如下:

            Function DownloadImage
              ;略...
              Call DownloadFile
              Call ExtractFile

              ; 將文件移動(dòng)到$INSTDIR下,并刪除空掉的子目錄
              Rename "$INSTDIR\Squeak3.9-RC2-7064\Squeak3.9-RC2-7064.changes" "$INSTDIR\Squeak3.9-RC2-7064.changes"
              Rename "$INSTDIR\Squeak3.9-RC2-7064\Squeak3.9-RC2-7064.image" "$INSTDIR\Squeak3.9-RC2-7064.image"
              Rename "$INSTDIR\Squeak3.9-RC2-7064\SqueakV39.sources" "$INSTDIR\SqueakV39.sources"
              Rename "$INSTDIR\Squeak3.9-RC2-7064\WelcomeSqueak39" "$INSTDIR\WelcomeSqueak39"
              RMDir "$INSTDIR\Squeak3.9-RC2-7064"
            FunctionEnd

            至此,第二個(gè)需求就滿足了,為了方便用戶使用,下面實(shí)現(xiàn)第3個(gè)需求——在桌面和程序菜單中建立Squeak的快捷方式,這樣用戶只需要雙擊這些快捷方式的圖標(biāo),就可以運(yùn)行Squeak了。squeak的運(yùn)行方式是按照這樣的命令行:

            squeak.exe squeak_iamge_filename.image

            但是Windows的目錄名可能會(huì)帶有空格,例如C:\ Program Files\Squeak3.9\中,Program和Files之間就存在一個(gè)空格,這樣squeak.exe會(huì)把空格前的部分,C:\Program 當(dāng)作映像文件名,而把后面的Files\Squea...當(dāng)作參數(shù),這就出現(xiàn)了歧義。為此需要把路徑用""括起來(lái)。但是NSIS中,會(huì)把""忽略掉,辦法是在""外再括一層''。此后就可以使用NSIS的CreateShortCut函數(shù)創(chuàng)建快捷方式了。當(dāng)必要的文件下載并解壓縮成功后就進(jìn)行這一步的內(nèi)容,為此修改Section如下:

            Section ""

              SetOutPath $INSTDIR

              Call DownloadVM
              Call DownloadImage

              ; 創(chuàng)建快捷方式
              CreateDirectory "$SMPROGRAMS\Squeak\3.9\"
              CreateShortcut "$SMPROGRAMS\Squeak\3.9\squeak.lnk" $INSTDIR\Squeak.exe
                 '"$INSTDIR\Squeak3.9-RC2-7064.image"'
              CreateShortcut "$DESKTOP\squeak3.9.lnk" $INSTDIR\Squeak.exe
                 '"$INSTDIR\Squeak3.9-RC2-7064.image"'

              Exec '$INSTDIR\Squeak.exe "$INSTDIR\Squeak3.9-RC2-7064.image"' ; 安裝成功后自動(dòng)運(yùn)行Squeak
              SetAutoClose true ; 安裝結(jié)束后自動(dòng)關(guān)閉安裝程序
            SectionEnd

            為了進(jìn)一步增強(qiáng)用戶友好性,還在安裝成功后,自動(dòng)運(yùn)行Squeak并關(guān)閉安裝程序。

            最后,良好的安裝程序還應(yīng)該提供卸載功能,并干凈地清除用戶計(jì)算機(jī)上的內(nèi)容。為此可以利用NSIS提供的 UnistPage命令創(chuàng)建卸載程序頁(yè)面,并提供一個(gè)名叫Uninstall的Section實(shí)際進(jìn)行卸載工作。對(duì)于Squeak這點(diǎn)卸載工作的內(nèi)容包括,刪除程序文件,刪除快捷方式等,其實(shí)現(xiàn)如下:

            ; 用于安裝的頁(yè)

            Page directory
            Page instfiles
             

            ; 用于卸載的頁(yè)
            UninstPage uninstConfirm
            UninstPage instfiles

            ;--------------------------------
            ; 略...

            Section "Uninstall"
              ; 刪除文件
              Delete "$INSTDIR\*.image"
              Delete "$INSTDIR\*.changes"
              Delete "$INSTDIR\*.dll"
              Delete "$INSTDIR\*.sources"
              Delete "$INSTDIR\*.exe"
              Delete "$INSTDIR\WelcomeSqueak39"
              RMDir "$INSTDIR"

              ; 刪除快捷方式
              Delete "$SMPROGRAMS\Squeak\3.9\squeak.lnk"
              Delete "$DESKTOP\squeak3.9.lnk"
              RMDir "$SMPROGRAMS\Squeak\3.9"

              SetAutoClose true
            SectionEnd

            提供Uninstall功能的腳本,需要在安裝的最后一步身成uninstall.exe供用戶日后使用,為此在安裝Section最后增加這樣一行:

              CreateShortcut "$SMPROGRAMS\Squeak\3.9\uninstall.lnk" "$INSTDIR\uninstall.exe"
              WriteUninstaller "$INSTDIR\uninstall.exe"

            并在Uninstall的Section中增加對(duì)卸載快捷方式的刪除動(dòng)作:

              Delete "$SMPROGRAMS\Squeak\3.9\uninstall.lnk"
             

            至此一個(gè)完整的安裝程序就制作完成了,該安裝腳本的完整代碼可以在這里下載。squeak3.9_win_install.nsi

            [繼續(xù)提高]

            包括國(guó)際語(yǔ)言支持,斷點(diǎn)續(xù)傳等。待續(xù)

            [參考文獻(xiàn)]

            [1]. Eclipse NSIS plug-in: http://eclipsensis.sourceforge.net/

            [2]. Squeak http://www.squeak.org

            [3]. Nsisunz plug-in http://nsis.sourceforge.net/Nsisunz_plug-in 



            Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1552043

            posted on 2008-01-30 19:37 大龍 閱讀(3201) 評(píng)論(0)  編輯 收藏 引用


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            国产精品久久久香蕉| 久久精品国产99久久久香蕉| 精品久久久久久国产免费了| 99久久精品午夜一区二区| 色婷婷久久综合中文久久蜜桃av| 亚洲а∨天堂久久精品9966| 中文成人久久久久影院免费观看| 久久婷婷午色综合夜啪| 亚洲欧美日韩精品久久亚洲区| 一本久久综合亚洲鲁鲁五月天亚洲欧美一区二区| 秋霞久久国产精品电影院| 91精品日韩人妻无码久久不卡| 亚洲精品国产成人99久久| 久久精品一区二区影院 | 久久毛片一区二区| 亚洲欧洲中文日韩久久AV乱码| 热久久视久久精品18| 亚洲级αV无码毛片久久精品| 久久综合综合久久综合| 国产精品99久久久久久宅男| 亚洲国产精品综合久久一线| 久久久久久精品成人免费图片| 久久夜色精品国产网站| 狠狠色综合久久久久尤物| 日产精品久久久久久久| 久久精品国产清高在天天线| 国产三级精品久久| 一本一道久久综合狠狠老| 国内精品久久国产大陆| 亚洲?V乱码久久精品蜜桃 | 久久免费的精品国产V∧| 欧美色综合久久久久久| 亚洲精品国产美女久久久| 久久人妻少妇嫩草AV蜜桃| 99久久婷婷国产综合精品草原| 久久人人爽人人爽人人片AV不| 91亚洲国产成人久久精品| 久久99精品国产自在现线小黄鸭| 久久99国产精品久久| 中文字幕人妻色偷偷久久 | 久久国产乱子精品免费女|