Значение свойства BuildingInsideVisualStudio не работает со ссылкой на файл и условной ссылкой на проект

Я пытаюсь добавить ссылку на проект и файл в ту же dll в csproj со свойством BuildingInVsideisualStudio. Но когда они вместе в 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>

Кто-то еще тоже пошел по этому пути, но он появляется там есть некоторые предостережения. Мне нужно сделать это условие из-за моего процесса сборки, который не может измениться. Использование ссылки на файл приводит к тому, что я теряю команды «Перейти к определению» и «Найти все ссылки» (извините, но я также не могу установить ReSharper, чтобы решить эту проблему).


person kevindaub    schedule 24.05.2012    source источник


Ответы (4)


Предполагая, что я правильно понял вопрос после небольшого эксперимента, кажется, что если назвать их по-разному, это решит большинство проблем; msbuild будет соблюдать условие и использовать ссылку на сборку, VS отобразит их оба в обозревателе решений, но предварительно создаст ссылку, как если бы она была видом проекта, и сохранит определение перехода без работы R #. Условный импорт - это еще что-то, на что стоит обратить внимание, но я не пробовал.

<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>
person Ilya Kozhevnikov    schedule 06.06.2012
comment
Это сработало. Немного отстойно, что dll все еще появляется, но преимущества, кажется, перевешивают это. - person kevindaub; 06.06.2012

Я вижу две проблемы:

  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>
person KMoraz    schedule 28.05.2012
comment
Я обновил свой csproj с вашими рекомендациями, но, к сожалению, я получаю тот же результат. - person kevindaub; 29.05.2012
comment
К сожалению, я получил тот же результат. - person kevindaub; 06.06.2012

В 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>
person jessehouwing    schedule 23.08.2012
comment
Добавление ссылок на различия не является проблемой. Добавление ссылки на проект или ссылку на dll является проблемой, но я попробую. - person kevindaub; 24.08.2012
comment
Сейчас мы используем его внутри, и для нас он работает просто отлично. Мы используем переменные $(BuildingInsideVisualStudio) и $(TeamBuildConstants) для управления в зависимости от того, строим ли мы в Visual Studio, Team Build или «иначе» (командная строка или что-то еще). - person jessehouwing; 02.10.2012
comment
Вы пробовали? Потому что он фактически перечислит вашу ссылку только один раз. - person jessehouwing; 14.12.2012
comment
Да, это сработало, но у меня дома только Visual Studio 2012. К сожалению, позже я понял, что наша система сборки безумна и на самом деле дает сбой, потому что перезаписывает csproj. Во время этого процесса он удаляет выбор, когда и в противном случае; таким образом, у меня осталось 2 ссылки, несмотря ни на что. Но ваше решение сработало (по крайней мере, в 2012 году). - person kevindaub; 15.12.2012
comment
Думаю, это единственное решение, которое работает с Visual Studio Online. Спасибо! - person Kerem Demirer; 09.11.2016

Ответ, опубликованный Microsoft на этот вопрос on Connect указывает, что Visual Studio намеренно игнорирует условия для ссылок на сборки, независимо от того, проект это или нет. Это понятно; однако процесс разрешения всегда предпочитает ссылки на файлы, когда файл проекта содержит более одной ссылки на одну и ту же сборку, что является спорным.

Короче говоря, вам не повезло, если только нет способа сообщить VS, чтобы он рассматривал ссылку на проект, даже если ссылка на файл присутствует в той же сборке. Я не знаю, как это сделать, и мне также было бы интересно узнать, возможно ли это как-то еще.

person Alan    schedule 03.06.2012
comment
Хотя я все еще считаю, что это ошибка в VS/MSBuild, мне удалось обойти ее, изменив имя проекта. Я не думаю, что смогу разделить награду. - person kevindaub; 06.06.2012