2011-02-09 124 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

相关问题