先說一下ClickOnce的使用方法:
先給一個要釋出的工程設定安全和簽名。然後釋出到iis中。當使用者通路該iis目錄下的.application檔案時,就會自動安裝整個應用程式。
再說一下我們目前的應用程式。相對還是比較複雜的,分為架構部分和特定應用程式部分。其中的架構部分,以後會作為開源架構釋出。由于是AutoUI,架構部分就包含了生成最後用戶端運作的exe的工程。而特定的應用程式隻需要實作自己的類庫和子產品(Module)。最後釋出的時候,需要把生成好的類庫和Module放到exe檔案所在目錄的子目錄Library和Module當中,架構會自動尋找這兩個目錄中的檔案,進行加載。
這時候,我們的釋出就比較麻煩了。
先要把架構直接釋出好,這樣其它團隊就可以直接使用。但是其中包括安全和簽名,和所有檔案hash值。這時候,如果其它使用這個架構的團隊進行釋出時,必須要把他們自己的類庫和Module放入到已經打包好的程式當中。然後使用MS一個開源的工具(ManifestManagerUtility.exe)對已經生成好的.application檔案進行修改,把類庫和Module添加到這個檔案中,這樣,用戶端在裝程式的時候,才會也把這些檔案一起安裝到用戶端中。這時,這個軟體也會再次對每個檔案生成hash值。
但是,這樣直接加了以後,有兩個問題。
一是他們在類庫和module釋出更新的版本時,為了避免再次打開那個MS的軟體進行手工編輯,應該實作自動化更新application檔案。
二是新的檔案生成的hash值,肯定不會和原有的hash值相同。
是以,我隻有自己把MS的那個軟體的源碼給研究完,然後自己寫了一個控制台程式實作以上功能。
其中,遇到一個MS比較缺陷的設計,害得我是查了好半天!當直接複制MS程式中的代碼:
Manifest.ResolveFiles();
Manifest.UpdateFileInfo();
來進行更新時,老是不能把檔案的hash值也一并更新。其原因在于,UpdateFileInfo更新hash值時,是使用每個AssemblyReference對象的ResolvedPath來計算hash,而在ResolveFiles方法裡面,這個屬性值的計算是調用SourcePath和Environment.CurrentDirectory計算出來的。此時,這個Environment.CurrentDirectory檔案夾路徑是我的這個控制台程式所在路徑,是以并不能正确計算出.application所在檔案夾中的檔案的路徑。找不到檔案,自然hash值就更新失敗了。
解決方案:
一:在更新前,計算出各個AssemblyReference的SourcePath值,然後再調用ResolveFiles方法。(我使用的是此法,因為MS軟體中有現成的方法。)
二:使用ResolveFiles的重載ResolveFiles(string[] searchPaths)指定搜尋的檔案夾即可。
參考:
繼承層次 : ApplicationManifest : AssemblyManifest : Manifest。
本文轉自BloodyAngel部落格園部落格,原文連結:http://www.cnblogs.com/zgynhqf/archive/2009/11/21/1607735.html,如需轉載請自行聯系原作者