导入另一个msbuild文件时,评估的顺序是什么?

时间:2012-03-02 16:35:21

标签: msbuild-4.0 msbuild-propertygroup

我有一个共享属性文件shared.properties.proj

<Project  xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <SharedAssemblySearch>$(MSBuildProjectDirectory)\..\Shared Assemblies</SharedAssemblySearch>
    <ParentDir>..</ParentDir>
    <SharedAssemblySearch Condition="!Exists('$(SharedAssemblySearch)')">$(ParentDir)\$(SharedAssemblySearch)</SharedAssemblySearch>
    <SharedAssemblySearch Condition="!Exists('$(SharedAssemblySearch)')">$(ParentDir)\$(SharedAssemblySearch)</SharedAssemblySearch>
    <SharedAssemblySearch Condition="!Exists('$(SharedAssemblySearch)')">$(ParentDir)\$(SharedAssemblySearch)</SharedAssemblySearch>
    <SharedAssemblySearch Condition="!Exists('$(SharedAssemblySearch)')">$(ParentDir)\$(SharedAssemblySearch)</SharedAssemblySearch>
    <SharedAssemblySearch Condition="!Exists('$(SharedAssemblySearch)')">$(ParentDir)\$(SharedAssemblySearch)</SharedAssemblySearch>
    <SharedAssemblySearch Condition="!Exists('$(SharedAssemblySearch)')">$(ParentDir)\$(SharedAssemblySearch)</SharedAssemblySearch>
    <SharedAssemblyPath Condition="Exists('$(SharedAssemblySearch)')">$(SharedAssemblySearch)</SharedAssemblyPath>
    <SharedAssemblySearch Condition="!Exists('$(SharedAssemblySearch)')">..\SharedAssemblies</SharedAssemblySearch>
    <SharedAssemblySearch Condition="!Exists('$(SharedAssemblySearch)')">$(ParentDir)\$(SharedAssemblySearch)</SharedAssemblySearch>
    <SharedAssemblySearch Condition="!Exists('$(SharedAssemblySearch)')">$(ParentDir)\$(SharedAssemblySearch)</SharedAssemblySearch>
    <SharedAssemblySearch Condition="!Exists('$(SharedAssemblySearch)')">$(ParentDir)\$(SharedAssemblySearch)</SharedAssemblySearch>
    <SharedAssemblySearch Condition="!Exists('$(SharedAssemblySearch)')">$(ParentDir)\$(SharedAssemblySearch)</SharedAssemblySearch>
    <SharedAssemblyPath Condition="Exists('$(SharedAssemblySearch)')">$(SharedAssemblySearch)</SharedAssemblyPath>
 </PropertyGroup>
</project>

我正在搜索任何级别的父目录包含名为Shared Assemblies的目录。或者SharedAssemblies

我想将此代码放在sln的中心位置,以便所有项目都可以导入它。 sln中的项目并非都处于同一层级。

示例.csproj

    <?xml version="1.0" encoding="utf-8"?>
    <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), Shared.Properties.proj))\Shared.Properties.proj"
   Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), Shared.Properties.proj))' != '' "/>
    <ItemGroup>
    <Reference Include="EntityFramework">
      <HintPath>$(SharedAssemblyPath)\NuGet\EntityFramework.4.3.0\lib\net40\EntityFramework.dll</HintPath>
     </Reference>
    </ItemGroup>
  <Target Name="CheckReferencePaths" BeforeTargets="ResolveAssemblyReferences">
    <Message Importance="high" Text="Doing CheckReferencePaths" />
    <ItemGroup>
     <SharedAssemblyPathItem Include="$(SharedAssemblyPath)" />
    </ItemGroup>
    <Warning Condition="!Exists('@(SharedAssemblyPathItem)')" Text="SharedAssemblyPath not found at '@(SharedAssemblyPathItem)'" />
    <Warning Condition="!Exists('@(SharedAssemblyPathItem)')" Text="SharedAssemblyPath not found at '@(SharedAssemblyPathItem->'%(FullPath)')'" />
    <Message Condition="!Exists('%(Reference.HintPath)')" Text="FullPath=%(Reference.HintPath)" Importance="high" />

    

我在主项目中工作,没有将属性组推送到我导入的卫星文件,但现在想让它可以在可以共享引用的其他项目之间重用。

BeforeTargets目标在新的尝试中显示此信息:

  

CheckReferencePaths:   做CheckReferencePaths   d:\项目\团队\项目\适配器\将对DBAdapter \ dbadapter.csproj(103,5):   警告:''找不到SharedAssemblyPath   d:\项目\团队\项目\适配器\将对DBAdapter \ dbadapter.csproj(104,5):   警告:在''中找不到SharedAssemblyPath   FULLPATH = \的NuGet \ EntityFramework.4.3.0 \ lib中\ net40 \ EntityFramework.dll
  FULLPATH =

如何在评估项目组的提示路径之前,获取导入共享的项目文件以评估导入项目的属性。或者评估顺序是否正确,但我的构造中的其他内容是不正确的?

2 个答案:

答案 0 :(得分:18)

你的问题引导我找到这个有价值的info on MSDN。我在这里发帖是为了保留答案self-contained


评估顺序

当MSBuild到达导入元素时,导入的项目将有效地插入到导入元素位置的导入项目中。因此,导入元素的位置可能会影响属性和项的值。了解导入项目设置的属性和项以及导入项目使用的属性和项非常重要。

项目构建时,首先评估所有属性,然后评估项目。例如,以下XML定义导入的项目文件MyCommon.targets:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
        <Name>MyCommon</Name>
    </PropertyGroup>

    <Target Name="Go">
        <Message Text="Name='$(Name)'"/>
    </Target>
</Project>

以下XML定义MyApp.proj,它导入MyCommon.targets:

<Project
    DefaultTargets="Go"
    xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
        <Name>MyApp</Name>
    </PropertyGroup>
    <Import Project="MyCommon.targets"/>
</Project>

项目构建时,将显示以下消息:

名称= “MyCommon”

因为在MyApp.proj中定义了属性Name之后导入了项目,所以MyCommon.targets中Name的定义将覆盖MyApp.proj中的定义。如果在定义属性Name之前导入项目,则构建将显示以下消息:

名称= “MyApp的”

导入项目时使用以下方法

  1. 在项目文件中定义所有使用的属性和项目 作为导入项目中属性和项目的参数。

  2. 导入项目。

  3. 在项目文件中定义必须的所有属性和项目 覆盖导入的属性和项的默认定义 项目

  4. 实施例

    以下代码示例显示了第二个代码示例导入的MyCommon.targets文件。 .targets文件评估导入项目的属性以配置构建。

    <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
        <PropertyGroup>
            <Flavor Condition="'$(Flavor)'==''">DEBUG</Flavor>
            <Optimize Condition="'$(Flavor)'=='RETAIL'">yes</Optimize>
            <appname>$(MSBuildProjectName)</appname>
        <PropertyGroup>
        <Target Name="Build">
            <Csc Sources="hello.cs"
                Optimize="$(Optimize)"
                OutputAssembly="$(appname).exe"/>
        </Target>
    </Project>
    

    以下代码示例导入MyCommon.targets文件。

    <Project DefaultTargets="Build"
        xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
        <PropertyGroup>
            <Flavor>RETAIL</Flavor>
        </PropertyGroup>
        <Import Project="MyCommon.targets"/>
    </Project>
    

答案 1 :(得分:-1)

尝试使用内联任务而不是shared.properties.proj文件。在this question上查看我的答案。

它是关于搜索某些文件是父目录。您可以对其进行调整以搜索父目录。