22

私は MSBuild が初めてで、少し試してみたいと思っていましたが、なぜこれが機能しないのかわかりません。

したがって、私のソリューションには「Model」と「BuildTasks」の 2 つのプロジェクトがあります。BuildTasks には 1 つのクラスしかありません。

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」の前にビルドされるように、ビルド順序を設定しました。しかし、モデルを構築しようとすると、次のエラーが発生します。

"BuildTasks.Test" タスクをアセンブリ C:\WIP\TestSolution\src\BuildTasks\bin\BuildTasks.dll から読み込めませんでした。ファイルまたはアセンブリ 'file:///C:\WIP\TestSolution\src\BuildTasks\bin\BuildTasks.dll' またはその依存関係の 1 つを読み込めませんでした。システムは、指定されたファイルを見つけることができません。<UsingTask> 宣言が正しいこと、およびアセンブリとそのすべての依存関係が利用可能であることを確認してください。

このファイルは確かに存在するのに、なぜ MSBuild はそれを見つけられないのでしょうか?

「$(SolutionDir)」の代わりに「C:\WIP\TestSolution」をハードコーディングしようとしても、同じエラーが発生します。ただし、その .dll をデスクトップにコピーし、デスクトップへのパスをハードコーディングすると、動作しますが、理由がわかりません。

編集:パスが間違っていません。BuildTasks のデバッグ/リリース ビルドを変更して、.dll を bin フォルダーだけに出力するようにしました。これは、デバッグ/リリースに異なるパスを持たせたくないためです。

4

7 に答える 7

14

これを試してみたところ、UsingTask をプロジェクト ファイルの先頭に配置する必要があることがわかりました (そして、すべてのパスを正しくする必要があります)。ただし、それが配置され、タスクがロードされると、一度しか機能しません。その後、タスクが含まれている DLL をコピーできないため、ビルドが失敗し始めます。実際には、ビルドしているのと同じアセンブリ/プロジェクト内でビルド後のタスクを実行しています。

これを解決するために、別の MSBuild ファイルで別の MSBuild プロセスを起動して、ビルド後のタスクを実行しました。そうすれば、DLL はビルドされて bin ディレクトリにコピーされるまでロードされません。

<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>
于 2010-07-08T21:52:29.317 に答える
2

すべてのカスタム タスクがAppDomainIsolatedTaskMSBUILDDISABLENODEREUSE = 1から継承され、 Visual Studio を起動する前に 環境変数を設定すると、カスタム タスク DLL のロックを回避できます。

カスタム ビルド タスクを含むアセンブリは、devenv.exe と msbuild.exe の両方によってロックされます。

で msbuild.exe プロセスをなくすことはできますが、カスタム タスクがTaskMSBUILDDISABLENODEREUSE = 1から継承されている場合、devenv.exe はカスタム タスク アセンブリを散発的にロックします。

一方、AppDomainIsolatedTask からのみ継承しMSBUILDDISABLENODEREUSE、アイドル状態の MSBuild プロセスを設定しない場合でも、アセンブリはロックされます。

于 2016-05-20T10:46:07.817 に答える
1

Slaceは正しかった。アセンブリへのパスが間違っている可能性が高いです。そして、それはおそらく次のようになるはずです:

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

<Target Name="AfterBuild">
    <Test />
</Target>
于 2008-11-12T01:55:54.277 に答える
1

MSBuild ノードの再利用を無効にすると、この問題も修正されます。

  • MSBuild コマンド ラインで、/nr:falseオプションを渡します。
  • Visual Studio の場合、VS を開始する前にMSBUILDDISABLENODEREUSE環境変数をに設定する必要があります。1

Visual Studio 2012 RTM を閉じた後、メモリに MSBuild.exe があることを参照してください。

于 2016-05-20T10:09:46.950 に答える
0

パスを書いてよろしいですか?それはにあるべきではありませんbin\Configuration Type\BuildTasks.dllか?

私はこのリンクを見つけました:http://bartdesmet.net/blogs/bart/archive/2008/02/15/the-custom-msbuild-task-cookbook.aspxMSBuildタスクを書き始めるときに非常に役立ちました。

于 2008-11-12T00:33:39.200 に答える
0

fuslogvwを試して問題を診断することもできますが、それがそれほど進んでいるかどうかはわかりません...

http://msdn.microsoft.com/en-us/library/e74a18c4.aspx

于 2008-11-12T23:08:43.960 に答える