[英]WIX : Adding and Reading cabinet file to msi Installer programatically with DTF to allow dynamic customization of installers
我們使用WIX Toolset創建了MSI安裝程序。 並且我們需要根據用戶特定的文件(例如主題和對話)動態地自定義安裝程序。 我們使用此鏈接將“ 添加文件櫃文件”添加到安裝程序,但我看不到它。 我們想知道讀取Cabinet文件及其文件(自定義文件)的最佳位置。 我們應該在自定義操作中執行此操作,還是執行此操作的最佳位置是什么? 另外,我們需要遵循以下示例代碼來完成此任務? 注意:-我們的內閣文件將包含很多文件(txt文件,圖片等)
我假設,因為您遵循了該鏈接(對我自己的問題仍然如此),現在您將文件嵌入到msi中,作為帶有MediaID的新內閣文件
警告:此回復中的代碼目前尚未經過測試
注意,msi基本上只是一個數據庫,可以使用類似SQL的語句來查詢。 cabfile位於_Streams表中的數據庫中,可以將其提取為原始的cab文件格式。
您可以使用ORCA和7zip進行驗證。
您所提到的SO問題的解決方案旨在“替換”文件。 因此,在msi構建中使用了一個虛擬文件,並且在wix中配置了該展示位置。 然后在建立msi之后,修改文件表,以將引用從wix生成的原始cab文件更改為注入的新cab文件。 這樣,偽文件在孤立的地方,但仍嵌入在msi中。
當人們知道將為每個用戶定制哪些文件,並且所有用戶將具有相同的文件夾/文件結構而與定制無關時,這種方法就很好。
我假設您為每個用戶擁有不同數量的文件,或者為每個用戶擁有不同的文件夾結構,因為您不只是復制該解決方案。 為了實現這一點,需要對多個msi表進行編輯。
目錄表:如果您的wix配置尚未定義目錄,則需要在此表中創建目錄。
這樣的事情應該可以讓您插入新目錄:
string query = "INSERT INTO `Directory` (`Directory`, `Directory_Parent`, `DefaultDir`) ";
query += "VALUES ('" + The_Directory_ID + "', '" + The_Parents_ID + "', '" + FolderName + ")";
pkg.Execute(query);
從這里開始,必須對新cab文件中的所有文件重復所有操作
**成分表**
您將需要創建一個控制文件的組件,以便msiexec可以安裝/卸載該文件。
string query = "INSERT INTO `Component` (`Component`, `ComponentId`, `Directory_`, `Attributes`, `Condition`, `KeyPath`) ";
query += "VALUES ('" + The_new_files_name_or_Similar + "', '{" + FileGUID + "}', '" + The_Directory_ID + "0, \"\", "+ A_FILE_ID +" )";
pkg.Execute(query);
哪里:
Guid.NewGuid()
生成Guid.NewGuid()
。 CreateFolder表:通常僅在需要創建一個空文件夾時才需要,因此我們現在將其忽略,因為您可以轉儲自述文件或文件夾中的某些內容。
文件表此表告訴msiexec在msi中的文件位置以及文件的版本,因此它知道是否需要復制,更新,忽略它,等等。
序列號用於告訴msi文件在哪里,媒體表將序列與cab文件或外部媒體相關聯。
該代碼也只是插入到語句中:
然后是魔術部分,我們稍后將使用它:
FeatureComponent表此表用於將其添加到功能樹,使用戶可以添加或刪除此功能。 所有組件都應屬於一個特征。
媒體表您所引用的代碼已經將文件櫃添加到了msi,並在媒體表中創建了一個條目:
IList<int> sequences = pkg.ExecuteIntegerQuery("SELECT `LastSequence` FROM `Media` ORDER BY `LastSequence`");
lastIndex = sequences.Count - 1;
int LastSequence = sequences.ElementAt(lastIndex) + numberOfFilesToAdd;
query = "INSERT INTO `Media` (`DiskId`, `LastSequence`, `Cabinet`) VALUES (" + DiskId.ToString() + "," + LastSequence.ToString() + ",'#" + mediaCabinet + "')";
pkg.Execute(query);
因此,這應該已經為您設置了。如果其他人迷失了這個答案,我在這里復制了相關代碼段,以說明如何為新的cab文件創建序列號。
因此,文件表的序列號比msi中的序列號大,但比您已添加的新介質中的序列號低。
注意: cab文件中的文件與序列號的順序非常重要,否則msiexec可能會引發無法找到該文件的錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.