2011-09-23 64 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

大廈稱爲目標接近,使這臺新路徑依賴的目標,而不是使用CallTarget將產生預期的行爲:

<?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類的實例是爲腳本創建的,並且 包含全局 上下文中的屬性和項目的所有值。
  • 執行目標時,將全局上下文複製到目標使用的本地 上下文中。
  • 目標執行結束時,本地上下文更新合併爲 回到全局上下文。
  • 直到目標執行完成本地更新不 使用CallTarget或MSBuild任務上SLL的回答