Я разрабатываю пользовательскую задачу MSBuild, которая строит
Visual Studio 2008 блокирует пользовательские сборки MSBuild Task
Ответ 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 "$(PrebuildProject)"" /> </Target>
Теперь, когда вы строите зависимый проект, он запускает MSBuild в новом процессе перед запуском компиляции.
Ответ 2
Вы можете редактировать файлы проекта и включать следующее объявление свойства
<PropertyGroup>
<GenerateResourceNeverLockTypeAssemblies>true</GenerateResourceNeverLockTypeAssemblies>
</PropertyGroup>
Сообщите мне, если это сработает для вас.
Ответ 3
Как я упоминал в комментарии, адресованном @Al-Muhandis, представляется возможным создать оболочку вокруг пользовательской задачи, чтобы обертка была заблокирована, но не настраиваемая DLL задачи. Я сделал первый выстрел при этом с проектом isolated-task. Он может быть неисправен, и он работает только с VS2008. Приглашаем вас приветствовать.
Идея проекта была основана на наблюдении, что задачи, вытекающие из MarshalByRefObject
(используя, возможно, AppDomainIsolatedTask
), загружаются в основной домен приложения для целей отражения, но создается новый домен приложения для выполнить задачу. Поскольку загрузка в основной домен приложения по-прежнему блокирует DLL, было полезно создать DLL с задачей, полученной из AppDomainIsolatedTask
, которая загружает DLL настраиваемых задач. Таким образом, DLL-обложка блокируется, но поскольку она выполняется в собственном домене приложения, DLL настраиваемых задач выгружается, когда выполняемая доменная операция-оболочка выгружается. Эта процедура позволяет избежать блокировки DLL настраиваемых задач после завершения сборки.