常見問題
問:Windows Installer是一種什么樣的產品?
答:Windows Installer是一種系統服務,用來安裝和管理系統中的應用程序。它為應用程序的開發、定制、安裝和升級提供了一種標準化的方法和手段。
問: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能夠查詢程序的當前狀態,校驗現有狀態,或者修復受損的狀態,并且能夠從一種狀態過渡到另一種狀態。
問: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文件),這些文件包含一些屬性,能夠由合并模塊的使用者加以配置。
問:我可以從哪里獲得有關Windows Installer的更多信息?
答:有關Windows Installer的更多信息可以在Windows Installer軟件開發工具包(SDK)中找到。
有關Windows Installer的進一步信息還可以通過以下白皮書獲得:
--Windows Installer服務概述
--Windows Installer:優點以及具體實現過程
可用性
問:哪些版本的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。
問:Windows Installer支持哪些操作系統?
答:下表詳細介紹了每個版本的Windows Installer所支持的操作系統。
問:我可以從何處獲得最新版本的Windows Installer再分發程序?
答:您可以通過Microsoft Platform SDK Redistributables站點獲得最新版本的Windows Installer再分發程序,Windows Installer的再分發程序有兩個不同的版本:一個適用于Windows 95、Windows 98和Windows Me;另一個適用于Windows NT和Windows 2000。
問:我需要在我的安裝程序中再次分發這些技術,我可以從哪里獲得針對Microsoft技術的合并模塊?
答:Microsoft合并模塊隨同Microsoft Visual Studio .NET一同提供。它們的默認安裝位置為 [ProgramFilesFolder]/Common Files/Merge Modules。請注意:并不是所有的Microsoft再分發組件都有可用的合并模塊。
教學指導 問:我應該怎樣在"添加或刪除程序"中隱藏某個應用此程序?
答:為了在"添加或刪除程序"中隱藏某個應用程序,請將ARPSYSTEMCOMPONENT屬性設置為1。該屬性可以在命令行、在程序包的"屬性"表中設置,或者通過轉換進行設置。在Windows 2000以前的操作系統上,可以通過將ARPNOREMOVE屬性設置為1 來在"添加或刪除程序"中隱藏應用程序。在Windows 2000和Windows XP操作系統中, ARNOREMOVE可以禁用"添加或刪除程序"中的"刪除"按鈕。
問:在Orca中對我的.msi程序包進行多次編輯之后,程序包的體積顯著增加了。我應該怎樣減小.msi文件的大小呢?
答:.msi程序包的數據庫格式是建立在OLE結構化存儲基礎上的。頻繁對數據庫進行編輯回導致碎片的出現,并因此浪費一些空間。您可以通過在Orca中使用"另存為"命令減小.msi程序包的大小。或者,您也可以使用msidb.exe導出所有表,然后再將這些表重新導入到一個新建的數據庫中,以便減小程序包的體積大小。
Orca和msidb.exe工具可以通過Windows Installer SDK獲得。
問:如何在安裝期間隱藏"取消"按鈕?
答:從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)方法。
問:我怎樣才能只安裝那些我希望使用的功能特性?
答:您可以使用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
另一個重要的注意事項是:功能特性的名稱是大小寫敏感的。
問:我怎樣在升級期間強制升級一個和版本無關的文件,即使用戶已經修改了該文件?
答:通過在"文件"(File)表中為文件制作一個版本號,您可以在升級期間"強制升級"一個和版本無關的文件。根據Windows Installer的文件版本控制原則,版本發生變化的文件將覆蓋一個和版本無關的文件。需要注意的是:所有的后續重新安裝過程都需要訪問源程序,因為所有的后續版本檢查都會指出文件需要被重新安裝。
問:我怎樣才能正確地書寫路徑字符串?
答:目錄屬性值以一個目錄分隔符結束。因此,路徑字符串的書寫不要求使用目錄分隔符。
錯誤寫法:[DirectoryProperty]/someLocation
正確寫法:[DirectoryProperty]someLocation
問:我應該怎樣為不同的地理區域開發產品?
答:對于擁有不同版本的產品--這種不同既可以是產品語言上的不同,也可以是產品功能間的差異,您可以使用不同的產品代號。以便指明方向、熟悉產品間的關系,并且讓產品共享相同的升級代碼。
安全性 問:何謂受管理應用程序?
答:受管理應用程序是一種管理員能夠在程序的安裝和維護期間對其施加某種控制的程序。受管理應用程序經常用來進行大規模的軟件部署。對于系統管理員來說,受管理應用程序為他們允許用戶在一個"鎖定"環境中安裝授權軟件提供了方便,在這個環境之中,用戶一般沒有安裝軟件所需的權限。
如果滿足以下條件,一個應用程序將被認為是受管理的:
可以由(管理員)組的成員為用戶進行安裝或宣告。
可以由Administrators組的成員以計算機為基礎進行安裝和宣告。
可以由管理員在Windows 2000或更高版本的操作系統上進行指派或發布。
可以被其它軟件或部署管理系統標記為受管理程序。具體方法取決于用戶使用的管理系統,但是一般需要由管理員完成這項操作。
安裝程序包不能自己宣稱自己是"受管理"的,該程序是否為一個"受管理"程序是由系統管理員進行控制的。
請注意:"受管理"和"權限提升"不同。經過權限提升的應用程序是指在安裝之時利用系統權限進行運行的程序。所有的受管理應用程序都是權限提升程序,但是權限提升程序卻不一定是受管理程序,這是由AlwaysInstallElevated 策略來決定的。出于安全性的考慮,該策略在默認情況下處于禁用狀態,在使用此策略之前,請務必對其可能造成的危害加以認真考慮。
問:AdminUser和Privileged 屬性有何不同?
答:如果執行安裝操作的用戶是一個管理員,AdminUser屬性將被設置;如果允許用戶利用經過提升的權限來安裝程序,Privileged屬性將被設置。如果用戶是一位管理員,用戶可以利用經過提升的權限安裝程序,無論您是按照用戶還是按照計算機設置AlwaysInstallElevated策略,或者,程序已經被系統管理員指派給用戶了。
如果用戶是管理員,那么AdminUser和Privileged屬性都會被設置。如果用戶不是管理員,那么AdminUser屬性將永遠不會被設置。在這種情況下,如果用戶已經由管理員通過指派或策略賦予了安裝程序所需的提升權限,那么Privileged屬性將是唯一被設置的屬性。
在很多情況下,我們都建議:無論是啟動條件或者是類似條件,都使用Privileged屬性代替AdminUser屬性來安裝由管理員指派的應用程序。
問:應該允許具有用戶級權限的用戶安裝MSI程序嗎?
答:如果管理員允許,具有用戶級權限的用戶可以安裝受管理的應用程序。否則,用戶只能安裝那些寫入文件、創建目錄和寫注冊表鍵的位置與用戶擁有的權限相符的MSI應用程序。如果用戶不能在某個位置進行寫入操作,那么除非管理員為安裝程序賦予了寫入權限,否則安裝程序將不能在該位置寫入數據。
定制操作 問:"延遲"定制操作和"立即"定制操作有何不同?
答:"延遲"定制操作僅僅能夠以執行后續表中的InstallInitialize或InstallFinalize操作作為其后續操作。而"立即"定制操作可以以后續表中的任何地方作為其后續操作。
"延遲"定制操作不能訪問安裝數據庫。事實上,"延遲"定制操作只具有十分有限的安裝會話訪問能力,因為安裝腳本可以在創建該腳本的安裝會話的外部執行。"立即"定制操作可以訪問安裝數據庫,并且可以讀取和設置安裝屬性,修改特性和組件狀態,以及添加臨時行、臨時列和臨時表等其它東西。
盡管"延遲"和"立即"定制操作都可以運行在初始化安裝操作的用戶上下文環境中,但是只有"延遲"定制操作可以使用系統上下文環境以得到提升的權限運行。
"延遲"定制操作不能夠立即執行。相反,它們按照預先設定的日程在腳本執行期間運行。在InstallExecute、InstallExecuteAgain或InstallFinalize操作運行之前,執行腳本并不會被處理。
問:我什么時候應該使用延遲定制腳本,而不是使用立即定制腳本?
答:如果定制操作必須修改系統或者調用另一個系統服務,那么您必須使用延遲定制腳本。此外,只有延遲定制操作能夠運行經過權限提升的上下文環境中。如果您的定制腳本需要經過提升的權限才能運行,那么您需要將定制腳本標記為"延遲"腳本。注意:只有在安裝程序自身經過權限提升的情況下,標記為在系統上下文環境(msidbCustomActionTypeInScript + msidbCustomActionTypeNoImpersonate)中運行的定制操作才能夠運行。
此外,如果希望通過定制操作對系統進行修改,您還應該包括一個回滾定制操作,以便撤銷修改,將系統還原回先前狀態。
問:如何向我的延遲定制腳本提供數據?
答:延遲定制操作只能對安裝會話進行有限訪問。如果您的延遲定制操作無法通過這種有限的訪問獲取到有關安裝的信息,您可以通過CustomActionData屬性為延遲定制操作提供這些信息。這種方法僅僅對腳本和DLL延遲定制操作有效。其具體工作方式如下:
在延遲定制操作之前執行的立即定制操作會使用與延遲定制操作所使用的相同名稱將某個屬性設置為延遲定制操作需要的值。所以,如果延遲定制操作的主鍵名稱為"DeferredCA",那么立即定制操作將把名為"DeferredCA"的屬性設置為延遲定制操作需要的值。類型51的定制操作可以很容易地設置該屬性。另一種方法是:立即定制操作使用"szName"參數調用MsiSetProperty,其中szName參數等于"DeferredCA"。注意:操作名稱是大小寫敏感的。
當延遲定制操作排隊進入安裝腳本之后,安裝程序將會把 "DeferredCA" 屬性值寫入到安裝腳本之中,并用它作為CustomActionData屬性的值。
在執行時,延遲定制腳本通過調用帶有szName參數的MsiGetProperty來獲得所需的值,其中szName參數等于CustomActionData。或者,腳本定制操作會使用會話(Session)對象的"Property"屬性。
問:我能夠使用定制操作重新啟動計算機嗎?
答:通過使用MSIRUNMODE_REBOOTATEND或MSIRUNMODE_REBOOT的運行模式以及等于"TRUE"的狀態值調用MsiSetMode,立即定制操作可以重新啟動計算機。因為MsiSetMode 需要一個hInstall句柄,所以只有DLL和腳本定制操作能夠重新啟動計算機。腳本定制操作將使用"會話"對象的"模式"屬性。或者,立即定制操作也可以使用等于"ScheduleReboot"的szAction參數調用MsiDoAction。
延遲定制操作不能調用MsiSetMode。延遲定制操作需要對注冊表某個位置的值進行設置,該值會被立即定制 操作和隨后的InstallFinalize讀取。然后,立即定制操作可以使用MsiSetMode設定計算機的重新啟動日程。如果需要使用該方法,您還應該提供一個回滾定制操作,以便在取消安裝時,從注冊表中刪除能夠觸發重新啟動的該鍵值。
問:我的定制操作應該如何向日志文件添加信息?
答:通過使用MsiProcessMessage API發送INSTALLMESSAGE_INFO消息,DLL和腳本定制操作可以向日志文件添加信息。腳本定制操作將使用"Session"(會話)對象的"Message"(消息)方法。
問:為什么在安裝程序時,會有多個MSIExec.exe進程運行在我的計算機上?
答:在程序安裝期間,會有多個MSIExec進程運行。之所以會出現這種現象,主要是因為Windows Installer使用了客戶機-服務器模式來執行程序安裝任務。此外,出于安全方面的考慮,Windows Installer會在一個"沙箱"(sandbox)進程中駐留DLL和腳本定制操作。根據安裝過程初始化方式的不同,一個MSIExec進程將作為客戶機進程。另一個MSIExec進程將作為Windows Installer服務。在計算機上運行的所有MSIExec進程通常都是用來托管定制操作的沙箱進程。決定哪一個MSIExec進程將作為面向腳本或DLL定制操作的沙箱進程的具體過程部分取決于定制操作是以經過提升的權限運行還是以人格化的方式運行,以及該定制操作是32位的還是64位的。
補丁和升級 問:小型、次要和主要升級之間有何不同?
答:"小型"升級是一種只對很少的文件進行修改或者只增加少量新內容的產品升級。"次要"升級是對產品進行的修改足以改變產品版本號的產品升級,而"主要"升級則是對產品進行了大量修改,以致需要修改產品代號的產品升級活動。下表總結了每一種升級方式所做的產品修改內容以及每種升級方式可能使用的分發載體形式。
在某種程度上,您可以將一個小型升級看作是一個"熱修補"或者"快速修補工程"(Quick Fix Engineering,QFE)升級,將次要升級看作服務包,而將主要升級看作是產品升級。
除了次要升級會改變產品版本號而小型升級不會改變版本號之外,小型升級和次要升級可以被認為是基本相同的。它們所遵循的原則和補丁程序都是相同的。小型升級和次要升級的應用程序都需要進行明確的重新安裝。主要升級則不受此限制,補丁程序不需要重新安裝。此外,小型升級和次要升級的補丁程序對程序包的功能組件結構所做的修改比較有限。而主要升級則會對程序的功能組件結構進行顯著的修改。
問:什么時候補丁程序會需要原始源文件?
答: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,以便補丁能夠成功得到應用。
問:我怎樣才能防止我的補丁程序需要訪問源文件?
答:目前,您還無法完全阻止補丁程序訪問源文件,但是,以下步驟可以幫助您減少程序訪問源文件的次數:
--使用只包含完整文件的補丁。這使得補丁創建程序無需根據每個先前發布的補丁程序和產品的RTM版本創建二進制補丁。通過將Patch Creation Properties(補丁創建屬性,PCP)文件的"Properties"(屬性)表中的IncludeWholeFilesOnly屬性的值設置為"1",您可以輕松制作出僅僅包含完整文件的補丁。
--確保您所有的定制操作都不會訪問原始的源文件位置。
--確保ResolveSource 操作只有在特定條件中才會執行,或者根本不存在此操作。
--為程序包中所有與版本變化無關的文件建立"MsiFileHash"表。Windows Installer SDK包括了一個名為"MSIFiler.exe"的工具和一個名為"Wifilver.vbs"的腳本,它們可以自動完成這項工作。
問:為什么雖然我的補丁成功應用到了計算機上,但是文件卻沒有被升級?
答:這很可能是因為您簡單地雙擊了一個小型或次要升級補丁。小型升級或者次要升級的補丁程序需要對將要升級的文件執行一次明確的重新安裝過程。您可以使用MSIExec命令行完成這個工作,并且將REINSTALL和REINSTALLMODE屬性包括在命令行命令之中(也就是:msiexec /p {path to my patch.msp} REINSTALL=ALL REINSTALLMODE=omus)。另一種方法是:在補丁中包括一個定制操作,對REINSTALL和REINSTALLMODE屬性進行相應的設置。您應該確信您對該操作的執行條件進行了嚴格的限制,只在補丁程序的第一次應用期間執行。產品的后續重新安裝不應該導致該定制操作的執行,否則您的產品可能會變得無法卸載。其它方法包括使用一個啟動執行文件并利用正確的屬性設置調用MsiApplyPatch,或者使用Windows Installer自動化對象,使用腳本編寫補丁應用程序。
問:我能通過補丁升級一個定制操作嗎?
答:可以,您可以使用補丁升級某個定制操作。如果定制操作包括在 "Binary"(二進制)表中,那么您可以簡單地對升級安裝映像中的定制操作進行升級。如果您使用原始文件和升級安裝映像制作補丁程序,該補丁將包含一個數據庫轉換,將老的二進制數據流轉換成新的二進制數據流。
故障處理 問:我如何才能找出程序包安裝失敗的原因?
答:有三種比較好的方法可以對程序包的安裝問題進行跟蹤。第一種方法是通過運行校驗確信您的程序包合法有效。通過進行驗證,您可以發現錯誤和警告,并找出一些常見的安裝程序制作問題。有兩個工具可以對安裝程序包進行驗證,這兩個程序都可以通過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%"文件夾中。
注意:通過命令行產生的日志記錄比所有的日志記錄策略設置擁有更高的優先級。
問:在我每次啟動程序的時候,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"不存在。您應該找出導致鍵路徑不存在的原因所在--在本例中,是因為用戶刪除了該文件。
問:我怎樣才能確定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"也將根據給定的操作狀態進行本地安裝。
問:為什么我的文件在卸載過程中沒有被刪除?
答:產生這個問題的原因主要有四種:
這些文件所屬的組件被標記為"永久"(permanent)。(這一點可以通過Component表的Attributes列來實現)
這些文件所屬的組件沒有一個擁有組件GUID。(位于Component表的ComponentId列的該值為NULL)。Windows Installer無法管理那些沒有GUID的組件。
如果組件的鍵路徑(keypath)擁有一個共享的DLL refcount,那么該組件將不能被卸載。
如果該組件安裝在系統文件夾中,而且在程序卸載之時,組件中的某一個文件擁有一個外部共享的DLL refcount,那么該組件將不能被卸載。
問:為什么我的文件夾在程序卸載時沒有被刪除?
答:導致文件夾在程序卸載過程中不能被刪除的原因主要有以下幾種:
在同時使用CreateFolder表和CreateFolders操作時,執行順序表中的RemoveFolders操作丟失。
該文件夾不是由Windows Installer創建的文件夾,因此它不會刪除它們,除非您告訴Windows Installer刪除這些文件夾。
文件夾中仍然存在資源。
問:為什么我的注冊表鍵在程序卸載是沒有被刪除?
答:導致程序卸載時注冊表鍵沒有被刪除的最常見原因有以下幾種:
1. Registry(注冊表)表包含了帶有"+"標記的實體。該符號將指示Installer在卸載程序時保留這些注冊表鍵。
2. 在InstallExecuteSequence表中,RemoveRegistryValues操作位于UnregisterProgIdInfo和 UnregisterMIMEInfo操作之后。您需要反轉這些操作的順序。Registry表所寫入的某些注冊表鍵值會阻止特定的ProgId、擴展和CLSID 鍵被刪除。
問:為什么安裝過程所占用的磁盤空間遠遠大于我實際安裝的文件尺寸?
答:Windows Installer會計算兩種類型的磁盤占用:帶有回滾操作的磁盤占用;以及沒有回滾操作的空間占用。沒有回滾的空間占用是程序安裝實際占用的磁盤空間。帶有回滾操作的空間占用包括了在安裝過程中為回滾操作提供支持所需的備份文件所占用的空間。此外,Windows Installer還會計算出執行安裝操作所需的一些額外空間占用。其中包括安裝腳本所需占用的空間以及緩存程序包的空間需求。此外,在安裝期間,Installer需要對安裝程序包進行臨時復制。安裝腳本和程序包運行副本所占用的空間是臨時性的。在安裝結束之后,這些文件將會被清除。請看以下示例,在本例中,您的安裝程序包的大小約為80KB,而您正在安裝一個4 KB的文件。(注意:根據硬盤簇大小的不同,您的數字與我的可能會有所不同):
89120字節(被緩存的MSI,基本上是4 KB簇大小的整數倍)
89120字節(MSI的臨時工作副本)
8192字節(估計的腳本大小)
4096字節(小文件,與大小為4 KB磁盤簇基于相等)
----------------------
176128字節 = 172 KB
問:為什么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文件,然后在重新啟動后被刪除。
問:"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
問:在我用系統賬戶啟動一個安裝過程的時候,我得到了編號為2103的錯誤信息,這是為什么?
答:從系統賬戶(例如計劃任務服務)啟動程序安裝可能會導致2103錯誤。如果您進行的是一個針對用戶的安裝,這種情況就會發生。只有針對計算機的安裝才能夠使用系統賬戶,因為系統賬戶不能夠對所有必要的用戶配置文件夾進行訪問。
問:在我從終端服務器上的一個映射驅動器進行安裝的時候,為什么出現了2755錯誤?
答:Windows 2000和更早期的操作系統不支持在終端服務器會話間傳遞映射驅動器盤符信息。因為Windows Installer服務是在控制臺會話中作為一個服務運行,在遠程會話中建立的映射驅動器盤對于Windows Installer服務來說是不可見的,從而導致了本錯誤的出現。只有服務運行于應用程序服務器模式下時才會出現本錯誤,在遠程管理(Remote Admin)模式下不會出現。
注意:Windows XP以及其后的操作系統不存在此限制。
問:在我安裝一個使用Web下載啟動文件的程序包時,我為什么會得到一個安全性警告對話框,對話框中的消息稱"訪問在線撤銷服務器時發生錯誤"?
答:安全性警告對話框之所以會出現,是因為在Web下載啟動文件(Setup.exe)執行數字簽名驗證的過程中發生了問題。我們已經通過Windows Installer SDK提供的最新示例代碼解決了這個問題,該SDK可以從Microsoft Download Center獲得。您只需要使用工具對Setup.exe進行簡單的重新配置即可。您可以從SDK Update站點下載該經過修正的示例代碼。