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.
|
+- <UsingTask TaskName="BuildOrmLayerTask" AssemblyFile="$(TaskAssembly)" />
但是,当项目 (2) 生成时,它会锁定项目 (1) 中的程序集。所以现在我无法在不关闭解决方案并重新打开它的情况下再次构建项目 (1)。
有什么方法可以组织事物,以便自定义构建任务不会被 Visual Studio 锁定?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
(编辑: 赛义德·易卜拉欣·哈希米,字面意思是写了关于 msbuild 的书,建议 AppDomainIsolatedTask 类以获得更好的方法)
我自己设法解决了这个问题...
找到了这个 来自 Dan Moseley 的论坛帖子 ,来自微软的 MSBuild 开发人员之一:
因此,似乎要停止锁定,您必须生成一个新的 MSBuild.exe 进程。它不能是在 Visual Studio 内部运行的任务,因为当 MSBuild 运行时,它将任务加载到 Visual Studio 的主应用程序域中,并且永远无法卸载。
创建一个新的 MSBuild 项目(.csproj 或类似文件),该项目将覆盖“构建”目标并执行您的自定义操作,例如;
如果需要,可以将其添加到 Visual Studio,但使用配置管理器来确保它未内置在任何配置中。只需让 VS 处理源代码控制等事务,而不是构建。
编辑依赖于
Prebuild.csproj
的项目的.csproj文件。添加一个BeforeBuild
目标,该目标使用Exec
任务调用 MSBuild。这将启动一个新进程,当该进程结束时,文件锁将被释放。示例;现在,当您构建依赖项目时,它会在运行编译之前在新进程中执行 MSBuild。
(Edit: Sayed Ibrahim Hashimi, who literally wrote the book on msbuild, suggests the AppDomainIsolatedTask class for a better approach)
I've managed to solve this one myself...
Found this forum post from Dan Moseley, one of the MSBuild developers from Microsoft:
So, it seems that to stop the locks, you must spawn out a new MSBuild.exe process. It can't be the one that runs inside Visual Studio, because when MSBuild runs, it loads the tasks into Visual Studio's primary app domain, and that can never be unloaded.
create a new MSBuild project (a .csproj or similar) which overrides the 'Build' Target and performs your custom actions, eg;
Add it to visual studio if you want, but use Configuration Manager to make sure it is notbuilt in any configuration. Just let VS take care of source control and suchlike, not building.
Edit the .csproj file of the project that depends on
Prebuild.csproj
. Add aBeforeBuild
target which invokes MSBuild using theExec
task. This will start a new process, and when that process ends, the file locks are released. Example;Now, when you build the dependent project, it executes MSBuild in a new process before running the compile.
您可以编辑项目文件并包含以下属性声明吗?
请告诉我这是否适合您。
Can you edit the project files and include the following property declaration
Let me know if that works for you.
正如我在针对 @Al-Muhandis 的评论中提到的,似乎可以围绕自定义任务创建一个包装器,以便包装器被锁定,但自定义任务 DLL 不会被锁定。我已经通过 isolated-task 项目初步尝试这样做。它可能有 bug,并且目前仅适用于 VS2008。欢迎拉请求。
该项目的想法是基于这样的观察:从
MarshalByRefObject
派生的任务(可能使用AppDomainIsolatedTask
)似乎出于反射目的而加载到主应用程序域中,但是创建一个新的应用程序域来执行该任务。由于加载到主应用程序域似乎仍然会锁定 DLL,因此使用从加载自定义任务 DLL 的AppDomainIsolatedTask
派生的任务创建 DLL 非常有用。这样,包装器 DLL 就会被锁定,但由于它在自己的应用程序域中执行,因此当包装器任务的执行域被卸载时,自定义任务 DLL 也会被卸载。此过程可避免在构建完成后锁定自定义任务 DLL。As I mentioned in a comment directed at @Al-Muhandis, it seems possible to create a wrapper around the custom task so that the wrapper gets locked but not the custom task DLL. I have taken an initial shot at doing so with the isolated-task project. It may be buggy, and it only works with VS2008 for now. Pull requests welcome.
The idea for the project was based on the observation that tasks deriving from
MarshalByRefObject
(using, perhaps,AppDomainIsolatedTask
) appear to be loaded into the main application domain for reflection purposes, but a new application domain is created to execute the task. Since loading into the main application domain still seems to lock the DLL, it was useful to create a DLL with a task derived fromAppDomainIsolatedTask
that loads the custom task DLLs. That way, the wrapper DLL gets locked, but because it executes in its own app domain, the custom task DLLs are unloaded when the wrapper task's executing domain is unloaded. This procedure avoids keeping a lock on the custom task DLLs after the build is complete.