使用 WiX 安裝程序複製 Visual Studio COM 註冊
曾幾何時,一位年輕、天真的工程師認為將他的應用程序的一些功能分離到一個用 C# 編寫的 COM 組件中是個好主意。Visual Studio 擁有所有的工具來做到這一點,對吧?.NET 實際上就是為此而生的,對吧?哈!他說,這會很容易。我將有良好的組件分離,使業務邏輯遠離前端,並且使用 COM,我將能夠在任何地方使用它!他興高采烈地勾選
register for COM interop了項目屬性中的複選框,暴露了他想要的類,然後繼續前進。哦,試煉做出了這樣的選擇。現在這位年輕的工程師,更有經驗,現在不會希望任何人這樣做。然而,重擔已經壓在了他的肩上,重擔依然沉重。他想減輕負擔。
隨之而來的是 WiX,這是一種從 XML 生成 Windows Installer 文件的工具。這引起了他的興趣——它可以很簡單地從少數配置文件中複製正確的 Windows 安裝程序文件所需的大部分程式碼。他的視線正在向上看。
使用 WiX 2.0,他可以很容易地生成註冊 C# COM 對象所需的文件。這涉及使用工具動物脂。他會做類似以下的事情:
tallow -c -nologo MyComExposedLibrary.dll > MyComExposedLibrary.wxs然後將其修復(起初這是手動完成的,但最終我將這些步驟記錄到一個小工具中,設置最終目錄 ref id、組件 ID、fileID、GUID 和程式碼庫)。
然後,隨後的安裝程序將安裝,如果應用程序正常執行,將會有歡樂的慶祝活動。
它沒有。
幾天來,這位年輕的工程師傾注了他的開發 PC 和測試安裝 PC 的差異。“所有的系統資料庫項都是一樣的!” 他會驚呼。“MyComExposedLibrary 的所有內容都已註冊,我發誓!”
但事實並非如此。
在第三天的黎明,在經歷了多次山露之後,他意識到 Visual Studio 正在註冊的另一個對像是他的安裝程序沒有註冊的:MyComExposedLibrary.tlb 文件。
顯然,Visual Studio 一直在註冊這個文件,在
HKLM\Software\Classes\Interface系統資料庫項中創建額外的子項,並在HKLM\SOFTWARE\Classes\TypeLib.Tallow 沒有提供任何幫助,抱怨 .tlb 不是它摸索的文件。也不是 WiX 3.0 測試版——這似乎有更多的問題讓事情正常工作。
我也嘗試過熱火。這會生成系統資料庫元素和類元素。我清理了 heat 的輸出,然後去編譯它,但得到了一個不同的錯誤:
error LGHT0130 : The primary key <uuid here> is duplicated in table 'Registry'. 問題是,據我所知,uuid 實際上並不存在於我的任何 wxs 源文件中。如果我改變了我的特徵元素中的組件引用順序,一個不同的 dll 組件會給出該錯誤。由於我未能成功編譯該項目的 WiX 3.0 版本,因此我無法確認 heat 是否提供了正確的輸出。我從安裝程序中刪除了所有內容,除了導致出現此錯誤的程序集之一併嘗試再次編譯。我得到了同樣的錯誤。啊!
所以,我的好夥伴、Windows 愛好者和 WiX 使用者,有兩個問題:
- 類型庫是 WiX 可以本地註冊的東西嗎?如果是這樣,怎麼做?
- 如果沒有,使用 Windows 安裝程序註冊類型庫的正確方法是什麼?
另外,我想作為另一部分,Visual Studio 如何確定如何註冊類型庫?(編輯:看起來關於 typelib 註冊的 MSDN 庫文章有所需密鑰的名稱,但我仍然需要弄清楚如何獲取 uuid。(這是來自Larry Osterman 關於 typelib 和 COM 註冊的這篇部落格文章。)多讀一點,我可能會手動註冊這些位,但我希望不會……
我評估了
regasm /regfile:MyDll.dll MyDll.dll. 看起來這些是 wix 為 dll 生成的相同鍵。Regasm 的另一種模式,regasm /tlb:<filename>生成並註冊程序集的類型庫,但是,/regfile[:FileName] 生成具有指定名稱的 reg 文件,而不是註冊類型。此選項不能與 /u 或 /tlb 選項一起使用
似乎 /regfile 開關與 /tlb 開關不兼容。哈啊啊啊!
**進一步更新:**看起來您實際上不需要包含 .tlb 文件。 根據 wix 的 typelib element 上的這篇文章,MSI 可以創建/註冊它作為設置過程的一部分。這一切都歸結為通過獲取正確的屬性來配置 WiX 文件以實際安裝它。
後來我發現你可以直接在 .tlb 上使用 heat 來獲得正確的屬性!有關更多資訊,請參閱此 SO 問題。
您應該使用位於您正在使用的版本的 bin 目錄中的 Heat (WIX 3.0)。看看這篇博文,我們在這裡使用它來註冊我們所有的 COM 對象,通過創建一個 wix 片段……
就像是
heat file MyComExposedLibrary.dll -out MyComExposedLibrary.wxs在閱讀您的編輯之後,我將使用 wix 創建一個基本的 msi,它只安裝 com 對象,看看是否有效……然後你就會知道要攻擊哪個戰場……