天天看點

一個完整的Installshield安裝程式執行個體—艾澤拉斯之海洋女神出品(三) --進階設定一

在開始進行程式設計前,我們先明确一下我們要用程式設計來彌補前面設定的哪些功能的不足

1. 顯示軟體許可協定

2. 判斷是否安裝了本軟體所需要的先決軟體JKD1.6.0_04,如無,則啟動外部安裝程式進行安裝(同樣原理可以用來判斷是否安裝了其他軟體,隻要該軟體在系統資料庫中有鍵值)

3. 使用者的輸入資訊、所選安裝路徑、所選安裝元件将顯示在安裝界面上(Installshield雖然自帶了此界面,但是預設是顯示為空的,需要寫腳本來顯示資訊)

4. 根據使用者選擇的元件,從外部檔案夾拷貝相應的檔案到安裝目标路徑的檔案夾中

5. 根據從外部拷貝進來的檔案,建立快捷方式(這裡主要是拷貝文檔,并在開始菜單中建立快捷方式)

6. 在安裝結束時,顯示readme.txt檔案

7. 在安裝結束後,啟動指定的程式

8. 完美解除安裝

腳本程式設計這部分都将在Installer Designer這個界面進行。後面不再贅述。

Installshield大小寫敏感,是以請嚴格按照示例上所寫的大小寫規則來書寫。例:字元串變量STRING和string都支援,但是String不支援。

1. 添加許可協定文本

在左邊導航樹上找到Behavior and Logic | Support Files/Billboards選項。這個選項允許使用者添加一些在安裝過程中需要用到的檔案。

一個完整的Installshield安裝程式執行個體—艾澤拉斯之海洋女神出品(三) --進階設定一

中間的導航欄會顯示對應的選項

一個完整的Installshield安裝程式執行個體—艾澤拉斯之海洋女神出品(三) --進階設定一

在Support Files分支下,會顯示一個Language Independent和所有你所選擇的語言類型。 Language Independent意為,如果你在這裡分支下做了設定,那麼無論選擇用何種語言安裝,這個設定都會生效;而各個語言類型意為,如果你在某語言下做了設定,那麼這個設定隻有在選擇了用這種語言安裝的時候才會生效。

點選Language Independent,這次我們将在這個分支下進行試驗。

一個完整的Installshield安裝程式執行個體—艾澤拉斯之海洋女神出品(三) --進階設定一

在右邊的Files欄中右鍵點選,在彈出菜單上選擇Insert Files選項。

一個完整的Installshield安裝程式執行個體—艾澤拉斯之海洋女神出品(三) --進階設定一

選擇事先撰寫好的許可協定的文本檔案,插入到Files欄中。

許可協定允許兩種文本格式:txt和rtf格式,此處我們采用 txt格式。

2. 然後切換到Behavior and Logic | InstallScript選項,

一個完整的Installshield安裝程式執行個體—艾澤拉斯之海洋女神出品(三) --進階設定一

3. 中間的導航欄Files下有一個預設的Rul檔案Setup.Rul,我們這個工程的全部installscript代碼都将寫在這個預設檔案裡

一個完整的Installshield安裝程式執行個體—艾澤拉斯之海洋女神出品(三) --進階設定一

4. 點選選中Setup.Rul節點,右邊會顯示該檔案的可程式設計面闆。

5. 許可協定應該在一開始運作安裝程式的時候就顯示,也就是在拷貝資料前。請在第一個下拉框中選擇Before Move Data選項,然後在第二個下拉框中選擇OnBegin選項(不要因為預設顯示的是這兩個選項,而不做這個打開下拉清單進行選擇的動作,否則軟體檢測不到你選擇了選項,無法自動添加代碼),則程式設計界面上會自動添加一些代碼如下圖所示。當然,如果你手動敲代碼上去也是可以的。

一個完整的Installshield安裝程式執行個體—艾澤拉斯之海洋女神出品(三) --進階設定一

6. 我們将在function OnBegin()的函數體裡面寫代碼來顯示剛才添加的許可協定文本的内容,直接把下面的代碼拷貝到OnBegin()函數的begin和end;之間就可以了

Disable (BACKBUTTON);

if(!MAINTENANCE)then

SdLicense2 ("License ", "", "", SUPPORTDIR ^ "2.txt", FALSE);

endif;.

7. 代碼解釋

************************************************************************

将“上一步”按鍵設定為不可用。安裝程式在一開始的時候會有一個預設的開始界面,第二步才顯示許可協定,一般來說沒必要回退回去看這個什麼都沒有的開始界面,是以将回退按鍵設定為不可用

endif;

這一個條件用來判斷安裝程式處于何種狀态,安裝、修複、重新安裝或解除安裝狀态,後三者都屬于MAINTENANCE狀态,是以判斷隻有在正常安裝的狀态才顯示許可協定

這個函數用于在界面上顯示所用的許可協定。Help裡對該函數的構造函數如下

SdLicense2 ( szTitle, szOpt1, szOpt2, szLicenseFile, bLicenseAccepted );

參數一:szTitle,顯示在界面左上角的标題,如果填寫空字元串””,則顯示為預設值”License Agreement”。

參數二:szOpt1,我們常見許可協定界面上會有兩個選項,一個是“同意”,一個是“不同意”,szOpt1和szOpt2就是這兩個選項,如果填寫空字元串,則會顯示為預設值"I accept the terms of the license agreement"和"I do not accept the terms of the license agreement"。

參數三:szOpt2,見參數二的說明

參數四:szLicenseFile,指定需要顯示的文檔,包含路徑和帶擴充名的文檔名。我們剛才把許可協定文本放在supportfile選項下了,這個路徑在Installshield裡有專門的靜态變量來指明,即SUPPORTDIR,然後再添加上帶擴充名的文檔名,這裡是2.txt。靜态變量路徑和引号引起來的路徑之間用^符号來連接配接。

參數四:bLicenseAccepted,布爾型變量,TRUE狀态,則在許可協定界面上預設選中的是那個“同意”的選項;不過好像一般更常見的是預設選中為“不同意”的選項,是以這裡可以填入FALSE。

一個完整的Installshield安裝程式執行個體—艾澤拉斯之海洋女神出品(三) --進階設定一

這是許可協定的界面。當使用者選擇了I accept the terms of the license agreement這個選項後,Next按鍵可用,安裝程式可以繼續。(請忽略這裡顯示的許可協定内容…網上有很多軟體許可協定的範本供下載下傳...)

小結:至此,許可協定就添加完畢,在安裝執行的時候,使用者就可以看到許可協定顯示在界面上,并且隻有選擇了“同意”選項後,安裝程式才會往下執行。

顯示許可協定的函數一共有三個SdLicense,SdLicenseRtf和SdLicense2,參數略有不同,顯示的界面也略有不同,使用者可以根據喜好來選擇。目前我常用的就是SdLicense2這個函數,顯示的界面符合大多數目前流行的安裝界面的習慣。

1. 代碼還是在OnBegin()函數體内實作,直接把下面的代碼拷貝到OnBegin()函數的begin和end;之間就可以了

RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE);

if (RegDBKeyExist ("SOFTWARE\\JavaSoft\\Java Development Kit\\1.6.0_04") < 0) then

LaunchAppAndWait (SRCDISK^"jdk\\jdk-6u4-windows-i586-p.exe","", LAAW_OPTION_WAIT);

2. 代碼解釋

設定一下預設的系統資料庫鍵值根節點為HKEY_LOCAL_MACHINE。

打開系統資料庫可以看到“我的電腦”下的根節點有HKEY_CLASSES_ROOT, HKEY_CURRENT_USER,HKEY_LOCAL_MACHINE等。我們這次要尋找的JDK軟體的系統資料庫鍵值在HKEY_LOCAL_MACHINE下,是以要把根鍵設定為HKEY_LOCAL_MACHINE。

表告訴我你不知道怎麼看系統資料庫,開始-〉運作-〉輸入指令regedit

***********************************************************************

RegDBKeyExist ("SOFTWARE\\JavaSoft\\Java Development Kit\\1.6.0_04") < 0)

判斷是否存在鍵值SOFTWARE\\JavaSoft\\Java Development Kit\\1.6.0_04,這個是JDK1.6.0_04安裝時向系統資料庫寫入的值;

RegDBKeyExist( szSubKey );如果存在鍵值則傳回1,否則傳回小于0的随機數字。

當上面判斷了沒有安裝JDK1.6.0_04這個軟體時,則啟動CD光牒裡jdk檔案夾下的jdk-6u4-windows-i586-p.exe安裝程式來安裝。

這個函數在help裡是這樣叙述的:

LaunchAppAndWait ( szProgram, szCmdLine, nOptions );

參數一:szProgram,即要啟動的程式。這裡我們寫入的參數是SRCDISK^"jdk\\jdk-6u4-windows-i586-p.exe", SRCDISK指源盤,安裝程式所在的盤,CD光牒和硬碟都可以。"jdk\\jdk-6u4-windows-i586-p.exe"源盤下jdk檔案夾下的jdk-6u4-windows-i586-p.exe安裝程式。

參數二:szCmdLine,如果要啟動的程式需要從指令行讀入參數來啟動,那麼在這裡寫入對應的參數值;我們這裡不需要,是以輸入空字元串””。

參數三:nOptions,靜态變量,不同的靜态變量會得到不同的執行結果,比如無等待安裝,靜默安裝,滑鼠外形改變等等。詳情請參閱Installshield自帶的Help。這裡我們用LAAW_OPTION_WAIT,即當JDK安裝結束後(無論是正常安裝了,還是使用者點選取消了安裝),安裝程式才往下繼續。

一個完整的Installshield安裝程式執行個體—艾澤拉斯之海洋女神出品(三) --進階設定一

這裡可以看到,當點選了同意許可協定的時候,安裝程式會自動檢測是否安裝了JDK,如果沒有安裝,則彈出安裝界面。

這裡在函數體裡面,沒有對找不到JDK安裝程式,以及安裝出錯等情況做判斷。如果使用者有需要,可以添加一個消息框,提示在找不到安裝程式或者安裝出錯的情況下,使用者可以手動地安裝需要的軟體。代碼可以改寫為

if(LaunchAppAndWait (SRCDISK^"jdk\\jdk-6u4-windows-i586-p.exe","", LAAW_OPTION_WAIT)<0)then

MessageBox ("You haven't installed JDK 1.6.0_04 yet! ", INFORMATION);

小結:至此,判斷運作所需軟體的功能結束,使用者可以自己試驗一下判斷多個軟體。用法就是重複上述代碼功能,仍在OnBegin()函數體内執行。

Installshield是自帶這個界面的,在安裝過程中使用者可以看到這個界面,但是這個界面上的資訊是空的,這一點讓人很是疑惑,懷疑是Installshield的bug。是以我們不得不手動地實作這個功能。

1. 這個功能需要在OnFirstUIBefore()函數體中實作,選擇Before Move Data | OnFirstUIBefore選項

一個完整的Installshield安裝程式執行個體—艾澤拉斯之海洋女神出品(三) --進階設定一

2. 選擇了這個選項後,軟體會自動在程式設計界面生成大量代碼,如圖所示,這裡的每一個Dlg_SdXXXX都對應着一個界面,例如Dlg_SdWelcome就是對應着最初開始的歡迎界面。如果開發人員對這些很熟悉,可以在這裡對每一個界面程式設計設定。

一個完整的Installshield安裝程式執行個體—艾澤拉斯之海洋女神出品(三) --進階設定一

3. 找到Dlg_SdStartCopy這個界面選項,我們将在這裡對已有的代碼進行改動,使之顯示使用者輸入的使用者資訊、所選安裝路徑群組件等資訊

一個完整的Installshield安裝程式執行個體—艾澤拉斯之海洋女神出品(三) --進階設定一

4. 首先定義所需變量。

在begin前定義6個feature的名字和兩個NUMBER類型的變量,即藍色字串。之前在第一部分我們定義了6個可用的feature,這裡就要對這6個feature進行一些判斷。

在begin字樣後對這6個feature指派,所賦的值就是我們在第一部分定義的feature的名字(Name, not Display Name)。

//---------------------------------------------------------------------------

function OnFirstUIBefore()

NUMBER nResult, nSetupType, nvSize, nUser;

STRING szTitle, szMsg, szQuestion, svName, svCompany, szFile;

STRING szLicenseFile;

LIST list, listStartCopy;

BOOL bCustom;

STRING szFeatureName1;

STRING szFeatureName2;

STRING szFeatureName3;

STRING szFeatureName4;

STRING szFeatureName5;

STRING szFeatureName6;

NUMBER bvOpt1,bvOpt2;

begin

// TO DO: if you want to enable background, window title, and caption bar title

// SetTitle( @PRODUCT_NAME, 24, WHITE );

// SetTitle( @PRODUCT_NAME, 0, BACKGROUNDCAPTION );

// Enable( FULLWINDOWMODE );

// Enable( BACKGROUND );

// SetColor(BACKGROUND,RGB (0, 128, 128));

szFeatureName1 ="Server";

szFeatureName2 ="Client";

szFeatureName3 ="Watch_Portion";

szFeatureName4 ="Log_Portion";

szFeatureName5 ="Report_Portion";

szFeatureName6 ="Document";

5. 在Dlg_SdStartCopy的listStartCopy = ListCreate( STRINGLIST ); 和ListDestroy(listStartCopy);之間的nResult = SdStartCopy( szTitle, szMsg, listStartCopy );之前加入如下代碼。

ListAddString(listStartCopy,"Customer Information:",AFTER);

ListAddString(listStartCopy,"User Name: " + svName,AFTER);

ListAddString(listStartCopy,"Company Name: " + svCompany,AFTER);

ListAddString(listStartCopy,"Destination Location: " + INSTALLDIR,AFTER);

switch (nSetupType)

case TYPICAL : ListAddString(listStartCopy,"Setup Type: Typical",AFTER);

case COMPACT: ListAddString(listStartCopy,"Setup Type: Compact",AFTER);

case CUSTOM: ListAddString(listStartCopy,"Setup Type: Custom",AFTER);

endswitch;

ListAddString(listStartCopy," ",AFTER);

ListAddString(listStartCopy,"The Selected Feature:",AFTER);

if (FeatureIsItemSelected(MEDIA, szFeatureName1)=1) then

ListAddString(listStartCopy," "+szFeatureName1,AFTER);

if (FeatureIsItemSelected(MEDIA, szFeatureName2)=1) then

ListAddString(listStartCopy," "+szFeatureName2,AFTER);

if (FeatureIsItemSelected(MEDIA, szFeatureName3)=1) then

ListAddString(listStartCopy," "+szFeatureName3,AFTER);

if (FeatureIsItemSelected(MEDIA, szFeatureName4)=1) then

ListAddString(listStartCopy," "+szFeatureName4,AFTER);

if (FeatureIsItemSelected(MEDIA, szFeatureName5)=1) then

ListAddString(listStartCopy," "+szFeatureName5,AFTER);

if (FeatureIsItemSelected(MEDIA, szFeatureName6)=1) then

ListAddString(listStartCopy," "+szFeatureName6,AFTER);

6. 代碼解釋

*************************************************************

ListAddString(listStartCopy,"XXXXXX",AFTER);

把要顯示的資訊添加到list裡去,這個list的内容稍後會添加到界面上進行顯示。

Help裡對這個函數是這樣描述的:ListAddString ( listID, szString, nPlacementFlag );

參數一:listID,需要使用者事先建立一個list,這裡我們看到listStartCopy = ListCreate( STRINGLIST );這句話,即建立了一個叫listStartCopy的list

參數二:szString,要添加的字元串

參數三:nPlacementFlag,如果設定為AFTER,則順序添加;如果為BEFORE,則逆序添加,即新添加的内容會放在前面顯示。

這是根據使用者選擇的安裝類型來顯示安裝類型資訊。安裝類型分三種:TYPICAL,COMPACT和CUSTOM。

這裡的FeatureIsItemSelected(MEDIA, szFeatureName1)=1是一個很重要的函數,将會在本安裝程式内反複出現多次。這個函數用于判斷使用者是否選擇了某feature。Help裡對這個函數是這樣描述的:FeatureIsItemSelected ( szFeatureSource, szFeature );

參數一:szFeatureSource,大意好像是feature的來源,具體不是很明白到底指什麼,反正help自帶的例子裡寫的MEDIA照抄沒有錯。

參數二:szFeatureName1,就是 feature的名字了

如果使用者選擇了這個feature,傳回值就為1,往list裡添加一個關于該feature的相關資訊即可。

如此反複,判斷所有的feature是否被選擇,如被選擇則添加一個相關資訊即可。

一個完整的Installshield安裝程式執行個體—艾澤拉斯之海洋女神出品(三) --進階設定一

這個就是顯示了使用者資訊,安裝路徑和安裝元件的資訊。如果沒有添加上述代碼,這個界面預設是顯示的,但是資訊欄裡是空白的。

順便說一句,以前在制作這個安裝程式的時候,因為這塊顯示是空白的,那時候對程式設計也是一竅不通的,情急之下,筆者把這個顯示設定的框框設定了不可見。設定方法如下:

找到User Interface | Dialogs

一個完整的Installshield安裝程式執行個體—艾澤拉斯之海洋女神出品(三) --進階設定一

在中間的導航樹上找到SdStartCopy這個選項

一個完整的Installshield安裝程式執行個體—艾澤拉斯之海洋女神出品(三) --進階設定一

這裡我們使用的是英文界面,是以點選選中English選項

一個完整的Installshield安裝程式執行個體—艾澤拉斯之海洋女神出品(三) --進階設定一

選中這個界面上的将會顯示使用者資訊的框,把右邊的Visible選項設定為False即可

小結:在Dlg_SdStartCopy界面裡,使用者還可以設定左上角顯示的标題和消息,szTitle = ""; szMsg = "";這兩行代碼如果指派為空,則顯示如圖所示的預設資訊,使用者可以指派成自己想要顯示的資訊。