我正在尝试使用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来解决这个问题)。
答案 0 :(得分:6)
我看到两个问题:
您没有考虑$(BuildingInsideVisualStudio)
可以为空(''
)。对于第一个使用条件:
<ItemGroup Condition="'$(BuildingInsideVisualStudio)' != 'true'">
始终用单引号括住两个操作数:
<ItemGroup Condition="'$(BuildingInsideVisualStudio)' == 'true'">
简单的字母数字字符串或单字母不需要单引号 布尔值。 但是,空值需要单引号。
更新:
可能是一个长镜头,但您可以尝试使用属性定义的条件:
<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考虑项目参考,即使文件引用存在于同一个程序集中。我不知道如何做到这一点,我也有兴趣了解它是否仍然可能以某种方式。