使用来自同一解决方案的自定义MSBuild任务?
我是一个MSBuild的新手,想玩一下它,但我无法弄清楚为什么这不起作用。使用来自同一解决方案的自定义MSBuild任务?
所以我的解决方案有两个项目:“模型”和“BuildTasks”。 BuildTasks只是有一个类:
using Microsoft.Build.Utilities;
namespace BuildTasks
{
public class Test : Task
{
public override bool Execute()
{
Log.LogMessage("FASDfasdf");
return true;
}
}
}
然后在Model.csproj我添加了这一点:
<UsingTask TaskName="BuildTasks.Test" AssemblyFile="$(SolutionDir)src\BuildTasks\bin\BuildTasks.dll" />
<Target Name="AfterBuild">
<Test />
</Target>
我已经设置了构建顺序,以便“BuildTasks”被前“建模型”。但是当我试图建立模型我得到这个错误:
The "BuildTasks.Test" task could not be loaded from the assembly C:\WIP\TestSolution\src\BuildTasks\bin\BuildTasks.dll. Could not load file or assembly 'file:///C:\WIP\TestSolution\src\BuildTasks\bin\BuildTasks.dll' or one of its dependencies. The system cannot find the file specified. Confirm that the <UsingTask> declaration is correct, and that the assembly and all its dependencies are available.
这个文件肯定存在,所以为什么不能MSBuild找到它?
我甚至试过在“$(SolutionDir)”的地方硬编码“C:\ WIP \ TestSolution”,并得到相同的错误。但是,如果我将该.dll复制到我的桌面并将路径硬编码到我的桌面,则工作,我不明白为什么。
编辑:我没有路径错误。我修改了BuildTasks的Debug/Release版本,将.dll输出到bin文件夹,因为我不想让Debug/Release具有不同的路径。
你确定你有你的路径写吗?它不应该在bin\Configuration Type\BuildTasks.dll
?
我发现这个链接:http://bartdesmet.net/blogs/bart/archive/2008/02/15/the-custom-msbuild-task-cookbook.aspx当开始编写MSBuild任务时非常有帮助。
我们尝试这样做,我们发现您必须将UsingTask放置在项目文件的顶部(并且拥有正确的所有路径)。然而,一旦这些就绪,并加载任务,它只会工作一次。之后,构建开始失败,因为它不能复制任务所在的DLL。我们实际上正在运行一个后期构建任务,这些任务位于我们正在构建的相同程序集/项目中。
我们解决这个问题的方法是在单独的MSBuild文件上启动一个单独的MSBuild进程来运行Post Build任务。这样,只有在构建并复制到bin目录后,DLL才会被加载。
<Target Name="AfterBuild">
<Exec Command="$(MSBuildBinPath)\MSBuild.exe
"$(MSBuildProjectDirectory)\PostBuild.msbuild"
/property:SomeProperty=$(SomeProperty)" />
</Target>
请注意,您可以在命令行中将属性传递到此子构建任务。
和PostBuild。MSBuild的是这样的:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="PostBuild" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<UsingTask TaskName="PostBuild" AssemblyFile="$(MSBuildProjectDirectory)\bin\AssemblyThatJustBuiltAndContainsBuildTask.dll" />
<PropertyGroup>
<SomeProperty>SomePropertyDefaultValue</SomeProperty>
</PropertyGroup>
<Target Name="PostBuild">
<MyPostBuildTask SomeProperty="$(SomeProperty)" />
</Target>
</Project>
非常感谢我为我工作的大好时光。 – daljit 2014-01-13 16:52:34
禁用的MSBuild节点再利用也将解决这个问题:
- 在MSBuild的命令行,传递
/nr:false
选项。 - 对于Visual Studio,必须在启动VS之前将
MSBUILDDISABLENODEREUSE
环境变量设置为1
。
见Visual Studio 2012 RTM has MSBuild.exe in memory after close
如果所有的自定义任务从AppDomainIsolatedTask 继承可以避免自定义任务的DLL的锁定,如果你启动Visual Studio之前设置环境变量MSBUILDDISABLENODEREUSE = 1
。
具有自定义构建任务的程序集同时被devenv.exe和msbuild.exe锁定。
您可以使msbuild.exe进程与MSBUILDDISABLENODEREUSE = 1
一起消失,但如果您的自定义任务继承自Task,devenv.exe仍会零星地锁定自定义任务程序集。另一方面,如果你只从AppDomainIsolatedTask继承,并且不设置MSBUILDDISABLENODEREUSE
,空闲的MSBuild进程仍然会锁定程序集。
你是否设法解决这个问题?我有同样的问题。 – sean 2009-05-03 17:18:12
3年没有解决?我有这个问题,但这篇文章没有帮助,因为它不清楚问题是不是已经解决了...... – DaveN59 2012-04-16 19:34:58