對於大多數用戶來說,安裝軟體常常是一件痛苦的事情。生成安裝包是軟體開發的 “最後一步”,但它可能導致不同的結果:要麼用戶採用軟體,要麼它就成為無人問津的垃圾品。在本期的 讓開發自動化 中,自動化專家 Paul Duvall 演示了如何使用免費、開源的工具 IzPack 來編寫為您的用戶安裝軟體的基於嚮導的安裝程序。
在我職業生涯的大部分時間裡,我參與了軟體開發的整個生命周期 — 不僅設計軟體的需求、設計、開發和測試,還涉及部署、構建管理、文檔編製和安裝等活動。最近,隨著敏捷開發越來越流行,這些活動可能會更加規範。然而,我在敏捷項目方面的經驗表明,有效的部署和安裝並沒有受到同等的重視。這很滑稽,因為如果潛在用戶不能輕鬆地安裝您的軟體,那麼您很可能會失去他們。提供一種簡單的方式來安裝您的軟體,這對於吸引和留住用戶至關重要。
這些年來,我使用過很多安裝程序工具。我們團隊在今年年初開始的一個大型項目中,為了創建企業級安裝程序,必須滿足一些非常特別的需求。我們看過 Antigen、AntInstaller、Denova、install4j、InstallAnywhere、IzPack、NSIS 等工具。但是根據項目的特定需求,我們最後決定使用 IzPack,因為:
IzPack 在 2001 年已經出現。它為創建基於嚮導的安裝程序提供了一套豐富的特性。在本文中,我演示如何使用該工具創建安裝程序,並給出定義面板、用腳本編寫驗證器、設置資源等方面的例子。
下載和安裝 IzPack
![]() |
|
下載和安裝 IzPack 非常簡單。IzPack 使用 IzPack 來安裝 IzPack,這也許並不奇怪。請訪問 IzPack 網站,下載 IzPack JAR 文件(請參閱 參考資料)。
要安裝 IzPack,必須有一個正在運行的 Java Runtime Environment(JRE)。打開命令行提示符,輸入 java -jar IzPack-install-4.1.0.jar,可以根據需要修改版本。
基於嚮導的安裝程序要求提供基本的安裝信息,比如想將 IzPack 安裝在哪裡。IzPack 安裝完畢后,將得到一個可以運行的示例安裝程序。
![]() ![]() |
修改示例腳本
IzPack 提供了一套完整的示例安裝腳本。以它們為基礎編寫自己的安裝程序,這是獲得一個可運行的安裝程序的最快方法。安裝 IzPack 的根目錄下有一些子目錄,包括 bin、doc 和 lib 等。示例安裝程序在子文件夾 sample 中,實際上它包含了開發您自己的安裝程序所需的所有東西。我選擇複製這個 sample 目錄,這樣就可以隨意修改它,而不會破壞原始的內容。圖 1 顯示了 sample 目錄的內容:
下面是對圖 1 中列出的每個文件的描述:
接下來,通過查看 install.xml 腳本仔細研究 IzPack。
資源
通過資源定義不同的腳本、圖像、許可和其他文件,它們共同構成我將要創建的安裝程序。我在 install.xml 腳本中定義了一個 <resources> XML 元素。在 <resources> 元素下,我可以定義安裝程序將使用的多個文件,如清單 1 所示:
<resources> <res id="LicencePanel.licence" src="Licence.txt"/> <res id="InfoPanel.info" src="Readme.txt"/> <res id="AntActionsSpec.xml" src="antActionSpec.xml" /> <res id="userInputSpec.xml" src="userInputSpec.xml" /> </resources> |
可以將 IzPack 的資源看作安裝程序的 “原料單”,其中定義了用於安裝程序的所有文件。
面板
面板是用戶在安裝嚮導的每一步中看到的東西。IzPack 提供了很多類型的開箱即用的面板,您可以根據自己的需求定製它們。在圖 2 中,我定製了 IzPack 的 HelloPanel,以便向用戶提供介紹信息:
標準面板包括 LicensePanel、UserInputPanel 和 PacksPanel 等。在 install.xml 文件中,可以使用 <panels> 元素定義要顯示的面板,然後再定義編寫安裝程序時將使用的面板模板。清單 2 中的例子演示了如何定義面板模板:
<panels> <panel classname="HelloPanel"/> <panel classname="InfoPanel"/> <panel classname="LicensePanel"/> <panel classname="UserInputPanel" id="UserInputPanel.0" /> <panel classname="TargetPanel"/> <panel classname="PacksPanel"/> <panel classname="InstallPanel"/> <panel classname="FinishPanel"/> </panels> |
您最常用的是模板類型可能是 UserInputPanel。這是讓用戶可以輸入可變信息而定製的面板模板。這包括用戶的聯繫方式信息、認證憑證、目錄位置等。用戶可能需要根據他們特定的環境在面板上輸入信息。由於我們的團隊需要用戶連接到一個資料庫並設置多個 JBoss 容器,所以我們使用面板提示用戶提供特定的信息。
清單 3 是從 userInputSpec.xml 摘錄的一個例子,在 清單 1 中我將它定義為一個資源。在這個例子中,我將收集特定於用戶的信息,用於連接到一個特定的資料庫。
<panel order="0"> <field type="title" txt="Configuring your database connection" bold="true" size="1" /> <field type="staticText" align="left" txt="Connect to an existing database..."/> <field type="divider" align="top"/> <field type="text" variable="database.hostname"> <spec txt="Database Host Name:" id="databasehostname.label" size="40" set=""/> <validator class="com.izforge.izpack.util.NotEmptyValidator" txt=" Database Hostname is a required field" /> </field> ... </panel> |
該面板的 order 屬性被設置為 0,這對應於 清單 2 中的面板集合中定義的 UserInputPanel 的數量。
在用戶輸入面板中,可以為用戶定義信息文本。而且,我加入了一個 NotEmptyValidator,它要求用戶在文本域中輸入一個值。這樣可以防止因用戶忘記輸入必需的信息而導致安裝錯誤。圖 3 中顯示了基於 清單 3 的 UserInputPanel:
用戶常常根據輸入信息和顯示消息的難易程度來判斷安裝程序的好壞。因此一定要讓用戶看到的東西容易使用。
pack
IzPack 使用術語 pack 表示負責實際安裝開發團隊已實現的軟體的組件。所有其他的 IzPack 組件(面板、用戶輸入、驗證器等)都是為運行這些 pack 做準備。我的項目使用 pack 做兩件事:下載我們已經用 Ant 編寫好的一個 ZIP 安裝發布包,然後運行這個安裝。這種方法使我們可以重用之前編寫的在命令行運行的命令。清單 4 定義了一個 <pack>:
<packs> <pack name="download_install" id="download_install" installGroups="ap" required="no"> <description>The base files</description> <file src="autopeople.zip.file" targetdir="$SYSTEM_user_home/_cnnew1_cnnew1@{installer.dir}"/> <file src="build.xml" targetdir="$SYSTEM_user_home/@{installer.dir}"/> <file src="property-template" targetdir="$SYSTEM_user_home/@{installer.dir}"> <excludes>**/.svn/**</excludes> </file> </pack> |
圖 4 顯示一個進行中的 pack 安裝:
IzPack 中的 packs 可以包含多個 pack!如果您已經完成了用戶驗證、診斷和獲取特定於環境的信息等前期工作,那麼用戶應該很容易運行安裝包。
![]() ![]() |
運行 Ant 腳本
在我的團隊中,我們花了很多時間用 Ant 創建基於發布包的安裝程序。我們不想在 IzPack 中再次重新實現該功能。幸運的是,IzPack 支持調用已有 Ant 文件。還記得嗎,我在 清單 1 中定義資源時,曾列出了 antActionSpec.xml 作為一個資源。清單 5 顯示了摘自 antActionSpec.xml 腳本的一個片段:
<antactions> <pack name="download_install"> <antcall buildfile="$SYSTEM_user_home/${installer.dir}/build.xml" order="afterpack" verbose="yes" logfile="$SYSTEM_user_home/${installer.dir}/antlog_installer.txt" inheritall="false" messageid="AntAction.download-install"> <target name="install"/> <property name="install.path" value="$SYSTEM_user_home/${installer.dir}"/> </antcall> </pack> ... </antactions> |
這個腳本中最重要的執行 build.xml 的部分。這是現有的 Ant 構建腳本,它執行下載和提取一個 ZIP 安裝文件,安裝並配置 Web 容器,然後完成安裝中剩下的其他任務。antActionSpec.xml 使我們可以重用現有的 Ant 腳本。
![]() ![]() |
編譯安裝程序
最後一步就是 IzPack 的編譯。編寫好 install.xml 和相關腳本之後,就可以生成安裝程序。清單 6 是一個可用於生成 install.jar(可以修改這個文件的文件名)的單行命令的例子:
compile ../sample/install.xml -b ../sample |
清單 6 中的命令假設您是從 IzPack 的 bin 子目錄運行它。sample 是對 IzPack 提供的 sample 子目錄的引用。生成安裝程序后,可以通過從 sample 子目錄中生成 install.jar 的位置運行 java -jar install.jar 來測試它。
![]() ![]() |
結束語
在本文中,我展示了如何使用 IzPack 的不同組件為用戶創建易於使用的安裝包。他們可能是安裝基於客戶機的軟體的用戶,也可能是安裝和配置多個伺服器的遠程站點的用戶,還可能是安裝和配置企業工具套件的團隊。如果軟體容易安裝,則更易被採納,這一點在安裝比較複雜的環境中尤為突出。如果安裝需要很多手動步驟或者乾脆無法進行,那麼用戶很快就會對軟體失去信心。通過 IzPack 等工具使安裝變得更加容易,這可以幫助您贏得並留住熱情的用戶。(責任編輯:A6)
[火星人 ] 讓開發自動化: 使用基於嚮導的安裝程序已經有545次圍觀