[英]Use custom MSBuild tasks from the same solution?
我是 MSBuild 的新手,想稍微玩一下,但我不知道为什么这不起作用。
所以我的解决方案有两个项目:“Model”和“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”在“Model”之前构建。 但是当我尝试构建模型时,我收到此错误:
无法从程序集 C:\\WIP\\TestSolution\\src\\BuildTasks\\bin\\BuildTasks.dll 加载“BuildTasks.Test”任务。 无法加载文件或程序集“file:///C:\\WIP\\TestSolution\\src\\BuildTasks\\bin\\BuildTasks.dll”或其依赖项之一。 该系统找不到指定的文件。 确认 <UsingTask> 声明是正确的,并且程序集及其所有依赖项都可用。
这个文件肯定存在,为什么MSBuild找不到呢?
我什至尝试硬编码 "C:\\WIP\\TestSolution" 代替 "$(SolutionDir)" 并得到相同的错误。 但是,如果我将该 .dll 复制到我的桌面并将路径硬编码到我的桌面,它确实可以工作,但我不知道为什么。
编辑:我没有错误的路径。 我修改了 BuildTasks 的 Debug/Release 构建,以将 .dll 输出到 bin 文件夹,因为我不希望 Debug/Release 有不同的路径。
我们尝试了这个,我们发现您必须将 UsingTask 放在项目文件的顶部(并且所有路径都正确)。 然而,一旦到位并且任务加载,它只会工作一次。 在那之后,构建开始失败,因为它无法复制任务所在的 DLL。我们实际上正在运行我们正在构建的同一个程序集/项目中的构建后任务。
我们为解决这个问题所做的是在单独的 MSBuild 文件上启动一个单独的 MSBuild 进程来运行 Post Build 任务。 这样,DLL 在构建并复制到 bin 目录之后才会加载。
<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>
如果所有自定义任务都继承自AppDomainIsolatedTask并且在启动 Visual Studio 之前设置环境变量MSBUILDDISABLENODEREUSE = 1
,则可以避免锁定自定义任务 DLL。
带有自定义生成任务的程序集由 devenv.exe 和 msbuild.exe 锁定。
您可以使用MSBUILDDISABLENODEREUSE = 1
使 msbuild.exe 进程消失,但如果您的自定义任务继承自Task ,devenv.exe 仍会偶尔锁定自定义任务程序集。
另一方面,如果您仅从 AppDomainIsolatedTask 继承并且不设置MSBUILDDISABLENODEREUSE
,空闲的 MSBuild 进程仍将锁定程序集。
斯莱斯说得对。 您的组装路径很可能是错误的。 它应该是:
<UsingTask
TaskName="BuildTasks.Test"
AssemblyFile="$(SolutionDir)src\BuildTasks\bin\$(Configuration)\BuildTasks.dll" />
<Target Name="AfterBuild">
<Test />
</Target>
禁用 MSBuild 节点重用也将解决此问题:
/nr:false
选项。MSBUILDDISABLENODEREUSE
环境变量设置为1
。你确定你的路径写了吗? 它不应该在bin\\Configuration Type\\BuildTasks.dll
吗?
我发现这个链接: http : //bartdesmet.net/blogs/bart/archive/2008/02/15/the-custom-msbuild-task-cookbook.aspx在开始编写 MSBuild 任务时非常有帮助。
您可能会尝试使用 fuslogvw 来诊断问题,我想我不清楚它是否有那么远......
在我们的案例中,将 PlaformTarget 添加到项目文件 (.csproj) 解决了该问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.