gpt4 book ai didi

msbuild - 自定义 MSBuild 任务锁定程序集

转载 作者:行者123 更新时间:2023-12-03 15:04:10 26 4
gpt4 key购买 nike

乍一看,我的问题似乎很常见:我的一些项目中有一个自定义的 MS Build 任务。编译项目后,我无法再编译构建任务 - 构建任务程序集被 Visual Studio 锁定。

我在这里发现很多帖子都说“只是从 AppDomainIsolatedTask 继承”。

我的任务已经完成了。该程序集除此任务外不包含任何其他内容。 AppDomain 似乎已卸载,至少触发了 DomainUnload 事件。并且,依赖程序集被正确卸载。

但是,包含构建任务本身的程序集被 devenv.exe 锁定(我通过 ProcessExplorer 进行了双重检查)。

我发现另一个帖子说“将 GenerateResourceNeverLockTypeAssemblies 属性设置为 true”,这听起来很有希望,但也没有帮助。

所以,我想知道还有什么问题。无论我使用 VS2008 还是 2010,行为都是相同的。

最佳答案

这种事情可能非常棘手。有很多需要考虑的 LoaderOptimization、ShadowCopy 等。
AppDomainIsolatedTask并不意味着“不污染构建域”。
这意味着“在另一个域中运行我的代码”——任务类型本身仍被加载到构建引擎域中。这很不幸,因为我觉得大多数人将其解释为前者。要使这种专门的任务类型起作用,您还必须使用 [LoadInSeparateAppDomain] 对您的任务进行装饰。 .这仍然不能解决你的问题。

ProcessExplorer 有这个方便的 .NET 程序集 View ,您可以使用它来识别哪个域拥有程序集的句柄。如您所知,devenv.exe 已将其锁定。

Useful feature

由于您将具有任务的 DLL 加载到 VS 用于构建内容的域中,因此您将遇到此问题。

您需要做的是引入另一层间接。

选项

  • 您可以将您的任务转换为 inline code task .
  • 您可以使用内联代码任务来加载您的静态任务并委托(delegate)给它。

  • 我为方法 #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 (它必须),它就可以工作。
    您需要在新实例化的任务上设置引擎属性,以使一切正常工作。

    Class Library1 is not loaded

    关于msbuild - 自定义 MSBuild 任务锁定程序集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4460721/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com