Как использовать HeatDirectory 2 и более раз для каталогов с одинаковыми файлами?

Я использовал задачу HeatDirectory в нашем проекте установщика WiX в цели BeforeBuild для сбора файлов веб-приложения, которое мы развертываем в клиентской сети. Работал отлично.

Теперь я хочу развернуть второй набор файлов, который является некоторой документацией и содержит файлы с теми же именами, что и в предыдущих выходных данных HeatDirectory.

Я получаю следующую ошибку:

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

Я понимаю, почему я получаю сообщение об ошибке, мне интересно, как лучше всего ее решить.

Вариант А:

Скопируйте все файлы в каталог и запустите их нагрев за один массивный проход.

Мне это нравится, потому что это было бы довольно легко реализовать, используя стандартные задачи MSBuild. Мне это не нравится, потому что это создаст одну массивную группу компонентов, и если я когда-нибудь решу сделать дополнительные функции (например, не устанавливать что-то), я не смогу.

Вариант Б:

Переберите выходной файл задачи HeatDirectory и добавьте суффикс ко всем идентификаторам компонентов и файлов. Пример — web.config станет web.config_DocuminationFiles

Мне это нравится, потому что это чисто; т. е. я могу удалить его позже или добавить в проект, в котором возникла проблема, и не добавлять его в проекты, в которых ее нет. Мне это не нравится, потому что я не уверен, какой «процесс» (или задача MSBuild) способен это сделать. Мне нужна специальная задача, я думаю.

Другие варианты: ?

Идеи?


person Rick Glos    schedule 09.02.2011    source источник


Ответы (2)


Задача HeatDirectory имеет атрибут Transforms, который можно использовать для преобразования файла результатов. Вы можете создать xslt, чтобы добавить свой суффикс к идентификаторам компонентов.

Кроме того, Heat — это расширяемый. Возможно, вы захотите создать свой собственный харвестер, который добавит для вас суффикс к идентификаторам компонентов.

person Aaron Carlson    schedule 15.02.2011
comment
Мне нравится эта идея, Аарон. Поскольку я задал вопрос, я создал пользовательскую задачу MSBuild для «исправления» файла фрагмента WiX и добавления суффикса, но для этого требуется установить пользовательскую задачу MSBuild на компьютере сборки и любых компьютерах разработчика, которые используют проект. Сначала я рассмотрю Transforms и XSLT. - person Rick Glos; 17.02.2011

Я вижу, кто-то пришел и проголосовал за это три года спустя. Я подумал, что вернусь и скажу, что я все еще использую вариант B, пользовательскую задачу MSBuild для решения проблемы.

Я сделал комментарий к другому сообщению о проблеме с более подробной информацией и решил переместить/скопировать свою реализацию здесь, в случае это полезно.

Я решил эту проблему, создав пользовательскую задачу сборки для запуска после задачи 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.

person Rick Glos    schedule 16.04.2014