(1)問:Windows Installer是一種什麼樣的產品?
答:Windows Installer是一種系統服務,用來安裝和管理系統中的應用程式。它為應用程式的開發、定製、安裝和升級提供了一種標準化的方法和手段。
(2)問:Windows Installer都提供了哪些準系統?
答:Windows Installer提供了以下準系統:
--事務型操作。所有的安裝操作都是事務形式的。對於Windows Installer執行的每項操作,它都會產生一個對應的撤銷(Undo)操作,以便在需要時撤銷使用者對系統所做的修改。如果在安裝過程中發生了一個錯誤,Windows Installer可以將系統還原回進行安裝前的狀態。
--自我治癒。Windows Installer支援應用程式的“自我治癒”能力。應用程式可以在啟動時檢查各種常見的安全問題,例如檔案或註冊表鍵丟失問題,並且可以自動修複自己。
--按需安裝。Windows Installer支援應用程式的按需安裝。例如,Microsoft Office Word的拼字檢查功能在預設情況下不會被安裝,但是使用者也可以根據需要安裝該功能。
--在“鎖定”環境下的安裝。在全面鎖定的環境中,使用者一般沒有安裝應用程式所需的許可權或能力。在大多數情況中,他們沒有對電腦“Program Files”檔案夾或者HKEY_LOCAL_MACHINE註冊表位置的“寫”許可權。例如,如果管理員通過組策略允許使用者安裝某個程式包,Windows Installer便可以代表使用者進行程式的安裝。
--狀態管理。Windows Installer為應用程式提供了一組標準的Win32? API(API)和自動化介面,管理員可以使用它們查詢程式在電腦中的安裝狀態。API能夠查詢程式的目前狀態,校正現有狀態,或者修複受損的狀態,並且能夠從一種狀態過渡到另一種狀態。
(3)問:Windows Installer V2.0是該產品的最新版本。2.0版本提供了哪些新增功能和改進功能?
答:同先前版本相比,2.0版本的Windows Installer包括了大量的新增特性和改進特性,例如:
--組件的安裝和管理。Windows Installer 2.0與SxS(Fusion)和Common Language Runtime(CLR)組件完全整合。.
--更高的安全性。Windows Installer的體繫結構經過修改,具有更高的安全性。
--隱藏個人資訊的能力。Windows Installer為作者提供了一種在記錄檔中隱藏資訊(例如口令)的方法。
--多個使用者間的隔離。對Windows Installer架構所做的修改實現了每個使用者安裝的真正隔離,因為每個使用者對產品進行的配置不再在多個使用者間進行共用。
--對數位簽章的支援。數位簽章支援已經包括在有關Windows Installer的檔案之中,例如軟體包(.msi)、補丁(.msp)和轉換(.mst)。Windows Installer還能夠對與安裝有關的外部.cab檔案進行數位簽章驗證。
--更健壯的補丁。2.0版本修正了眾多的補丁問題。
--簡化了補丁的製作過程。在2.0版本中,補丁衝突問題的圓滿解決消除了使用者在製作補丁過程中的一些負擔。針對2.0版本開發安裝程式的製作人員不再需要跟蹤每一個磁碟ID和先前補丁使用的最後一個序號。
--改進了補丁和升級檔案的安裝過程。2.0版本減少了不必要的來源程式解析嘗試。在大多數情況下,當應用某個補丁的時候,使用者不再被要求訪問原始程式的位置,除非補丁和升級檔案的製作者特彆強調這一點。此外,由於無需複製那些和版本變化無關的檔案,升級過程的效率也提高了。
--支援轉化和來自URL源的補丁。Windows Installer的2.0版本現在允許使用轉化和來自URL(統一資源定位器)的補丁。
--作業系統特性的增強。與系統還原和軟體限制策略(Windows? XP的功能特性)整合在一起,並且改善了對終端服務的支援。
--64位Windows上的64位服務。Windows Installer是一個天生的64位服務,能夠64位版本的Windows上安裝64位的應用程式。
--得到增強日誌記錄能力。事件的日誌記錄已經得到了極大的改進,以便協助技術人員解決安裝過程中出現的問題。這包括確保每一個不同的錯誤都擁有一個獨一無二的事件ID。
--可配置的合併模組。經過改進的MergeMod.dll允許使用者製作合併模組(.msm檔案),這些檔案包含一些屬性,能夠由合併模組的使用者加以配置。
(4)問:我可以從哪裡獲得有關Windows Installer的更多資訊?
答:有關Windows Installer的更多資訊可以在Windows Installer軟體開發套件(SDK)中找到。
有關Windows Installer的進一步資訊還可以通過以下白皮書獲得:
--Windows Installer服務概述
--Windows Installer:優點以及具體實現過程
(1)問:哪些版本的Windows包括了Windows Installer?
答:Microsoft Windows 2000、Windows Millennium Edition(Windows Me)以及Windows XP 包括了Windows Installer。Windows 2000包括了1.1版本的Windows Installer,Windows Me 包括的是1.2版本,而Windows XP包括的Windows Installer則為2.0版本。Windows 2000 SP3 也包含了2.0版本的Windows Installer。
(2)問:Windows Installer支援哪些作業系統?
答:下表詳細介紹了每個版本的Windows Installer所支援的作業系統。
(3)問:我可以從何處獲得最新版本的Windows Installer再分發程式?
答:您可以通過Microsoft Platform SDK Redistributables網站獲得最新版本的Windows Installer再分發程式,Windows Installer的再分發程式有兩個不同的版本:一個適用於Windows 95、Windows 98和Windows Me;另一個適用於Windows NT和Windows 2000。
(4)問:我需要在我的安裝程式中再次分發這些技術,我可以從哪裡獲得針對Microsoft技術的合併模組?
答:Microsoft合併模組隨同Microsoft Visual Studio .NET一同提供。它們的預設安裝位置為 [ProgramFilesFolder]/Common Files/Merge Modules。請注意:並不是所有的Microsoft再分發組件都有可用的合併模組。
(1)問:我應該怎樣在'添加或刪除程式'中隱藏某個應用此程式?
答:為了在'添加或刪除程式'中隱藏某個應用程式,請將ARPSYSTEMCOMPONENT屬性設定為1。該屬性可以在命令列、在程式包的'屬性'表中設定,或者通過轉換進行設定。在Windows 2000以前的作業系統上,可以通過將ARPNOREMOVE屬性設定為1 來在'添加或刪除程式'中隱藏應用程式。在Windows 2000和Windows XP作業系統中, ARNOREMOVE可以禁用'添加或刪除程式'中的'刪除'按鈕。
(2)問:在Orca中對我的.msi程式包進行多次編輯之後,程式包的體積顯著增加了。我應該怎樣減小.msi檔案的大小呢?
答:.msi程式包的資料庫格式是建立在OLE結構化儲存基礎上的。頻繁對資料庫進行編輯回導致片段的出現,並因此浪費一些空間。您可以通過在Orca中使用'另存新檔'命令減小.msi程式包的大小。或者,您也可以使用msidb.exe匯出所有表,然後再將這些表重新匯入到一個建立的資料庫中,以便減小程式包的體積大小。
Orca和msidb.exe工具可以通過Windows Installer SDK獲得。
(3)問:如何在安裝期間隱藏'取消'按鈕?
答:從Windows Installer 2.0開始,我們提供了一個命令列選項,以便在顯示簡單的安裝介面(UI)時,隱藏'取消'按鈕。以下命令列指令碼示範了這個新選項的使用方法:
msiexec /i {path to package} /qb!
此外,您還可以使用MsiSetInternalUI Win32 API並結合使用INSTALLUILEVEL_HIDECANCEL和INSTALLUILEVEL_BASIC來隱藏'取消'按鈕。或者,在使用Windows Installer對象的讀寫UILevel屬性時,您可以結合使用msiUILevelHideCancel和msiUILevelBasic,通過Windows Installer自動化來實現這一目的。
在程式安裝期間,'取消'按鈕的存在與否可以通過一個DLL或者指令碼定製操作加以改變,該操作會發送一個INSTALLMESSAGE_COMMONDATA訊息。DLL定製操作使用MsiProcessMessage Win32 API發送INSTALLMESSAGE_COMMONDATA訊息,在該訊息中,記錄的欄位1被設定為'2',而欄位2被設定為'0'。為瞭解除'取消'按鈕的隱藏狀態,您可以仍然使用這個訊息,但是請將欄位2設定為'1'。指令碼定製操作使用會話對象的等效訊息(Message)方法。
(4)問:我怎樣才能只安裝那些我希望使用的功能特性?
答:您可以使用ADDLOCAL、ADDSOURCE和ADVERTISE屬性安裝某些特定的功能特性。以下命令列指令碼可以將example.msi程式包中的'Sports'(體育)和'News'(新聞)特性安裝在本機電腦上。
msiexec /i example.msi ADDLOCAL=Sports,News /qb
以下命令列指令碼可以通告'Sports'特性和安裝'News'特性,以便從來源程式運行這些特性。
Msiexec /i example.msi ADVERTISE=Sports ADDSOURCE=News /qb
另一個重要的注意事項是:功能特性的名稱是大小寫敏感的。
(5)問:我怎樣在升級期間強制升級一個和版本無關的檔案,即使使用者已經修改了該檔案?
答:通過在'檔案'(File)表中為檔案製作一個版本號碼,您可以在升級期間'強制升級'一個和版本無關的檔案。根據Windows Installer的檔案版本控制原則,版本發生變化的檔案將覆蓋一個和版本無關的檔案。需要注意的是:所有的後續重新安裝過程都需要訪問來源程式,因為所有的後續版本檢查都會指出檔案需要被重新安裝。
(6)問:我怎樣才能正確地書寫路徑字串?
答:目錄屬性值以一個目錄分隔字元結束。因此,路徑字串的書寫不要求使用目錄分隔字元。
錯誤寫法:[DirectoryProperty]/someLocation
正確寫法:[DirectoryProperty]someLocation
(7)問:我應該怎樣為不同的地理地區開發產品?
答:對於擁有不同版本的產品--這種不同既可以是產品語言上的不同,也可以是產品功能間的差異,您可以使用不同的產品代號。以便指明方向、熟悉產品間的關係,並且讓產品共用相同的升級代碼。
(1)問:何謂受管理應用程式?
答:受管理應用程式是一種管理員能夠在程式的安裝和維護期間對其施加某種控制的程式。受管理應用程式經常用來進行大規模的軟體部署。對於系統管理員來說,受管理應用程式為他們允許使用者在一個'鎖定'環境中安裝授權軟體提供了方便,在這個環境之中,使用者一般沒有安裝軟體所需的許可權。
如果滿足以下條件,一個應用程式將被認為是受管理的:
可以由(管理員)組的成員為使用者進行安裝或宣告。
可以由Administrators組的成員以電腦為基礎進行安裝和宣告。
可以由管理員在Windows 2000或更高版本的作業系統上進行指派或發布。
可以被其它軟體或部署管理系統標記為受管理程式。具體方法取決於使用者使用的管理系統,但是一般需要由管理員完成這項操作。
安裝程式包不能自己宣稱自己是'受管理'的,該程式是否為一個'受管理'程式是由系統管理員進行控制的。
請注意:'受管理'和'許可權提升'不同。經過許可權提升的應用程式是指在安裝之時利用系統許可權進行啟動並執行程式。所有的受管理應用程式都是許可權提升程式,但是許可權提升程式卻不一定是受管理程式,這是由AlwaysInstallElevated 策略來決定的。出於安全性的考慮,該策略在預設情況下處于禁用狀態,在使用此策略之前,請務必對其可能造成的危害加以認真考慮。
(2)問:AdminUser和Privileged 屬性有何不同?
答:如果執行安裝操作的使用者是一個管理員,AdminUser屬性將被設定;如果允許使用者利用經過較高的權限來安裝程式,Privileged屬性將被設定。如果使用者是一位管理員,使用者可以利用經過較高的權限安裝程式,無論您是按照使用者還是按照電腦設定AlwaysInstallElevated策略,或者,程式已經被系統管理員指派給使用者了。
如果使用者是管理員,那麼AdminUser和Privileged屬性都會被設定。如果使用者不是管理員,那麼AdminUser屬性將永遠不會被設定。在這種情況下,如果使用者已經由管理員通過指派或策略賦予了安裝程式所需的提升許可權,那麼Privileged屬性將是唯一被設定的屬性。
在很多情況下,我們都建議:無論是啟動條件或者是類似條件,都使用Privileged屬性代替AdminUser屬性來安裝由管理員指派的應用程式。
(3)問:應該允許具有使用者級許可權的使用者安裝MSI程式嗎?
答:如果管理員允許,具有使用者級許可權的使用者可以安裝受管理的應用程式。否則,使用者只能安裝那些寫入檔案、建立目錄和寫註冊表鍵的位置與使用者擁有的許可權相符的MSI應用程式。如果使用者不能在某個位置進行寫入操作,那麼除非管理員為安裝程式賦予了寫入許可權,否則安裝程式將不能在該位置寫入資料。
(1)問:'延遲'定製操作和'立即'定製操作有何不同?
答:'延遲'定製操作僅僅能夠以執行後續表中的InstallInitialize或InstallFinalize操作作為其後續操作。而'立即'定製操作可以以後續表中的任何地方作為其後續操作。
'延遲'定製操作不能訪問安裝資料庫。事實上,'延遲'定製操作只具有十分有限的安裝會話訪問能力,因為安裝指令碼可以在建立該指令碼的安裝會話的外部執行。'立即'定製操作可以訪問安裝資料庫,並且可以讀取和設定安裝屬性,修改特性和組件狀態,以及添加臨時行、臨時列和暫存資料表等其它東西。
儘管'延遲'和'立即'定製操作都可以運行在初始化安裝操作的使用者上下文環境中,但是只有'延遲'定製操作可以使用系統上下文環境以得到較高的權限運行。
'延遲'定製操作不能夠立即執行。相反,它們按照預先設定的議程在指令碼執行期間運行。在InstallExecute、InstallExecuteAgain或InstallFinalize操作運行之前,執行指令碼並不會被處理。
(2)問:我什麼時候應該使用延遲定製指令碼,而不是使用立即定製指令碼?
答:如果定製操作必須修改系統或者調用另一個系統服務,那麼您必須使用延遲定製指令碼。此外,只有延遲定製操作能夠運行經過許可權提升的上下文環境中。如果您的定製指令碼需要經過較高的權限才能運行,那麼您需要將定製指令碼標記為'延遲'指令碼。注意:只有在安裝程式自身經過許可權提升的情況下,標記為在系統上下文環境(msidbCustomActionTypeInScript + msidbCustomActionTypeNoImpersonate)中啟動並執行定製操作才能夠運行。
此外,如果希望通過定製操作對系統進行修改,您還應該包括一個復原定製操作,以便撤銷修改,將系統還原回先前狀態。
(3)問:如何向我的延遲定製指令碼提供資料?
答:延遲定製操作只能對安裝會話進行有限訪問。如果您的延遲定製操作無法通過這種有限的訪問擷取到有關安裝的資訊,您可以通過CustomActionData屬性為延遲定製操作提供這些資訊。這種方法僅僅對指令碼和DLL延遲定製操作有效。其具體工作方式如下:
在延遲定製操作之前執行的立即定製操作會使用與延遲定製操作所使用的相同名稱將某個屬性設定為延遲定製操作需要的值。所以,如果延遲定製操作的主鍵名稱為'DeferredCA',那麼立即定製操作將把名為'DeferredCA'的屬性設定為延遲定製操作需要的值。類型51的定製操作可以很容易地設定該屬性。另一種方法是:立即定製操作使用'szName'參數調用MsiSetProperty,其中szName參數等於'DeferredCA'。注意:操作名稱是大小寫敏感的。
當延遲定製操作排隊進入安裝指令碼之後,安裝程式將會把 'DeferredCA' 屬性值寫入到安裝指令碼之中,並用它作為CustomActionData屬性的值。
在執行時,延遲定製指令碼通過調用帶有szName參數的MsiGetProperty來獲得所需的值,其中szName參數等於CustomActionData。或者,指令碼定製操作會使用會話(Session)對象的'Property'屬性。
(4)問:我能夠使用定製操作重新啟動電腦嗎?
答:通過使用MSIRUNMODE_REBOOTATEND或MSIRUNMODE_REBOOT的運行模式以及等於'TRUE'的狀態值調用MsiSetMode,立即定製操作可以重新啟動電腦。因為MsiSetMode 需要一個hInstall控制代碼,所以只有DLL和指令碼定製操作能夠重新啟動電腦。指令碼定製操作將使用'會話'對象的'模式'屬性。或者,立即定製操作也可以使用等於'ScheduleReboot'的szAction參數調用MsiDoAction。
延遲定製操作不能調用MsiSetMode。延遲定製操作需要對註冊表某個位置的值進行設定,該值會被立即定製 操作和隨後的InstallFinalize讀取。然後,立即定製操作可以使用MsiSetMode設定電腦的重新啟動議程。如果需要使用該方法,您還應該提供一個復原定製操作,以便在取消安裝時,從註冊表中刪除能夠觸發重新啟動的該索引值。
(5)問:我的定製操作應該如何向記錄檔添加資訊?
答:通過使用MsiProcessMessage API發送INSTALLMESSAGE_INFO訊息,DLL和指令碼定製操作可以向記錄檔添加資訊。指令碼定製操作將使用'Session'(會話)對象的'Message'(訊息)方法。
(6)問:為什麼在安裝程式時,會有多個MSIExec.exe進程運行在我的電腦上?
答:在程式安裝期間,會有多個MSIExec進程運行。之所以會出現這種現象,主要是因為Windows Installer使用了客戶機-伺服器模式來執行程式安裝任務。此外,出於安全方面的考慮,Windows Installer會在一個'沙箱'(sandbox)進程中駐留DLL和指令碼定製操作。根據安裝過程初始化方式的不同,一個MSIExec進程將作為客戶機進程。另一個MSIExec進程將作為Windows Installer服務。在電腦上啟動並執行所有MSIExec進程通常都是用來託管定製操作的沙箱進程。決定哪一個MSIExec進程將作為面向指令碼或DLL定製操作的沙箱進程的具體過程部分取決於定製操作是以經過較高的權限運行還是以人格化的方式運行,以及該定製操作是32位的還是64位的。
1)問:小型、次要和主要升級之間有何不同?
答:'小型'升級是一種只對很少的檔案進行修改或者只增加少量新內容的產品升級。'次要'升級是對產品進行的修改足以改變產品版本號碼的產品升級,而'主要'升級則是對產品進行了大量修改,以致需要修改產品代號的產品升級活動。下表總結了每一種升級方式所做的產品修改內容以及每種升級方式可能使用的分發載體形式。
在某種程度上,您可以將一個小型升級看作是一個'熱修補'或者'重點補充工程'(Quick Fix Engineering,QFE)升級,將次要升級看作服務包,而將主要升級看作是產品升級。
除了次要升級會改變產品版本號碼而小型升級不會改變版本號碼之外,小型升級和次要升級可以被認為是基本相同的。它們所遵循的原則和補丁程式都是相同的。小型升級和次要升級的應用程式都需要進行明確的重新安裝。主要升級則不受此限制,補丁程式不需要重新安裝。此外,小型升級和次要升級的補丁程式對程式包的功能組件結構所做的修改比較有限。而主要升級則會對程式的功能組件結構進行顯著的修改。
(2)問:什麼時候補丁程式會需要原始源檔案?
答:Windows Installer 2.進行了大量改進,以便將補丁程式需要原始源檔案的次數降低到最少。但是,在以下一些特殊情況下,它仍然會需要原始源檔案:
--應用於某個功能特性的補丁當前正在源檔案中運行。在這種情況下,該特性會從'run-from-source'狀態過渡到本地狀態。
--需要應用補丁的組件出現了問題(檔案丟失或者受到損害)。
--需要應用補丁的檔案在一個組件之中,該組件還包含一些與版本變化無關的檔案,並且沒有MsiFileHash項目。需要一個經過填充的MsiFileHash表,以防止從源位置重新複製這些與版本變化無關的檔案。
--補丁應用時帶有一個值為'amus'的REINSTALLMODE選項。該選項比較危險,因為它會忽略檔案的版本對檔案進行複製。從而導致對較早的檔案進行修訂,所以它總是需要源檔案。我們建議將REINSTALLMODE的值設定為'omus'。
--產品的緩衝程式包丟失了。經過緩衝的程式包對於補丁程式來說是必需的。這個緩衝下來的程式包儲存在'%windir%/Installer'檔案夾中。
--程式包被設計為需要調用ResolveSource操作。該操作一般應該被盡量避免,或者僅僅用在某些特定的條件下,因為執行該操作總是會導致系統訪問源檔案。
--程式包擁有一個定製操作,該操作試圖通過某種方式訪問源檔案。
--補丁程式包由二進位的補丁檔案組成,這些檔案不能應用到電腦檔案的目前的版本之上。請看以下樣本:
1.安裝樣本產品的RTM版本。這會將1.0版本的Example.dll安裝到電腦中。
2.在電腦上應用補丁程式qfe1.msp。該補丁將Example.dll的版本從1.0升級到1.1。
3.新的補丁qfe2.msp已經發布,它可以將Example.dll升級到1.2版本。但是,該補丁僅僅適用於Example.dll的1.0版本,因為它是利用該產品的RTM製作產生的。1.2版本的Example.dll包括了Example.dll 1.1版本中的所有修補,但是MSP是在RTM和QFE2映像間產生的。所以,如果在電腦上應用qfe2.msp,Windows Installer將需要訪問原始的源檔案。example.dll的二進位補丁不能應用到1.1版本上;它只能應用於1.0版本。這會使安裝程式重新從原始的源檔案位置複製1.0版本的example.dll,以便補丁能夠成功得到應用。
(3)問:我怎樣才能防止我的補丁程式需要訪問源檔案?
答:目前,您還無法完全阻止補丁程式訪問源檔案,但是,以下步驟可以協助您減少程式訪問源檔案的次數:
--使用只包含完整檔案的補丁。這使得補丁建立程式無需根據每個先前發布的補丁程式和產品的RTM版本建立二進位補丁。通過將Patch Creation Properties(補丁建立屬性,PCP)檔案的'Properties'(屬性)表中的IncludeWholeFilesOnly屬性的值設定為'1',您可以輕鬆製作出僅僅包含完整檔案的補丁。
--確保您所有的定製操作都不會訪問原始的源檔案位置。
--確保ResolveSource 操作只有在特定條件中才會執行,或者根本不存在此操作。
--為程式包中所有與版本變化無關的檔案建立'MsiFileHash'表。Windows Installer SDK包括了一個名為'MSIFiler.exe'的工具和一個名為'Wifilver.vbs'的指令碼,它們可以自動完成這項工作。
(4)問:為什麼雖然我的補丁成功應用到了電腦上,但是檔案卻沒有被升級?
答:這很可能是因為您簡單地雙擊了一個小型或次要升級補丁。小型升級或者次要升級的補丁程式需要對將要升級的檔案執行一次明確的重新安裝過程。您可以使用MSIExec命令列完成這個工作,並且將REINSTALL和REINSTALLMODE屬性包括在命令列命令之中(也就是:msiexec /p {path to my patch.msp} REINSTALL=ALL REINSTALLMODE=omus)。另一種方法是:在補丁中包括一個定製操作,對REINSTALL和REINSTALLMODE屬性進行相應的設定。您應該確信您對該操作的執行條件進行了嚴格的限制,只在補丁程式的第一次應用期間執行。產品的後續重新安裝不應該導致該定製操作的執行,否則您的產品可能會變得無法卸載。其它方法包括使用一個啟動執行檔案並利用正確的屬性設定調用MsiApplyPatch,或者使用Windows InstallerAutomation 物件,使用指令碼編寫補丁應用程式。
(5)問:我能通過補丁升級一個定製操作嗎?
答:可以,您可以使用補丁升級某個定製操作。如果定製操作包括在 'Binary'(二進位)表中,那麼您可以簡單地對升級安裝映像中的定製操作進行升級。如果您使用原始檔案和升級安裝映像製作補丁程式,該補丁將包含一個資料庫轉換,將老的位元據流轉換成新的位元據流。
(1)問:我如何才能找出程式包安裝失敗的原因?
答:有三種比較好的方法可以對程式包的安裝問題進行跟蹤。第一種方法是通過運行校正確信您的程式包合法有效。通過進行驗證,您可以發現錯誤和警告,並找出一些常見的安裝程式製作問題。有兩個工具可以對安裝程式包進行驗證,這兩個程式都可以通過Windows Installer SDK獲得:MsiVal2和Orca。MsiVal2是一個用來校正程式包的命令列工具。Orca則為驗證提供了一個圖形化的使用者介面,並且可以反白程式包中的無效實體。
第二種方法是使用應用程式事件記錄檔。Windows Installer會把成功和失敗資訊記錄在應用程式事件記錄檔當中。
最後一種方法是產生一個詳細記錄檔。然後分析該詳細記錄檔,並從中找出錯誤的根源。Windows Installer SDK提供的WILogUtl.exe工具可以協助您分析詳細記錄檔。 日誌記錄可以通過Windows Installer日誌記錄策略加以啟用,或者,您也可以通過在MSIExec命令列中附加'/L*v path to logfile'來啟用該功能。
為了通過策略獲得詳盡的詳細記錄檔, 請使用如下註冊表鍵:
HKLM/Software/Policies/Microsoft/Windows/Installer
設定:Logging = REG_SZ voicewarmup
設定:Debug = REG_DWORD 0x7
通過策略鍵產生的記錄檔將以msiXXXXX.log的格式儲存在使用者的'%temp%'檔案夾中。
注意:通過命令列產生的日誌記錄比所有的日誌記錄原則設定擁有更高的優先順序。
(2)問:在我每次啟動程式的時候,Windows Installer都會執行安裝操作。我怎樣確定產生這種按需安裝的原因是什嗎?
答:有一種方法可以容易地確定引起按需安裝的原因,那就是:在應用程式事件記錄檔中尋找以下格式的MsiInstaller日誌資訊:
事件類型:警告
事件來源:MsiInstaller
事件ID:1001
描述:
檢測產品'{000C1109-0000-0000-C000-000000000046}',特性'Example' 在請求組件'{00030829-0000-0000-C000-000000000046}'時發生失敗
事件類型:警告
事件來源:MsiInstaller
事件ID:1004
描述:
檢測產品'{000C1109-0000-0000-C000-000000000046}',特性'Example',組件'{00030829-0000-0000-C000-000000000046}'失敗。資源'C:/Progam Files/example/example.exe'不存在。
第一條資訊(事件ID為1001)說明了哪一個組件正在被安裝。此處列出的組件是在針對特殊捷徑的Shortcut(捷徑)表中的Component(組件)列中所指定的組件。
第二條資訊(事件ID為1004)指出了哪一個組件在檢測時發生失敗。Windows Installer 2.0經過改進的事件記錄功能已經對資訊進行了更新,以便在大多數情況下,使用者都可以通過事件資訊尋找出導致檢測失敗的真正問題根源。 如果組件的鍵路徑(Keypath)丟失或者受損,可能會導致使用者重新安裝程式。
在上例中,使用者需要重新安裝程式,因為資源'c:/Program Files/example/example.exe'不存在。您應該找出導致鍵路徑不存在的原因所在--在本例中,是因為使用者刪除了該檔案。
(3)問:我怎樣才能確定Windows Installer是否安裝了我的功能特性或組件?
答:確定Windows Installer是否安裝了某個特定功能或組件的方法十分簡單。您可以通過Windows Installer的verbose記錄檔找到答案。您首先需要尋找的是InstallValidate操作的日誌資訊。該操作將會把程式包中每個功能和組件的安裝、請求和操作狀態記錄下來。
MSI (s) (5C:F4): 執行操作: InstallValidate
操作開始 1:51:18: InstallValidate.
MSI (s) (5C:F4): 功能: Example; 安裝: 缺席; 請求: 本地; 操作: 本地
MSI (s) (5C:F4): 組件: Example; 安裝: 缺席; 請求: 本地; 操作: 本地
操作結束 1:51:18: InstallValidate. 傳回值 1.
在上述記錄檔片斷中'Example'功能將在本地進行安裝,因為它的操作狀態為'本地'此外,組件'Example'也將根據給定的操作狀態進行本地安裝。
(4)問:為什麼我的檔案在卸載過程中沒有被刪除?
答:產生這個問題的原因主要有四種:
這些檔案所屬的組件被標記為'永久'(permanent)。(這一點可以通過Component表的Attributes列來實現)
這些檔案所屬的組件沒有一個擁有組件GUID。(位於Component表的ComponentId列的該值為NULL)。Windows Installer無法管理那些沒有GUID的組件。
如果組件的鍵路徑(keypath)擁有一個共用的DLL refcount,那麼該組件將不能被卸載。
如果該組件安裝在系統檔案夾中,而且在程式卸載之時,組件中的某一個檔案擁有一個外部共用的DLL refcount,那麼該組件將不能被卸載。
(5)問:為什麼我的檔案夾在程式卸載時沒有被刪除?
答:導致檔案夾在程式卸載過程中不能被刪除的原因主要有以下幾種:
在同時使用CreateFolder表和CreateFolders操作時,執行順序表中的RemoveFolders操作丟失。
該檔案夾不是由Windows Installer建立的檔案夾,因此它不會刪除它們,除非您告訴Windows Installer刪除這些檔案夾。
檔案夾中仍然存在資源。
(6)問:為什麼我的註冊表鍵在程式卸載是沒有被刪除?
答:導致程式卸載時註冊表鍵沒有被刪除的最常見原因有以下幾種:
1. Registry(註冊表)表包含了帶有'+'標記的實體。該符號將指示Installer在卸載程式時保留這些註冊表鍵。
2. 在InstallExecuteSequence表中,RemoveRegistryValues操作位於UnregisterProgIdInfo和 UnregisterMIMEInfo操作之後。您需要反轉這些操作的順序。Registry表所寫入的某些註冊表索引值會阻止特定的ProgId、擴充和CLSID 鍵被刪除。
(7)問:為什麼安裝過程所佔用的磁碟空間遠遠大於我實際安裝的檔案尺寸?
答:Windows Installer會計算兩種類型的磁碟佔用:帶有復原操作的磁碟佔用;以及沒有復原操作的空間佔用。沒有復原的空間佔用是程式安裝實際佔用的磁碟空間。帶有復原操作的空間佔用包括了在安裝過程中為復原操作提供支援所需的備份檔案所佔用的空間。此外,Windows Installer還會計算出執行安裝操作所需的一些額外空間佔用。其中包括安裝指令碼所需佔用的空間以及緩衝程式包的空間需求。此外,在安裝期間,Installer需要對安裝程式包進行臨時複製。安裝指令碼和程式包運行副本所佔用的空間是臨時性的。在安裝結束之後,這些檔案將會被清除。請看以下樣本,在本例中,您的安裝程式包的大小約為80KB,而您正在安裝一個4 KB的檔案。(注意:根據硬碟簇大小的不同,您的數字與我的可能會有所不同):
89120位元組(被緩衝的MSI,基本上是4 KB簇大小的整數倍)
89120位元組(MSI的臨時工作複本)
8192位元組(估計的指令碼大小)
4096位元組(小檔案,與大小為4 KB磁碟簇基於相等)
----------------------
176128位元組 = 172 KB
(8)問:為什麼Windows Installer提示我重新啟動電腦?
答:如果Windows Installer需要覆蓋一個正在使用的檔案,或者安裝程式包明確要求Installer重新啟動電腦,那麼Windows Installer將會提示您重新啟動。我們可以很容易地判斷出Windows Installer是否是因為需要覆蓋一個正在使用的檔案而提示您重新啟動電腦。我們首先需要產生一個詳細記錄檔。在這個詳細記錄檔中,在屬性部分中尋找是否存在ReplacedInUseFiles屬性。如果該屬性存在,並且值為1,那麼Installer將會因為需要覆蓋一個正在使用的檔案而提出重新啟動電腦的請求。
為了確定哪一個檔案正在被使用,請掃描記錄檔,尋找'Info 1603'和'Info 1903'資訊1603資訊由InstallValidate操作記錄在記錄檔中。例如:
MSI (s) (DC:DC): 執行操作: InstallValidate
操作開始 19:55:42: InstallValidate.
…
Info 1603. 檔案'd:/test/sample.exe'正在被以下進程使用:名稱:sample.exe,Id: 4068,視窗標題:'Sample'。請關閉該程式,然後再試。
一般情況下,出現該訊息的同時,也會出現'FilesInUse'(檔案正在使用)對話方塊。但是在使用'安靜'UI的情況下,該對話方塊不會出現。此外,並不是所有正在被使用的檔案都會出現在'FilesInUse'對話方塊中。如果處於使用狀態的檔案不是一個可執行檔,持有這些檔案的進程是一個與安裝過程有關的進程,或者持有檔案的進程沒有一個與之相關的視窗標題,'FilesInUse'對話方塊都可能不會顯示。
安裝指令碼中的FileCopy opcode也會將Info 1603資訊記錄在日誌中。在上例中,記錄檔包含:
MSI (s) (DC:DC):Executing op: FileCopy(SourceName=sample.exe, SourceCabKey=sample.exe, DestName=sample.exe, Attributes=0, FileSize=2044928, PerTick=32768, , VerifyMedia=1, , , , , CheckCRC=0, Version=2.0.2600.0, Language=0, InstallMode=59244544, , , , , , )
…
Info 1603. 檔案'D:/test/sample.exe'正在被使用。請關閉程式然後再試。
在檔案清理期間的指令碼末尾,以下記錄檔資訊將指出要求使用者重新啟動電腦的'元兇':
Info 1903. 設定重啟議程:刪除檔案'D:/Config.Msi/12544a31.rbf'。您必須重新啟動以完成操作。
儘管檔案名稱為'12544a31.rbf',但實際上它是'Sample.exe'檔案。為了安裝檔案,正在使用的檔案會被重新命名為.rbf檔案,然後在重新啟動後被刪除。
(9)問:'ERROR_INSTALL_PACKAGE_VERSION 錯誤(1613)是什麼意思?
答:'ERROR_INSTALL_PACKAGE_VERSION'錯誤表示:電腦上的Windows Installer不支援本程式包的架構。程式包架構由程式包摘要資訊流中的PID_PAGECOUNT屬性指出。如果程式包的架構號大於Windows Installer所能夠支援的最大架構,您就需要升級Windows Installer的版本或者重新製作該安裝程式包,利用較早期的架構對其進行編譯。
所有版本的MSI所支援的最小架構號為30。
每個版本的MSI所支援的最大架構號如下:
Windows Installer 1.0: 100
Windows Installer 1.1: 110
Windows Installer 1.2: 120
Windows Installer 2.0: 200
(10)問:在我用系統賬戶啟動一個安裝過程的時候,我得到了編號為2103的錯誤資訊,這是為什嗎?
答:從系統賬戶(例如計劃任務服務)啟動程式安裝可能會導致2103錯誤。如果您進行的是一個針對使用者的安裝,這種情況就會發生。只有針對電腦的安裝才能夠使用系統賬戶,因為系統賬戶不能夠對所有必要的使用者設定檔夾進行訪問。
(11)問:在我從終端伺服器上的一個對應磁碟機進行安裝的時候,為什麼出現了2755錯誤?
答:Windows 2000和更早期的作業系統不支援在終端伺服器會話間傳遞對應磁碟機盤符資訊。因為Windows Installer服務是在控制台會話中作為一個服務運行,在遠端工作階段中建立的對應磁碟機盤對於Windows Installer服務來說是不可見的,從而導致了本錯誤的出現。只有服務運行於應用程式伺服器模式下時才會出現本錯誤,在遠端管理(Remote Admin)模式下不會出現。
注意:Windows XP以及其後的作業系統不存在此限制。
(12)問:在我安裝一個使用Web下載開機檔案的程式包時,我為什麼會得到一個安全性警告對話方塊,對話方塊中的訊息稱'訪問線上撤銷伺服器時發生錯誤'?
答:安全性警告對話方塊之所以會出現,是因為在Web下載開機檔案(Setup.exe)執行數位簽章驗證的過程中發生了問題。我們已經通過Windows Installer SDK提供的最新範例程式碼解決了這個問題,該SDK可以從Microsoft Download Center獲得。您只需要使用工具對Setup.exe進行簡單的重新設定即可。您可以從SDK Update網站下載該經過修正的範例程式碼。