Предположим, я добавляю пользовательскую цель в файл csproj. Есть ли способ запустить эту цель из визуальной студии? Я не хочу, чтобы он делал шаг prebuild или postbuild, я просто хочу иметь возможность запускать эту цель (и ее зависимости) из visual studio.
Запустить пользовательскую цель msbuild из VisualStudio
Ответ 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"
целевой объект.