Visual Studio 2008锁定自定义MSBuild任务程序集

我正在开发一个自定义MSBuild任务,它构建一个ORM层 ,并在项目中使用它。 我受到Visual Studio保留MSBuild任务DLL而不放手的行为的阻碍。

我想像这样组织我的解决方案;

My Solution | +- (1) ORM Layer Custom Task Project | | | +- BuildOrmLayerTask.cs // here's my task | +- (2) Business Logic Project // and here's the project that uses it. | +-  

但是,当项目(2)构建时,它会从项目(1)锁定到程序集。 所以现在我无法在不关闭解决方案并重新打开它的情况下再次构建项目(1)。

有没有什么方法可以组织事情,以便自定义构建任务不被Visual Studio锁定?

编辑: Sayed Ibrahim Hashimi ,他在msbuild上写了这本书 ,建议使用AppDomainIsolatedTask类来获得更好的方法)

我自己设法解决了这个问题……

从Microsoft Moseley ,Microsoft的MSBuild开发人员发现此论坛post :

嗨,您好,

不幸的是,这是因为MSBuild在主应用程序域中加载任务程序集。 CLR不允许程序集从appdomain卸载,因为这样可以对其进行重要的优化。

我建议的唯一解决方法是调用tomsbuild.exe来构建使用该任务的项目。 为此,请在VS中创建MSBuild.exe <>作为外部工具。


msbuild上的开发人员
丹莫斯利 – MSFT

因此,似乎要停止锁定,您必须生成一个新的MSBuild.exe进程。 它不能是在Visual Studio中运行的那个,因为当MSBuild运行时,它会将任务加载到Visual Studio的主应用程序域中,并且永远无法卸载。

  • 创建一个新的MSBuild项目(.csproj或类似项目),它覆盖“Build”目标并执行自定义操作,例如;

         
  • 如果需要,可将其添加到visual studio,但使用Configuration Manager确保它不是以任何配置构建的。 只是让VS负责源代码控制等,而不是构建。

  • 编辑依赖于Prebuild.csproj的项目的.csproj文件。 添加一个BeforeBuild目标,该目标使用Exec任务调用MSBuild。 这将启动一个新进程,当该进程结束时,将释放文件锁。 例;

      $(SolutionDir)Prebuild\Prebuild.csproj     

现在,当您构建依赖项目时,它会在运行编译之前在新进程中执行MSBuild。

您可以编辑项目文件并包含以下属性声明

  true  

如果这对您有用,请告诉我。

正如我在针对@ Al-Muhandis的评论中提到的,似乎可以围绕自定义任务创建一个包装器,以便包装器被锁定但不是自定义任务DLL。 我已经对孤立任务项目进行了初步尝试。 它可能是错误的,它现在只适用于VS2008。 拉请求欢迎。

该项目的想法是基于这样的观察:从MarshalByRefObject派生的任务(可能使用AppDomainIsolatedTask )似乎被加载到主应用程序域中以用于reflection目的,但是创建了一个新的应用程序域来执行该任务。 由于加载到主应用程序域似乎仍然锁定DLL,因此创建一个DLL,其中包含从AppDomainIsolatedTask派生的任务,该任务加载自定义任务DLL。 这样,包装器DLL被锁定,但由于它在自己的应用程序域中执行,因此在卸载包装器任务的执行域时卸载自定义任务DLL。 此过程可避免在构建完成后保留对自定义任务DLL的锁定。