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

Visual Studio 2008 блокирует пользовательские сборки MSBuild Task

Я разрабатываю пользовательскую задачу MSBuild, которая строит

Однако, когда проект (2) строит, он фиксируется на сборке из проекта (1). Так что теперь я не могу построить проект (1) снова, не закрывая решение и не открывая его.

Можно ли каким-либо образом организовать так, чтобы задача пользовательской сборки не была заблокирована Visual Studio?

4b9b3361

Ответ 1

(Правка: Сайед Ибрагим Хашими, который буквально написал книгу о msbuild, предлагает класс AppDomainIsolatedTask для лучшего подхода)

Мне удалось решить это самому...

Нашел этот пост на форуме от Дэна Мозли, одного из разработчиков MSBuild от Microsoft:

Всем привет,

К сожалению, это связано с тем, что MSBuild загружает сборки задач в основном домене приложения. CLR не позволяет выгрузить сборки из домена приложения, поскольку это позволяет проводить важные оптимизации с их стороны.

Единственный обходной путь, который я предлагаю, это вызвать tomsbuild.exe для сборки проектов, использующих задачу. Для этого создайте MSBuild.exe <> в качестве внешнего инструмента в VS.

Дэн
разработчик на msbuild
ДэнМозли - MSFT

Таким образом, кажется, что для снятия блокировок вы должны создать новый процесс MSBuild.exe. Это не может быть тот, который работает в Visual Studio, потому что когда MSBuild работает, он загружает задачи в основной домен приложения Visual Studio, и это никогда не может быть выгружено.

  • создайте новый проект MSBuild (.csproj или аналогичный), который переопределяет цель 'Build' и выполняет ваши пользовательские действия, например;

    <!-- fragment of Prebuild.csproj -->   
    <Target Name="Build">   
         <BuildOrmLayerTask Repository="$(Repository)" />   
    </Target>
    
  • Добавьте его в Visual Studio, если хотите, но используйте Configuration Manager, чтобы убедиться, что он не встроен ни в одну конфигурацию. Просто позвольте VS позаботиться об управлении версиями и тому подобном, а не о сборке.

  • Отредактируйте файл .csproj проекта, который зависит от Prebuild.csproj. Добавьте цель BeforeBuild которая вызывает MSBuild с помощью задачи Exec. Это запустит новый процесс, и когда этот процесс завершится, блокировки файлов будут сняты. Пример;

    <PropertyGroup>   
         <PrebuildProject>$(SolutionDir)Prebuild\Prebuild.csproj</PrebuildProject>   
    </PropertyGroup>   
    <Target Name="BeforeBuild">   
         <Exec Command="msbuild.exe &quot;$(PrebuildProject)&quot;" />   
    </Target>
    

Теперь, когда вы строите зависимый проект, он запускает MSBuild в новом процессе перед запуском компиляции.

Ответ 2

Вы можете редактировать файлы проекта и включать следующее объявление свойства

<PropertyGroup>
    <GenerateResourceNeverLockTypeAssemblies>true</GenerateResourceNeverLockTypeAssemblies>
</PropertyGroup>

Сообщите мне, если это сработает для вас.

Ответ 3

Как я упоминал в комментарии, адресованном @Al-Muhandis, представляется возможным создать оболочку вокруг пользовательской задачи, чтобы обертка была заблокирована, но не настраиваемая DLL задачи. Я сделал первый выстрел при этом с проектом isolated-task. Он может быть неисправен, и он работает только с VS2008. Приглашаем вас приветствовать.

Идея проекта была основана на наблюдении, что задачи, вытекающие из MarshalByRefObject (используя, возможно, AppDomainIsolatedTask), загружаются в основной домен приложения для целей отражения, но создается новый домен приложения для выполнить задачу. Поскольку загрузка в основной домен приложения по-прежнему блокирует DLL, было полезно создать DLL с задачей, полученной из AppDomainIsolatedTask, которая загружает DLL настраиваемых задач. Таким образом, DLL-обложка блокируется, но поскольку она выполняется в собственном домене приложения, DLL настраиваемых задач выгружается, когда выполняемая доменная операция-оболочка выгружается. Эта процедура позволяет избежать блокировки DLL настраиваемых задач после завершения сборки.