Подтвердить что ты не робот

Запустить пользовательскую цель msbuild из VisualStudio

Предположим, я добавляю пользовательскую цель в файл csproj. Есть ли способ запустить эту цель из визуальной студии? Я не хочу, чтобы он делал шаг prebuild или postbuild, я просто хочу иметь возможность запускать эту цель (и ее зависимости) из visual studio.

4b9b3361

Ответ 1

Существует простой способ (хотя и не все, что удовлетворяет) с помощью настраиваемого внешнего инструмента.

Предполагая, что ваш файл проекта имеет следующую модификацию:

  <Target Name="CalledFromIde">
    <Error Text="Called from the IDE!" />
  </Target>

Перейдите в раздел Инструменты | Внешние инструменты и добавьте следующее:

  Title:      Called from IDE
  Command:    C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe
  Arguments:  $(ProjectDir)$(ProjectFileName) /t:CalledFromIde
  Initial directory:  $(ProjectDir)
  Use Output window:  checked

Выполнение этого вывода выводит как:

  Build FAILED.

  "F:\Code\CsProject\CsProject.csproj" (CalledFromIde target) (1) ->
  (CalledFromIde target) -> 
    F:\Code\CsProject\CsProject.csproj(57,5): error : Called from the IDE!

То, что вы делаете, - это вызов в MSBuild в качестве внешнего инструмента и непосредственный запуск цели. Вы должны предоставить полный путь к MSBuild, поскольку среда IDE не поддерживает те же свойства, что и созданная среда сборки.

Вы можете связать это с ярлыком, выяснив, какая команда # находится в наборе Tools.ExternalCommand #.

Если вы ищете решение с большей изощренностью, это немного более активно. Здесь он в двух словах (для VS2010):

1) Создайте VS Addin (Файл | Новый | Проект | Другие типы проектов | Расширяемость | Надстройка Visual Studio). Я не уверен, что вам нужно установить VS SDK для его получения, он доступен в диспетчере расширений.

Выберите в мастере следующие параметры:  - Microsoft Visual Studio 2010  - Да, создайте пункт меню "Инструменты"  - Загрузка при запуске приложения  - My Add-in никогда не будет устанавливать модальный пользовательский интерфейс и может использоваться с сборками командной строки.

2) Добавьте ссылки на Microsoft.Build и Microsoft.Build.Framework

3) Найдите реализацию Exec в файле Connect.cs

4) Замените его следующим кодом:

public void Exec(
    string commandName,
    vsCommandExecOption executeOption,
    ref object varIn,
    ref object varOut,
    ref bool handled)
{
    handled = false;
    if (executeOption != vsCommandExecOption.vsCommandExecOptionDoDefault)
        return;
    if (commandName != "BuildAddin.Connect.BuildAddin")
        return;

    var doc = _applicationObject.ActiveDocument;
    var projectItem = doc.ProjectItem;
    var project = projectItem.ContainingProject;
    var evalProject =
        Microsoft.Build.Evaluation.ProjectCollection
        .GlobalProjectCollection.LoadProject(project.FullName);
    var execProject = evalProject.CreateProjectInstance();

    bool success = execProject.Build("CalledFromIde", null);

    var window = _applicationObject.Windows.Item(Constants.vsWindowKindOutput);
    var output = (OutputWindow)window.Object;
    OutputWindowPane pane = output.OutputWindowPanes.Add("BuildAddin");
    pane.OutputString(success ? "built /t:CalledFromIde" : "build failed");

    handled = true;
    return;
}

5) Лучшая настраиваемая цель при отладке, поскольку предыдущие ошибки:

  <Target Name="CalledFromIde">
    <WriteLinesToFile File="CalledFromIde.txt" Lines="Called from the IDE!" />
  </Target>

6) В приведенном выше коде отсутствует проверка ошибок для краткости, вы захотите быть намного чище, так как он будет работать в среде IDE. Приложение добавит пункт меню в меню "Инструменты". Как написано выше, он просто ищет проект, содержащий текущий активный редакторский документ, для которого потребуется какая-то лучшая сантехника для всего, что вы готовите.

Этот метод получает экземпляр механизма сборки из среды IDE и выполняет его выполнение на отдельном экземпляре проекта.

Ответ 2

Если вы выполняете сборку внутри Visual Studio, во время сборки будет создана переменная сборки VisualStudioDir.

Для выполнения только сеанса сборки VS выполните следующее:

<Target Name="Test" BeforeTargets="Build" Condition="'$(VisualStudioDir)' != ''>
</Target>

Для выполнения только в сборке вне VS выполните следующее:

<Target Name="Test" BeforeTargets="Build" Condition="'$(VisualStudioDir)' == ''>
</Target>

Вам нужно будет добавить свой файл целевых целей одним из двух способов.

  • Задайте переменную среды CustomBeforeMicrosoftCommonTargets
  • Отредактируйте файл проекта, чтобы добавить свой файл целевых целей, добавив импорт

    <Imports Project="CustomBuildTasks.Targets"><Imports/>
    

Ответ 3

Вам не нужно кодировать Exec, хотя это один из способов сделать это. Более простой способ - сделать следующее:

Измените атрибут DefaultTargets="Build" на пользовательский целевой объект, который вы создаете, например "All":

DefaultTargets="All"

Затем в вашей настраиваемой цели "Все" вы можете использовать атрибут DependsOnTargets, например:

"<Target Name="All" DependsOnTargets="ZipOutputFiles;Build">
  </Target>"

Затем вы создадите и внесите zip файлы в свой собственный "All" целевой объект.