BuildingInsideVisualStudio属性值不使用文件引用和项目引用条件

时间:2012-05-24 13:16:01

标签: visual-studio msbuild csproj

我正在尝试使用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来解决这个问题)。

4 个答案:

答案 0 :(得分:6)

我看到两个问题:

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

    <ItemGroup Condition="'$(BuildingInsideVisualStudio)' != 'true'">

  2. 始终用单引号括住两个操作数:

    <ItemGroup Condition="'$(BuildingInsideVisualStudio)' == 'true'">


  3. 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>
    

答案 1 :(得分:2)

在Visual Studio 2010和2012中,您还可以使用Choose语句,而不是添加带条件的引用。这看起来好多了:

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

答案 2 :(得分:1)

假设我在经过一些实验后正确地理解了这个问题,似乎以不同方式命名它们可以解决大多数问题; 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>

答案 3 :(得分:0)

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

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