Использовать пользовательские задачи MSBuild из того же решения? - PullRequest
20 голосов
/ 12 ноября 2008

Я новичок в MSBuild и хотел немного поиграть с этим, но я просто не могу понять, почему это не работает.

Итак, у моего решения есть два проекта: «Модель» и «Задачи сборки». У BuildTasks только один класс:

using Microsoft.Build.Utilities;

namespace BuildTasks
{
    public class Test : Task
    {
        public override bool Execute()
        {
            Log.LogMessage( "FASDfasdf" );
            return true;
        }
    }
}

А потом в Model.csproj я добавил это:

  <UsingTask TaskName="BuildTasks.Test" AssemblyFile="$(SolutionDir)src\BuildTasks\bin\BuildTasks.dll" />
  <Target Name="AfterBuild">
    <Test />
  </Target>

Я установил порядок сборки, чтобы "BuildTasks" собирались раньше, чем "Модель". Но когда я пытаюсь построить модель, я получаю эту ошибку:

Не удалось выполнить задачу «BuildTasks.Test». быть загруженным из сборки C: \ WIP \ TestSolution \ SRC \ BuildTasks \ Bin \ BuildTasks.dll. Не удалось загрузить файл или сборку 'Файл: /// C: \ WIP \ TestSolution \ SRC \ BuildTasks \ Bin \ BuildTasks.dll' или одна из его зависимостей. Система не могу найти указанный файл. Подтвердите, что декларация верна, и что сборка и все ее зависимости имеется.

Этот файл определенно существует, так почему MSBuild не может его найти?

Я даже пытался жестко кодировать «C: \ WIP \ TestSolution» вместо «$ (SolutionDir)» и получал ту же ошибку. Однако, если я скопирую этот .dll на свой рабочий стол и жестко закодирую путь к нему, он ДЕЙСТВУЕТ , и я не могу понять, почему.

РЕДАКТИРОВАТЬ : Я не ошибся в пути. Я изменил сборки Debug / Release для BuildTasks, чтобы выводить .dll только в папку bin, так как я не хотел, чтобы Debug / Release имел разные пути.

Ответы [ 6 ]

11 голосов
/ 09 июля 2010

Мы попробовали это, и мы обнаружили, что вы должны поместить UsingTask вверху файла проекта (и правильно указать все пути). Однако, как только это произойдет, и задача будет загружена, она будет работать только один раз. После этого сборка начинает давать сбой, потому что она не может скопировать DLL, в которой находится задача. На самом деле мы запускаем задачу после сборки, которая находится в той же сборке / проекте, который мы строим.

Чтобы решить эту проблему, мы запустили отдельный процесс MSBuild для отдельного файла MSBuild для запуска задач Post Build. Таким образом, DLL не загружается до тех пор, пока не будет собрана и скопирована в каталог bin.

<Target Name="AfterBuild">
    <Exec Command="$(MSBuildBinPath)\MSBuild.exe 
          &quot;$(MSBuildProjectDirectory)\PostBuild.msbuild&quot; 
          /property:SomeProperty=$(SomeProperty)" />
</Target>

Обратите внимание, что вы можете передавать свойства в эту задачу подстройки в командной строке.

И PostBuild.msbuild выглядит так:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="PostBuild" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
    <UsingTask TaskName="PostBuild" AssemblyFile="$(MSBuildProjectDirectory)\bin\AssemblyThatJustBuiltAndContainsBuildTask.dll" />
    <PropertyGroup>
        <SomeProperty>SomePropertyDefaultValue</SomeProperty>
    </PropertyGroup>

    <Target Name="PostBuild">
        <MyPostBuildTask SomeProperty="$(SomeProperty)" />
    </Target>
</Project>
1 голос
/ 20 мая 2016

Блокировки библиотек DLL пользовательских задач можно избежать, если все пользовательские задачи наследуются от AppDomainIsolatedTask и если вы установите переменную среды MSBUILDDISABLENODEREUSE = 1 перед запуском Visual Studio.

Сборка с пользовательскими задачами сборки заблокирована как devenv.exe, так и msbuild.exe.

Вы можете заставить процессы msbuild.exe уходить с MSBUILDDISABLENODEREUSE = 1, но devenv.exe будет по-прежнему время от времени блокировать сборку пользовательских задач, если ваши пользовательские задачи наследуются от Task .

С другой стороны, если вы наследуете только от AppDomainIsolatedTask и не задаете MSBUILDDISABLENODEREUSE, то незанятые процессы MSBuild по-прежнему блокируют сборку.

1 голос
/ 20 мая 2016

Отключение повторного использования узла MSBuild также исправит эту проблему:

  • В командной строке MSBuild передайте параметр /nr:false.
  • Для Visual Studio необходимо установить для переменной среды MSBUILDDISABLENODEREUSE значение 1 перед запуском VS.

См. В Visual Studio 2012 RTM после закрытия MSBuild.exe находится в памяти

1 голос
/ 12 ноября 2008

Slace было правильно. Вы, скорее всего, ошиблись в пути к сборке. И это, вероятно, должно быть:

<UsingTask 
    TaskName="BuildTasks.Test" 
    AssemblyFile="$(SolutionDir)src\BuildTasks\bin\$(Configuration)\BuildTasks.dll" />

<Target Name="AfterBuild">
    <Test />
</Target>
1 голос
/ 12 ноября 2008

Вы уверены, что у вас есть свой путь записи? Разве это не должно быть в bin\Configuration Type\BuildTasks.dll?

Я нашел эту ссылку: http://bartdesmet.net/blogs/bart/archive/2008/02/15/the-custom-msbuild-task-cookbook.aspx очень полезно при написании задач MSBuild.

0 голосов
/ 13 ноября 2008

Вы можете попробовать fuslogvw, чтобы диагностировать проблему, подумал, что я не уверен, насколько далеко ...

http://msdn.microsoft.com/en-us/library/e74a18c4.aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...