End Ziel:Inline MS Aufgabe beim Aufbau in separaten AppDomain
Ich möchte eine benutzerdefinierte Build-Aufgabe haben, die meine kompilierten Assembly nimmt, und extrahiert alle Instanzen eines bestimmten Attribut für die automatisierte Dokumentation und Deinstallation. (In diesem Fall das GUID-Attribut für eine Reihe von COM-sichtbaren Typen).
Problem:
Nach ein paar Beispiele zu lesen, die Aussicht auf eine Inline Build Task der Verwendung war ziemlich verlockend. Allerdings muss meine Aufgabe über die gebauten Assemblies hinweg reflektiert werden und bestimmte Metadaten daraus extrahieren (speziell Attribute).
Der Catch widerspiegelt die Assembly wird die Ausgabedatei sperren, bis die AppDomain entladen wird, die in diesem Fall nur zu sein scheint, wenn Visual Studio geschlossen ist. Das Ergebnis: Der Build kann nur einmal pro Sitzung erstellt werden.
Ich sehe, dass es spezielle Build-Aufgabenklassen gibt, nämlich AppDomainIsolatedTask
, aber ich kann keine Beispiele oder Beweise finden, dass diese Klasse für eine Inline-Aufgabe verwendet werden kann.
Frage:
Ist es möglich, eine Inline-Build-Aufgabe in einem separaten AppDomain zu laufen? Wenn ja, wie?
Codebeispiel: (so kurz wie möglich)
<UsingTask TaskName="InDomainTask" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
<Task><Code Type="Class" Language="cs"><![CDATA[
public class InDomainTask : Microsoft.Build.Utilities.Task
{
public override bool Execute()
{
Log.LogMessage("InDomainTask AppDomain.Id = " + System.AppDomain.CurrentDomain.Id);
return true;
}
}
]]></Code></Task>
</UsingTask>
<UsingTask TaskName="OutDomainTask" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
<Task><Code Type="Class" Language="cs"><![CDATA[
[Microsoft.Build.Framework.LoadInSeparateAppDomain]
public class OutDomainTask : Microsoft.Build.Utilities.AppDomainIsolatedTask
{
public override bool Execute()
{
Log.LogMessage("OutDomainTask AppDomain.Id = " + System.AppDomain.CurrentDomain.Id);
return true;
}
}
]]></Code></Task>
</UsingTask>
<Target Name="AfterBuild" AfterTargets="Compile">
<InDomainTask />
<OutDomainTask />
</Target>
Die Build-Ausgabe davon ist:
1> InDomainTask AppDomain.Id = 1 1> OutDomainTask AppDomain.Id = 1