2008-11-12 53 views
20

我是一個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具有不同的路徑。

+3

你是否設法解決這個問題?我有同樣的問題。 – sean 2009-05-03 17:18:12

+0

3年沒有解決?我有這個問題,但這篇文章沒有幫助,因爲它不清楚問題是不是已經解決了...... – DaveN59 2012-04-16 19:34:58

回答

2

Slace說得沒錯。你很可能有錯誤的路徑。它也許應該是:

<UsingTask 
    TaskName="BuildTasks.Test" 
    AssemblyFile="$(SolutionDir)src\BuildTasks\bin\$(Configuration)\BuildTasks.dll" /> 

<Target Name="AfterBuild"> 
    <Test /> 
</Target> 
+0

@Tinister:根據上面的編輯,在路徑中使用$(配置)是正確的方式,因爲它將是'釋放'或'調試'(或其他任何你使用的名字) – gregmac 2010-06-29 02:54:13

10

我們嘗試這樣做,我們發現您必須將UsingTask放置在項目文件的頂部(並且擁有正確的所有路徑)。然而,一旦這些就緒,並加載任務,它只會工作一次。之後,構建開始失敗,因爲它不能複製任務所在的DLL。我們實際上正在運行一個後期構建任務,這些任務位於我們正在構建的相同程序集/項目中。

我們解決這個問題的方法是在單獨的MSBuild文件上啓動一個單獨的MSBuild進程來運行Post Build任務。這樣,只有在構建並複製到bin目錄後,DLL纔會被加載。

<Target Name="AfterBuild"> 
    <Exec Command="$(MSBuildBinPath)\MSBuild.exe 
      &quot;$(MSBuildProjectDirectory)\PostBuild.msbuild&quot; 
      /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> 
+0

非常感謝我爲我工作的大好時光。 – daljit 2014-01-13 16:52:34

0

如果所有的自定義任務從AppDomainIsolatedTask 繼承可以避免自定義任務的DLL的鎖定,如果你啓動Visual Studio之前設置環境變量MSBUILDDISABLENODEREUSE = 1

具有自定義構建任務的程序集同時被devenv.exe和msbuild.exe鎖定。

您可以使msbuild.exe進程與MSBUILDDISABLENODEREUSE = 1一起消失,但如果您的自定義任務繼承自Task,devenv.exe仍會零星地鎖定自定義任務程序集。另一方面,如果你只從AppDomainIsolatedTask繼承,並且不設置MSBUILDDISABLENODEREUSE,空閒的MSBuild進程仍然會鎖定程序集。

相關問題