簡體   English   中英

WIX:使用DTF以編程方式向Msi Installer添加和讀取Cabinet文件,以允許動態自定義安裝程序

[英]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()
  • A_FILE_ID可以是文件名,如果wix生成了MSI,則其他所有文件通常都由“ FileID ##”引用,因此它可能對您有用,否則您需要確定文件表中尚不可用的FileID ..

CreateFolder表:通常僅在需要創建一個空文件夾時才需要,因此我們現在將其忽略,因為您可以轉儲自述文件或文件夾中的某些內容。

文件表此表告訴msiexec在msi中的文件位置以及文件的版本,因此它知道是否需要復制,更新,忽略它,等等。

序列號用於告訴msi文件在哪里,媒體表將序列與cab文件或外部媒體相關聯。

該代碼也只是插入到語句中:

  • 檔案: A_FILE_ID
  • 組件: The_new_files_name_or_Similar
  • 文件名:文件名(安裝時)
  • FileSize:它是文件大小,以字節為單位...
  • 版本:如果文件包含一個,則添加一個版本號,否則保留空白。 如何檢索文件版本取決於文件類型。
  • 語言:這是文件語言版本,通常為1033,但是如果您不知道,可以將其留空。
  • 屬性:這取決於媒體文件(櫃)是嵌入的,外部的還是文件是外部的等。使用與msi中其他所有文件相同的編號,通常會沒事的。 構建后嵌入cabinet文件時,我一直使用512。

然后是魔術部分,我們稍后將使用它:

  • 序列:您需要獲取“文件”表中已經找到的最高序列值,並將其遞增

FeatureComponent表此表用於將其添加到功能樹,使用戶可以添加或刪除此功能。 所有組件都應屬於一個特征。

  • Feature_安裝此組件的功能。 您可以重新制作一個。 我建議您使用現有的!
  • Component_ The_new_files_name_or_Similar

媒體表您所引用的代碼已經將文件櫃添加到了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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM