2011-09-23 9 views
20

もう一度私はMSBuildと戦っています。私はルートパスで定義されたプロパティ値を持っています。ビルドの一部として、パスはバージョン情報で更新されます。しかし、MSBuildは完全に後方に見える独自のスコープ規則を持っているようです。この最初の例を見てみましょう:MSBuildプロパティスコープ

<?xml version="1.0" encoding="utf-8"?> 
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5"> 

    <PropertyGroup> 
    <MyPath>\\server\folder</MyPath> 
    </PropertyGroup> 

    <Target Name="Main"> 
    <Message Text="In Main Before - MyPath = $(MyPath)"/> 
    <CallTarget Targets="Task1" /> 
    <CallTarget Targets="Task2" /> 
    <CallTarget Targets="Task3" /> 
    <Message Text="In Main After - MyPath = $(MyPath)"/> 
    </Target> 

    <Target Name="Task1"> 
    <PropertyGroup> 
     <MyPath>$(MyPath)\version5</MyPath> 
    </PropertyGroup> 
    <Message Text="In Task1 - MyPath = $(MyPath)"/> 
    </Target> 

    <Target Name="Task2"> 
    <Message Text="In Task2 - MyPath = $(MyPath)"/> 
    </Target> 

    <Target Name="Task3"> 
    <Message Text="In Task3 - MyPath = $(MyPath)"/> 
    </Target> 

</Project> 

は、ここでは、このコマンドラインで出力です:msbuild PropertyScopeTest1.proj /target:Main

Project "C:\Temp\PropertyScopeTest1.proj" on node 1 (Main target(s)). 
Main: 
    In Main Before - MyPath = \\server\folder 
Task1: 
    In Task1 - MyPath = \\server\folder\version5 
Task2: 
    In Task2 - MyPath = \\server\folder\version5 
Task3: 
    In Task3 - MyPath = \\server\folder\version5 
Main: 
    In Main After - MyPath = \\server\folder 
Done Building Project "C:\Temp\PropertyScopeTest1.proj" (Main target(s)). 

は今、ここでの主なターゲットにMYPATH変数を設定し、わずかに異なるバージョンがあります:

<?xml version="1.0" encoding="utf-8"?> 
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5"> 

    <PropertyGroup> 
    <MyPath>\\server\path</MyPath> 
    </PropertyGroup> 

    <Target Name="Main"> 
    <Message Text="In Main Before - MyPath = $(MyPath)"/> 
    <PropertyGroup> 
     <MyPath>$(MyPath)\version5</MyPath> 
    </PropertyGroup> 
    <Message Text="In Main After PropertyGroup - MyPath = $(MyPath)"/> 
    <CallTarget Targets="Task1" /> 
    <CallTarget Targets="Task2" /> 
    <CallTarget Targets="Task3" /> 
    <Message Text="In Main After - MyPath = $(MyPath)"/> 
    </Target> 

    <Target Name="Task1"> 
    <Message Text="In Task1 - MyPath = $(MyPath)"/> 
    </Target> 

    <Target Name="Task2"> 
    <Message Text="In Task2 - MyPath = $(MyPath)"/> 
    </Target> 

    <Target Name="Task3"> 
    <Message Text="In Task3 - MyPath = $(MyPath)"/> 
    </Target> 

</Project> 

このコマンドラインの出力は次のとおりです。msbuild PropertyScopeTest2.proj /target:Main

Project "C:\Temp\PropertyScopeTest2.proj" on node 1 (Main target(s)). 
Main: 
    In Main Before - MyPath = \\server\path 
    In Main After PropertyGroup - MyPath = \\server\path\version5 
Task1: 
    In Task1 - MyPath = \\server\path 
Task2: 
    In Task2 - MyPath = \\server\path 
Task3: 
    In Task3 - MyPath = \\server\path 
Main: 
    In Main After - MyPath = \\server\path\version5 
Done Building Project "C:\Temp\PropertyScopeTest2.proj" (Main target(s)). 

このサイトの他のリンクも同様ですが、MSBuildプロジェクトファイル内からMSBuildタスクを呼び出しているようです。私がしたいのは、パスを更新してプロジェクトのどこでも利用できるようにすることだけです。何か案は?

答えて

23

ビルを使用してターゲットと呼ばれるにアクセスすることはできません ある終了します

<?xml version="1.0" encoding="utf-8"?> 
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5"> 

    <PropertyGroup> 
    <MyPath>\\server\folder</MyPath> 
    </PropertyGroup> 

    <Target Name="Main" DependsOnTargets="SetMyPathProperty"> 
    <Message Text="In Main Before - MyPath = $(MyPath)"/> 
    <CallTarget Targets="Task1" /> 
    <Message Text="In Main After - MyPath = $(MyPath)"/> 
    </Target> 

    <Target Name="SetMyPathProperty"> 
    <PropertyGroup> 
     <MyPath>$(MyPath)\version5</MyPath> 
    </PropertyGroup> 
    </Target> 

    <Target Name="Task1"> 
    <Message Text="In Task1 - MyPath = $(MyPath)"/> 
    </Target> 

</Project> 

ビルド出力:

Main: 
    In Main Before - MyPath = \\server\folder\version5 
Task1: 
    In Task1 - MyPath = \\server\folder\version5 
Main: 
    In Main After - MyPath = \\server\folder\version5 
が期待される動作が得られます

SetMyPathProperty代わりメインタスク1の依存性は、あなたのPropertyScopeTest1.projと同じ動作になります作ります。

+0

この解決法は私にははるかに意味があります。私はこれを明日試して、それが私のユースケースのためにうまくいくかどうかを見極める予定です。 – dprice

+0

このソリューションを試してみました。本当にありがとう! – dprice

16

これは、次の資料に例を深く検討されている非常に興味深い質問です:Scope of properties and item in an MSBuild script

は、基本的には、ローカルおよびグローバルな文脈でのトリックがあるが、ターゲットの実行間で切り替わり:

  • ワンProjectクラスのインスタンスがスクリプト用に作成され、 には、グローバル コンテキスト内のプロパティと項目のすべての値が含まれています。
  • ターゲットが実行されると、グローバルコンテキストはターゲットによって使用されるローカルの コンテキストにコピーされます。
  • ターゲットの実行が終了すると、ローカルコンテキスト更新はグローバルコンテキストに戻されます。 ターゲットの実行まで
  • は新しいパスに依存関係を設定する目標を作る代わりに使用して、ローカルアップデートがSLLの答えにCallTargetかのMSBuildタスクに