2011-09-23 35 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的回答