Как развернуть пользовательскую задачу MSBuild с помощью MEF?

У меня есть несколько пользовательских шаблонов элементов и проектов для Visual Studio 2010. Я создал пакет VSIX, который можно использовать для развертывания этих расширений на компьютерах нескольких разработчиков.

Сейчас я создаю пользовательскую задачу MSBuild, которая потребуется для нового шаблона элемента.

В моем локальном проекте я могу заставить это работать, вставив жестко заданный путь в файл проекта:

Но это не работает, когда пакет VSIX развернут в экземпляре Visual Studio dev. Visual Studio просто сообщает, что CustomBuildTask.dll не может быть найден.

Где VSIX развертывает DLL? Существует ли переменная MSBuild %(path), которую я могу использовать для поиска DLL на других компьютерах, или каждый пользователь должен вручную скопировать DLL и / или поместить глобальный файл ".tasks" в свою установку Visual Studio?

ПРИМЕЧАНИЕ. Тип задач VSIX для задач MSBuild отсутствует, как для шаблонов элементов и проектов. Я пробовал "VS Package", "MEF Component" и "Custom Extension Type" - и ни один из них не работает.

1 ответ

Решение

Я не верю, что вы можете сделать это, поскольку пакеты VSIX не могут устанавливать файлы в произвольных местах, и задача msbuild должна находиться в папке msbuild.

Решение для Visual Studio 2017/2019, которое, вероятно, сработало бы в 2010 году (поскольку тогда был доступен Microsoft.VisualStudio.TemplateWizard), состоит в том, чтобы создать мастер и указать путь к месту установки расширения в словаре замен и использовать замена в шаблоне на UsingTask.

public class ProjectLocationWizard : IWizard
{
    public void BeforeOpeningFile(ProjectItem projectItem)
    {
    }

    public void ProjectFinishedGenerating(Project project)
    {
    }

    public void ProjectItemFinishedGenerating(ProjectItem projectItem)
    {
    }

    public void RunFinished()
    {
    }

    public void RunStarted(object automationObject, Dictionary<string, string> replacementsDictionary, WizardRunKind runKind, object[] customParams)
    {
        var wizardDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
        replacementsDictionary.Add("$installlocation$", wizardDirectory);
    }

    public bool ShouldAddProjectItem(string filePath)
    {
        return true;
    }
}

<UsingTask AssemblyFile="$installlocation$\MyTask.dll" TaskName="MyTask" />
Другие вопросы по тегам