如何对具有相同文件的目录进行HeatDirectory 2次或更多次? [英] How to HeatDirectory 2 or more times against directories with the same files?
问题描述
我一直在BeforeBuild目标的WiX安装程序项目中使用HeatDirectory任务来收集我们部署在客户端网络上的Web应用程序的文件.一直很棒.
I've been using the HeatDirectory task in our WiX installer project in the BeforeBuild target to harvest the files of a web application we deploy on the clients network. Been working great.
我现在想部署第二组文件,这恰好是一些文档,并且包含与先前HeatDirectory输出中存在的文件名称相同的文件.
I now want to deploy a second set of files, which so happens to be some documentation, and it contains files that are of the same name that exist in the previous HeatDirectory output.
我收到以下错误:
LGHT0293: Multiple files with ID 'Web.Config' exist.
我了解我为什么会收到错误,我想知道如何最好地解决它.
I understand why I am getting the error, I'm wondering how best to resolve it.
选项A :
将所有文件复制到目录中,并通过大量操作对其进行加热.
Copy all the files into a directory and run heat on them in one massive pass.
我之所以这样,是因为使用库存MSBuild任务很容易实现.我不喜欢它,因为它会创建一个庞大的ComponentGroup,而且如果我决定提供可选功能(如不安装某些东西),我就不会.
I like this because it would be fairly easy to implement using stock MSBuild tasks. I dislike it because it would create one massive ComponentGroup and if I ever decided to make optional features (like not install something), I can't.
选项B :
遍历HeatDirectory任务的输出文件,并在所有Component ID和File Id的后面添加后缀.示例-web.config将变为web.config_DocumenationFiles
Iterate over the output file of the HeatDirectory task and append a suffix on all the Component ID and File Id's. Example - web.config would become web.config_DocumenationFiles
我喜欢它,因为它很干净.即,我可以稍后将其删除或将其添加到有问题的项目中,而不将其添加到没有问题的项目中.我不喜欢它,因为我不确定哪个进程"(或MSBuild任务)能够做到这一点.我认为我需要自定义任务.
I like this because it's clean; i.e. I can delete it later or add it to a project that's having the issue and not add it to projects that don't. I dislike it because I'm not sure what 'process' (or MSBuild task) is capable of doing this. I need a custom task I think.
其他选项:吗?
想法?
推荐答案
我看到有人在三年后出现并对此表示支持.我以为我会回来并声明我仍在使用选项B,这是一个自定义MSBuild任务来解决该问题.
I see someone has come along and upvoted this three years later. I thought I'd come back and state that I'm still using Option B, a custom MSBuild task to resolve the issue.
我对另一则帖子进行了评论,其中包含有关该问题的更多详细信息,并认为我会移动/复制实现在这里,以防万一.
I made a comment on another post about the issue with more details and thought I'd move/copy my implementation over here in case it's helpful.
我已经解决了此问题,方法是创建一个自定义构建任务,该任务在HeatDirectory任务之后运行,以将后缀附加到Id属性.
I had solved it by creating a custom build task to run after the HeatDirectory task to append a suffix to the Id attribute.
<AddSuffixToHeatDirectory File="ReportFiles.Generated.wxs" Suffix="_r" />
AddSuffixToHeatDirectory任务就是这样
The AddSuffixToHeatDirectory task is as such
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; }
}
希望有帮助.今天,我仍在使用此方法,而且还没有完成研究Transform或扩展HeatDirectory的工作.
Hope that helps. I'm still using this method today and I've not done the legwork to look into a Transform or extending HeatDirectory.
这篇关于如何对具有相同文件的目录进行HeatDirectory 2次或更多次?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!