5

我正在尝试使用 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>

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

4

4 回答 4

7

我看到的两个问题:

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

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

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

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


MSDN 参考:

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


更新:

可能是一个很长的镜头,但您可以尝试在属性定义上使用条件:

<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>
于 2012-05-28T22:26:54.117 回答
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>
于 2012-08-23T12:02:20.810 回答
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>
于 2012-06-06T01:24:30.943 回答
0

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

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

于 2012-06-03T14:38:32.570 回答