2011-02-09 243 views
3

我一直在我們的BeforeBuild目標中的WiX安裝程序項目中使用HeatDirectory任務來收集我們在客戶端網絡上部署的Web應用程序的文件。一直很好。如何對具有相同文件的目錄進行2次或多次HeatDirectory?

我現在想要部署第二組文件,這恰好是一些文檔,它包含的文件與以前的HeatDirectory輸出中存在的文件名稱相同。

我得到以下錯誤:

LGHT0293: Multiple files with ID 'Web.Config' exist. 

我明白爲什麼我收到了錯誤,我不知道如何解決它。

選項A

的所有文件複製到一個目錄,對他們在一個巨大的通運行熱。

我喜歡這個,因爲使用庫存MSBuild任務可以很容易實現。我不喜歡它,因爲它會創建一個龐大的ComponentGroup,如果我決定做可選功能(如不安裝某些東西),我不能。

選項B

遍歷HeatDirectory任務的輸出文件,並追加上的所有組件ID後綴和文件ID的。示例 - web.config將成爲web.config_DocumenationFiles

我喜歡這個,因爲它很乾淨;即我可以稍後將其刪除,或者將其添加到具有該問題的項目中,而不是將其添加到不具有該項目的項目中。我不喜歡它,因爲我不確定什麼'process'(或者MSBuild任務)能夠做到這一點。我需要一個自定義的任務。

其他選項:?

想法?

回答

1

我看到有人在三年後出現並投票贊成。我想我會回來說明我仍在使用選項B,一個自定義的MSBuild任務來解決問題。

我對此問題進行了a comment on another post更多詳細信息,並認爲如果有幫助,我會在此移動/複製我的實施。

我已經解決了這個問題,方法是創建一個自定義構建任務,在HeatDirectory任務後爲後綴添加到Id屬性中運行。

<AddSuffixToHeatDirectory File="ReportFiles.Generated.wxs" Suffix="_r" /> 

的AddSuffixToHeatDirectory任務是這樣

public class AddSuffixToHeatDirectory : Task 
{ 
    public override bool Execute() 
    { 
     bool result = true; 

     Log.LogMessage("Opening file '{0}'.", File); 
     var document = XElement.Load(File); 

     var defaultNamespace = GetDefaultNamespace(document); 

     AddSuffixToAttribute(document, defaultNamespace, "Component", "Id"); 
     AddSuffixToAttribute(document, defaultNamespace, "File", "Id"); 
     AddSuffixToAttribute(document, defaultNamespace, "ComponentRef", "Id"); 
     AddSuffixToAttribute(document, defaultNamespace, "Directory", "Id"); 

     var files = (from x in document.Descendants(defaultNamespace.GetName("File")) select x).ToList(); 

     Log.LogMessage("Saving file '{0}'.", File); 
     document.Save(File); 

     return result; 
    } 

    private void AddSuffixToAttribute(XElement xml, XNamespace defaultNamespace, string elementName, string attributeName) 
    { 
     var items = (from x in xml.Descendants(defaultNamespace.GetName(elementName)) select x).ToList(); 
     foreach (var item in items) 
     { 
      var attribute = item.Attribute(attributeName); 
      attribute.Value = string.Format("{0}{1}", attribute.Value, Suffix); 
     } 
    } 

    private XNamespace GetDefaultNamespace(XElement root) 
    { 
     // I pieced together this query from hanselman's post. 
     // http://www.hanselman.com/blog/GetNamespacesFromAnXMLDocumentWithXPathDocumentAndLINQToXML.aspx 
     // 
     // Basically I'm just getting the namespace that doesn't have a localname. 
     var result = root.Attributes() 
         .Where(a => a.IsNamespaceDeclaration) 
         .GroupBy(a => a.Name.Namespace == XNamespace.None ? String.Empty : a.Name.LocalName, a => XNamespace.Get(a.Value)) 
         .ToDictionary(g => g.Key, g => g.First()); 
     return result[string.Empty]; 
    } 

    /// <summary> 
    /// File to modify. 
    /// </summary> 
    [Required] 
    public string File { get; set; } 

    /// <summary> 
    /// Suffix to append. 
    /// </summary> 
    [Required] 
    public string Suffix { get; set; } 
} 

希望有所幫助。今天我仍然在使用這種方法,但我沒有仔細研究變換或擴展HeatDirectory。

4

HeatDirectory任務有Transforms屬性,您可以使用該屬性來轉換結果文件。您可以創建一個xslt將後綴添加到組件ID。

此外,熱是extensible。您可能需要考慮創建自己的收割機,它會爲您添加後綴到組件ID。

+0

+1選項B和Aaron的回答 – 2011-02-15 08:43:20

相關問題