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

Mas*_*low 12 msbuild-propertygroup msbuild-4.0

我有一个共享的属性文件 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>
Run Code Online (Sandbox Code Playgroud)

我正在搜索任何级别的父目录包含名为的目录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" />
Run Code Online (Sandbox Code Playgroud)

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

BeforeTargets目标显示了这个在不工作的新尝试:

CheckReferencePaths:执行CheckReferencePaths D:\ projects\Team\Project\Adapters\DbAdapter\dbadapter.csproj(103,5):警告:在'D:\ projects\Team\Project\Adapters\DbAdapter\dbadapter.csproj中找不到SharedAssemblyPath (104,5):警告:在''
FullPath =\NuGet\EntityFramework.4.3.0\lib \net40\EntityFramework.dll
FullPath =找不到SharedAssemblyPath

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

KMo*_*raz 18

您的问题让我MSDN找到这些有价值的信息.我在这里张贴它是为了保持答案自成一体.


评估顺序

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

项目构建时,首先评估所有属性,然后评估项目.例如,以下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>
Run Code Online (Sandbox Code Playgroud)

以下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>
Run Code Online (Sandbox Code Playgroud)

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

NAME = "MyCommon"

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

NAME = "MyApp的"

导入项目时使用以下方法

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

  2. 导入项目.

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

以下代码示例显示第二个代码示例导入的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>
Run Code Online (Sandbox Code Playgroud)

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

<Project DefaultTargets="Build"
    xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
        <Flavor>RETAIL</Flavor>
    </PropertyGroup>
    <Import Project="MyCommon.targets"/>
</Project>
Run Code Online (Sandbox Code Playgroud)