第三部分:其他
1. 修改顯示界面的風格
Installshield 原始安裝界面我始終覺得很醜,幸好Installscript 是可以不用寫代碼就可以改界面風格的。
在 Installation Designer 的左邊導航樹上找到User Interface | Dialogs
Skins 選項下面顯示了不同的界面風格,默認是None,選擇一個喜好的風格即可,筆者一般使用Blue 或BlueTC,適用於一般商業軟件的穩
重風格;Midnight 比較酷,要是做電腦遊戲的安裝程序,我一定會選這個風格。
2. 編譯打包
一切都準備就緒之後,就差一個編譯打包成實際的安裝程序的過程了。
編譯
編譯可以使用工具欄上的 ,檢查一下有無定義錯誤,編譯錯誤等。
打包
打包可以使用工具欄上的 。
1. 第一步,指定一個打包的配置版本,如果使用同一個安裝程序源來打包成不同的配置,就可以選擇新的配置版本。這裏的配置指的
是安裝程序本身的配置,包括是否壓縮文件、打包成網絡安裝程序或光盤安裝程序、安裝程序的客戶信息、是否加密等等。
2. 同一配置下允許多個版本的存在;一般筆者習慣於當安裝源文件升級的時候,就打包一個新版本出來以示區別,同時也可以保留老
版本的安裝程序備用不時之需。
3. 過濾設置,筆者從來沒用過。貌似是對feature 的一些設置參數,大概是針對某些版本,如果某些feature 不需要的話,就直接過濾掉
了,安裝時候無法選擇安裝了。不過參數具體怎麼設置,包括下面的語言過濾,筆者尚未使用過。但是回想起以前安裝的一些大型
軟件比如Oracle 之類的,會有一些選項是灰色無法選擇安裝的,大概就是類似這種功能。
4. 安裝程序的語言和被安裝的應用程序的語言沒有必然聯繫,因此這裏還需要設置一下安裝時所用的語言。選擇列表裏顯示的語言取
決於在做安裝程序時選擇的語言,剛纔我們只選擇了English,因此這裏只顯示English 了。如果選擇了多項語言,那麼在安裝時出
現的第一個界面會是讓你選擇安裝時所用語言的界面,非常智能。這種功能針對需要發佈到多個語種國家的軟件是非常有用的。不
過這樣的話,在寫腳本的時候,只要是顯示在界面上的語言,除了系統可以默認顯示的,都要多加一個語言判斷,並且顯示不同的
內容了。
5. 選擇介質類型,一般筆者都會把安裝程序刻錄到光盤上,因此選擇 CD-ROM
6. 光盤選項,第一個選項 Automatic 會自動爲你檢測所需光盤的規格數量,以及製作出光盤之間的斷點。我一般都是選第一項,免去
不少囉嗦事,第二個選項應該是高人才會選的吧。
7. 這個選項指定了打包時的形態:
Compress all files:所有的文件都壓縮打包(這裏不包括腳本里所寫的安裝時候從外部拷貝的文件,只包括在Project Assistant 裏指定
到各個feature 下的文件)
Leave files uncompressed and separate from the installation package:所有的文件都不打包,以原始形態存在
Custom:定製,允許你指定一部分壓縮打包,一部分散放。
筆者喜歡把所有的文件都打包,看上乾淨並且專業。
8. 對操作系統的要求,一般都默認即可
9. 這個是 Windows 安裝引擎,對此沒有研究過,憑着上面的解釋選了第二個,會幫你打包進安裝程序,這樣就高枕無憂了。
10. 簽名,目前用不到,有興趣的話可以導入數字簽名文件
11. 密碼和版權聲明。密碼還是算了吧,一個商業軟件是不該這樣設的,客戶會罵死的。
12. 是否要包括.NET Framework,Installshield 看來和微軟很和諧啊。
13. 編譯出來的文件放置的位置,以及一些相關設置,建議長文件名這個選項要選上,以免路徑太深造成不必要的問題。
14. 最後一步,顯示之前所配置的設置,點擊“完成”即可編譯出一個安裝程序來。
15. 編譯好的安裝程序文件應該在 工程路徑/My Project Name/Product Configuration X/Release X/DiskImages/DISK1 下
點擊 setup.exe,就可以安裝了。
這裏順便說一下,這個安裝程序雖然製作好了,但是如果這樣光禿禿地拿給客戶,客戶是要對產品的印象打折扣的。可以使用 Flash 或者其
他的專業光盤製作軟件來製作一個漂亮的應用界面來提供給客戶,在插入光盤的時候自動彈出一個漂亮的使用界面,不但印象深刻,而且客
戶使用起來也方便。
第四部分:補遺
這篇補遺是《一個完整的安裝程序實例—艾澤拉斯之海洋女神出品》的追加敘述,是在這個安裝程序安裝後發現應用程序運行時的一些小問題,通過安裝程序中傳遞參數和設置環境變量來解決掉問題的,與安裝程序本身無關。
這個程序做完之後,工程進入最後的調試階段;裏面發現了兩個問題,其實和安裝程序本身沒有關係,但是都可以通過安裝程序來解決,記錄在此,以備以後碰到此類問題時可以查閱。
1. JAVA_HOME的問題
之前在第二部分的第九小節裏提到了安裝完畢後,爲JDK設置一個環境變量,事實上這個文檔寫到這裏的時候有一點搞錯了先後順序,因爲需要這個環境變量的是第二部分第八小節裏安裝完畢後需要啓動的那個程序,所以後來調試時候發現了,就把第八節的程序內容和第九節的程序內容調換了一下順序。
但是,很快發現了新問題,在註冊表裏添加環境變量和在桌面上“我的電腦”裏直接添加環境變量是不一樣的;註冊表裏的操作,都需要通過重啓動計算機來使之生效,所以矛盾出現了:當這個程序啓動的時候,環境變量還沒有生效;而如果設置了讓計算機重啓動,就必須讓客戶手動啓動這個程序,這是非常不友好的操作。
所以這裏修改了一下方法,首先把需要啓動的程序,也就是一個批處理文件,裏面的
set JAVA_HOME=%JAVA_HOME%
這句話改成了
set JAVA_HOME=%1
在批處理裏面,需要從外部接收參數的時候,可以把參數寫成%1,%2…%n。
然後,在第八小節的程序基礎上修改,把
if (LaunchApp (serviceTarget, "") < 0) then
這句話修改成
if (LaunchApp (serviceTarget, javahome) < 0) then
即可。
2. 代碼解釋
這裏javahome就是第九小節裏if(RegDBSetKeyValueEx(szKey, "JAVA_HOME", REGDB_STRING, svValue, -1)<0) then這句話裏的svValue,即JDK的安裝路徑。
LaunchApp (serviceTarget, javahome)
不能不佩服IS函數設計者,在這篇文檔裏,三個地方用到了LaunchApp這個函數,而且每個用法都不同。
參數一:這裏寫我們要打開的文件,帶相對路徑的
參數二:cmd_line,這裏,我們寫入了JDK的路徑,這個值將作爲參數傳遞給我們要打開的批處理文件,批處理接收到JDK路徑後,便可以正確啓動了。
3. Path的問題
這個問題其實和JavaSerive以及操作系統相關;因爲在筆者的計算機上一直沒有發現這個問題。
在第二部分的第八小節中提到,我們會向Windows安裝一個服務,但是筆者在工程用的計算機上始終不能啓動這個服務,這次這個調試任務推給了經理,他經過多次試驗,發現是環境變量中Path 的問題,只要在Path裏添加上JRE的Bin文件路徑,這個服務就可以正確啓動了。因爲沒有深入瞭解JavaSerive的運行機制和Windows服務的運行機制,也沒有深究爲什麼了,猜想可能是這個服務需要找這個路徑,而有的操作系統只要指定了JAVA_HOME就可以尋找JRE了,而有的卻不行。
閒話休敘,我們需要寫一段程序來實現這個功能。
要注意的地方有以下幾點:
l Path往往已存在,並且裏面有內容,因此不可以像設置JAVA_HOME一樣,而要考慮往已有內容中添加JRE路徑,並且要考慮內容之間的分號問題
l 要考慮到卸載狀態時,不能把Path卸載。說到這個問題,要提一下前面的第九小節,發現引文作者關於卸載時是否卸載自己添加的註冊表鍵值的理解還是不正確的,Help裏關於RegDBSetKeyValueEx有這樣一句話However, the newly created key is not logged for uninstallation unless it is a subkey of a key already logged for uninstallation.也就是新創建的鍵值不會被日誌記錄了要反卸載掉,除非它有子鍵值被日誌記錄了要卸載
程序內容仍然添加在OnEnd()裏,寫在最後,如下:
szKey = "SOFTWARE//JavaSoft//Java Runtime Environment//1.6.0_04";//jre的鍵
RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE);//設置一下根鍵
if (RegDBKeyExist(szKey)=1) then//如果這個鍵存在
if(RegDBGetKeyValueEx(szKey,"JavaHome",nvType,svValue,nvSize)=0) then //查找這個鍵的值
javaPath= svValue;
endif;
endif;
**************************************以上爲第一部分,以下爲第二部分
//wirte the environment variable PATH
szKey = "SYSTEM//CurrentControlSet//Control//Session Manager//Environment"; //環境變量在註冊表中所在位置
javaPath=javaPath+"//bin";//jre/bin的路徑
if(RegDBGetKeyValueEx(szKey,"Path",nvType,svValue,nvSize)=0)then//如果Path存在
if(svValue!="") then
if(StrFind ( svValue, javaPath )<0) then//如果path還沒有jre/bin的路徑信息
svValue=svValue+";"+javaPath; //添加路徑信息,此時要帶上分號
endif;
else
svValue= javaPath;//如果鍵值爲空,則直接添加即可,事實上鍵值爲空的情況不會出現,這句話是無用的判斷
endif;
else
svValue= javaPath; //如果沒有這個鍵值,把值也直接添加進去,事實上這個情況也不會出現,因爲path在操作系統安裝完畢後就存在了,//除非你手動刪除了,但是那樣操作系統也會有問題了
endif;
if(!MAINTENANCE)then
Disable(LOGGING);
if(RegDBSetKeyValueEx(szKey, "Path", REGDB_STRING_EXPAND, svValue, -1)<0) then//添加或者重設鍵值
MessageBox ("Path create failed, please set it manually!", SEVERE);
endif;
Enable(LOGGING);
endif;
4. 代碼解釋
第一部分的目的在於找出JRE的安裝路徑,所有的函數之前都有解釋,不再贅述
第二部分:
szKey = "SYSTEM//CurrentControlSet//Control//Session Manager//Environment";
環境變量,位於註冊表的這個位置
*************************************************************************
javaPath=javaPath+"//bin";
需要尋找的是JRE下的bin文件
*************************************************************************
if(RegDBGetKeyValueEx(szKey,"Path",nvType,svValue,nvSize)=0)then
如果Path存在並返回了值。
這裏其實如果加上一個判斷此鍵是否存在,代碼會更加完善,不過操作系統裝完之後這個鍵是一定存在的,這裏筆者偷懶了
*************************************************************************
if(StrFind ( svValue, javaPath )<0) then
判斷返回的鍵值裏是否包含jre的bin文件夾的路徑
StrFind(szString, strFineMe)
在源字串裏查找是否包含指定的字串
參數一: szString,被查找的源字串
參數二:strFineMe,要查找的字串
如果包含要查找的字符串,則返回要查找的字符串在源字符串裏的位置;如果查找不到則返回小於0的隨機數字
*************************************************************************
if(!MAINTENANCE)then
判斷一下安裝狀態,使之只有在非維護(修改,重新安裝,卸載)狀態使起作用
*************************************************************************
Disable(LOGGING);
Enable(LOGGING);
這兩句話作用分別是停止日誌記錄和使日誌記錄重新生效,這是從網上的一篇心得裏抄錄的,當日志停止記錄時候,安裝程序就無視了停止日誌後的所有操作,這樣保證鍵值不會在反安裝時候被操作;其實本來上面一句if(!MAINTENANCE)then(非維護狀態時操作)在原文是沒有加上去,作者說只要不讓日誌記錄到操作註冊表,這個操作就不會被反安裝掉,不過好像自己試了一下不行,加上一句,比較保險些,至少試驗出來是沒問題的。
*************************************************************************
if(RegDBSetKeyValueEx(szKey, "Path", REGDB_STRING_ EXPAND, svValue, -1)<0)
寫註冊表的鍵值。
Help裏RegDBSetKeyValueEx的對應幫助裏有這樣一句話If the value data already exists, RegDBSetKeyValueExoverwrites it,也就是,如果鍵值存在,那麼覆蓋它。不過對註冊表操作後,要把計算機重新啓動才能生效;這一點和我們直接在“我的電腦”裏操作環境變量是不一樣的。
這裏,第三個參數改成了REGDB_STRING_ EXPAND,因爲在Windows 2003server下,path含有一個%SystemRoot%的相對路徑,當時一開始使用了REGDB_STRING,結果無意中發現所有的dos命令都用不了了,在dos下輸入path一看,該替換成絕對路徑的地方都沒有替換掉,當時也是一頭霧水,上CSDN一問,有人提醒說我應該看一下IS程序裏鍵值設置時候的類型問題,跑回來一看果然設置有問題,REGDB_STRING是不認識相對路徑的,換成REGDB_STRING_ EXPAND就可以了。
5. 文件的只讀性問題
用光盤裝程序的時候發現一個問題,當從光盤上拷貝出文件的時候,文件會默認爲只讀格式,導致配置文件不能正常存儲數據庫信息,因此,在安裝程序代碼裏拷貝完文件後,指定一下文件的屬性
SetFileInfo ( szPathFile, nType, nAttribute, szValue );
此處用作SetFileInfo ( szPathFile, FILE_ATTRIBUTE, FILE_ATTR_NORMAL, "" );
海洋女神博客http://www.cnblogs.com/Cindy_weiwei/archive/2009/05/19/1460261.html