【问题标题】:BuildingInsideVisualStudio Property Value Not Working With File Reference and Project Reference ConditionalBuildingInsideVisualStudio 属性值不适用于文件参考和项目参考条件
【发布时间】:2012-05-24 13:16:00
【问题描述】:

我正在尝试使用 BuildingInVsideisualStudio 属性在 csproj 中添加对同一 dll 的项目和文件引用。但是当它们一起在 csproj 中时,只会拾取文件引用。如果我删除文件引用,它会拾取 csproj。我曾尝试交换订单,但没有运气。任何想法为什么这不起作用?

基本思路如下:

<ItemGroup Condition="'$(BuildingInsideVisualStudio)' == false">
    <Reference Include="MyNamespace.Mine">
        <HintPath>..\$(OutDir)\MyNamespace.Mine.dll</HintPath>
    </Reference>
</ItemGroup>
<ItemGroup Condition="'$(BuildingInsideVisualStudio)' == '' Or '$(BuildingInsideVisualStudio)' == true">
    <ProjectReference Include="..\MyNamespace.Mine.csproj">
        <Project>{GUID}</Project>
        <Name>MyNamespace.Mine</Name>
    </ProjectReference>
</ItemGroup>

Someone else 也走上了这条路,但似乎有some caveats。由于我的构建过程无法更改,因此我需要有条件地执行此操作。使用文件引用会迫使我失去 Go to Definition 和 Find All References(抱歉,我也无法安装 ReSharper 来解决这个问题)。

【问题讨论】:

    标签: visual-studio msbuild csproj


    【解决方案1】:

    我看到了两个问题:

    1. 您没有考虑到$(BuildingInsideVisualStudio) 可以为空 ('')。对于第一个条件使用:

      &lt;ItemGroup Condition="'$(BuildingInsideVisualStudio)' != 'true'"&gt;

    2. 始终用单引号将两个操作数括起来:

      &lt;ItemGroup Condition="'$(BuildingInsideVisualStudio)' == 'true'"&gt;


    MSDN reference:

    简单的字母数字字符串或单引号不需要 布尔值。 但是,空值需要单引号。


    更新:

    可能有点远,但您可以尝试在属性定义上使用条件:

    <PropertyGroup Condition="'$(BuildingInsideVisualStudio)' != 'true'"><!-- In CMD -->
        <ReferenceInclude>MyNamespace.Mine"</ReferenceInclude>
        <ReferenceIncludePath>..\$(OutDir)\MyNamespace.Mine.dll</ReferenceIncludePath>
    </PropertyGroup>
    <PropertyGroup Condition="'$(BuildingInsideVisualStudio)' == 'true'"><!-- In VS -->
        <ProjectReferenceInclude>..\MyNamespace.Mine.csproj</ProjectReferenceInclude>
        <ProjectReferenceIncludeId>{GUID}</ProjectReferenceIncludeId>
    </PropertyGroup> 
    

    所以引用将有条件地解决:

    <ItemGroup>
        <Reference Include="$(ReferenceInclude)">
            <HintPath>$(ReferenceIncludePath)</HintPath>
        </Reference>
    </ItemGroup>
    <ItemGroup>
        <ProjectReference Include="$(ProjectReferenceInclude)">
            <Project>$(ProjectReferenceIncludeId)</Project>
            <Name>%(ProjectReferenceInclude.MSBuildProjectName)</Name>
        </ProjectReference>
    </ItemGroup>
    

    【讨论】:

    • 我根据您的建议更新了我的 csproj,但不幸的是我得到了相同的结果
    • 不幸的是,我得到了同样的结果。
    【解决方案2】:

    在 Visual Studio 2010 和 2012 中,您还可以使用选择语句而不是添加带有条件的引用。这似乎效果更好:

    <Choose>
      <When Condition="('$(VisualStudioVersion)' == '10.0' or '$(VisualStudioVersion)' == '') and '$(TargetFrameworkVersion)' == 'v3.5'">
        <ItemGroup>
          <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
        </ItemGroup>
      </When>
      <Otherwise>
        <ItemGroup>
          <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework" />
        </ItemGroup>
      </Otherwise>
    </Choose>
    

    【讨论】:

    • 添加差异引用不是问题。添加项目引用或 dll 引用是问题所在,但我会尝试一下。
    • 我们现在在内部使用它,对我们来说它工作得很好。我们使用 $(BuildingInsideVisualStudio)$(TeamBuildConstants) 变量来指导基于我们是在 Visual Studio、Team Build 还是“其他”(命令行或其他任何东西)中构建的事实
    • 你试过了吗?因为它实际上只会列出您的参考资料一次。
    • 是的,它确实有效,但我家里只有 Visual Studio 2012。不幸的是,我后来意识到我们的构建系统是“疯狂的”并且实际上失败了,因为它重写了 csproj。在此过程中,它会删除选择、何时以及其他方式;因此,无论如何,我都留下了 2 份参考资料。但是您的解决方案确实有效(至少在 2012 年)。
    • 我认为这是唯一适用于 Visual Studio Online 的解决方案。谢谢!
    【解决方案3】:

    假设我在经过一些实验后正确理解了这个问题,似乎以不同的方式命名它们可以解决大部分问题; msbuild 会尊重条件并使用程序集引用,VS 会在解决方案资源管理器中显示它们,但会像项目类型一样预构建引用,并且会在没有 R# 工作的情况下保持 goto-definition。条件导入是其他值得研究的东西,但我还没有尝试过。

    <ItemGroup>
        <ProjectReference Include="..\ClassLibrary1\ClassLibrary1.csproj" Condition="'$(Foo)'=='Bar1'">
            <Project>{FD0E01BC-7777-4620-9EF2-5F60804B3173}</Project>
            <Name>ClassLibrary1-ProjRef</Name>
        </ProjectReference>
        <Reference Include="ClassLibrary1" Condition="'$(Foo)'=='Bar2'">
            <Name>ClassLibrary1-AssRef</Name>
            <HintPath>..\ClassLibrary1\bin\Debug\ClassLibrary1.dll</HintPath>
        </Reference>
    </ItemGroup>
    

    【讨论】:

    • 那行得通。 dll 仍然出现,这有点糟糕,但好处似乎超过了这一点。
    【解决方案4】:

    Microsoft 在 Connect 上对 this 问题的回复表明,Visual Studio 故意忽略程序集引用上的条件,无论是否是项目。这是可以理解的;但是,当项目文件包含对同一程序集的多个引用时,解析过程似乎总是更喜欢基于文件的引用,这是没有实际意义的。

    简而言之,你很不走运,除非有办法告诉 VS 考虑项目引用,即使文件引用存在于同一个程序集中。我不知道有什么方法可以做到这一点,我也有兴趣了解它是否仍然可行。

    【讨论】:

    • 虽然我仍然认为这是 VS/MSBuild 中的一个错误,但我能够通过更改项目名称来解决它。我不认为我可以分配赏金。
    猜你喜欢
    • 1970-01-01
    • 2011-01-24
    • 1970-01-01
    • 1970-01-01
    • 2011-09-12
    • 1970-01-01
    • 2021-04-12
    • 1970-01-01
    • 2011-10-23
    相关资源
    最近更新 更多