【问题标题】:When you import another msbuild file, what is the order of evaluation?当您导入另一个 msbuild 文件时,评估顺序是什么?
【发布时间】:2016-02-18 07:24:48
【问题描述】:

我有一个共享属性文件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 D:\projects\Team\Project\Adapters\DbAdapter\dbadapter.csproj(103,5): 警告:在 '' 处找不到 SharedAssemblyPath D:\projects\Team\Project\Adapters\DbAdapter\dbadapter.csproj(104,5): 警告:在 ''
中找不到 SharedAssemblyPath FullPath=\NuGet\EntityFramework.4.3.0\lib\net40\EntityFramework.dll
全路径=

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

【问题讨论】:

    标签: msbuild-4.0 msbuild-propertygroup


    【解决方案1】:

    你的问题让我找到了这个有价值的info on MSDN。我把它贴在这里是为了保留答案self-contained


    评估顺序

    当 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>
    

    以下 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>
    

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

    Name="MyCommon"

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

    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>
    

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

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

    【讨论】:

    • 在最后一个例子中,你的意思是在属性组定义之前导入?
    • @Adam 不,因为Flavor 有一个条件&lt;Flavor Condition="'$(Flavor)'==''"&gt;,这意味着它将采用第一个定义的值(在这种情况下为零售)
    【解决方案2】:

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

    它是关于搜索一些文件是父目录。您可以调整它以搜索父目录。

    【讨论】:

    • 很确定内联任务不适用于 itemgroup 提示路径,以便 Visual Studio 正确搜索设计时解决方案资源管理器。
    猜你喜欢
    • 2015-11-02
    • 1970-01-01
    • 2023-03-03
    • 2010-09-18
    • 2016-11-24
    • 1970-01-01
    • 2021-02-14
    • 1970-01-01
    相关资源
    最近更新 更多