Подобные вещи могут быть очень сложными, чтобы получить право. Существует множество факторов, которые следует учитывать в LoaderOptimization, ShadowCopy и т. Д.
AppDomainIsolatedTask
не означает «не загрязнять домен сборки».
Это означает «запустить мой код в другом домене» - сам тип задачи все еще загружен в домен механизма сборки. Это прискорбно, так как я чувствую, что большинство людей интерпретируют это как первое. Чтобы этот специализированный тип задачи работал, вы также должны декоратировать свою задачу с помощью [LoadInSeparateAppDomain]
. Это все еще не решит вашу проблему.
ProcessExplorer имеет это удобное представление сборок .NET, которое вы можете использовать, чтобы определить, какой домен имеет дескриптор вашей сборки. Как вы уже знаете, devenv.exe заблокирован.
![Useful feature](https://i.stack.imgur.com/HwH1J.png)
Поскольку вы загружаете DLL-библиотеку, которая выполняет задачу, в домен, который VS использует для создания материала, вы столкнетесь с этой проблемой.
Что вам нужно сделать, это ввести еще один слой косвенности.
Опция
- Вы можете преобразовать свою задачу в задачу со встроенным кодом .
- Вы можете использовать задачу встроенного кода, чтобы загрузить статическую задачу и делегировать ее.
Я привел пример для подхода № 2
Этот снимок экрана подтверждает результаты, что моя пользовательская библиотека отсутствует в домене приложения MSBuild.
Определите встроенное задание следующим образом:
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask
TaskName="RunOtherTask"
TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll" >
<ParameterGroup />
<Task>
<Using Namespace="MyTasks" />
<Code Type="Class" Language="cs">
<![CDATA[
using System;
using System.Reflection;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
namespace MyTasks {
public class RunOtherTask : Task {
public override bool Execute() {
var remoteTask = CreateInstanceInSeparateDomain();
remoteTask.BuildEngine = this.BuildEngine;
remoteTask.Execute();
return true;
}
private ITask CreateInstanceInSeparateDomain() {
var thisAssembly = Assembly.GetExecutingAssembly();
var setup = new AppDomainSetup {
ShadowCopyFiles = true.ToString(),
LoaderOptimization = LoaderOptimization.MultiDomainHost
};
var domain = AppDomain.CreateDomain("MyDomain", null, setup);
var handle = domain.CreateInstanceFrom(@"C:\ClassLibrary1.dll", "ClassLibrary1.SimpleTask");
return (ITask)handle.Unwrap();
}
}
}
]]>
</Code>
</Task>
</UsingTask>
<Target Name="RunTask">
<RunOtherTask />
</Target>
</Project>
Пока ваша задача реализует ITask (что она должна), она будет работать.
Вам нужно установить свойство engine в только что созданной задаче, чтобы все работало правильно.
![Class Library1 is not loaded](https://i.stack.imgur.com/D7x6b.png)