Ссылка на DLL, не скопированную для ссылки на проект

Этот вопрос может быть задан несколько раз, и, возможно, я просто плохо использую функции поиска здесь, а также Google, но пока не нашел ответа на этот вопрос.

В настоящее время у меня есть два проекта: проект X, проект Y и проект Z (который содержит только сопоставления)

Проект X - это проект FluentNhibernate, в котором хранятся мои сессии и подобные вещи. Таким образом, это также то место, где загружаются сопоставления и вещи (это важно, и я подозреваю, что это может быть причиной моей проблемы)

Теперь в Project X я ссылаюсь на сборку, которая использует Microsoft.SqlServer.Types.dll.

Проект Y - это служба, которая использует проект X для соединений с базой данных.

Все сборки объектов находят и работают отлично на моей машине разработки, однако при развертывании на нашем сервере они не работали (ошибки времени выполнения). Ошибка была довольно неясной, поскольку она указывала на отсутствующую сборку FluentNHibernate, которая не была в этом случае.

Procmon.exe, к счастью, показал код, пытающийся загрузить файл Microsoft.SqlServer.Types.dll, который с сервера не имеет установленного SQL Server (мой клиент тоже не имеет, но у него есть студия управления, которая, скорее всего, устанавливает это. DLL).

До сих пор так хорошо, скопировал DLL и работал (yay!).

Теперь я понял, что добавлю сборку в проект X, чтобы убедиться, что эта ссылка скопирована на другие проекты с использованием проекта X. Этого не произошло.... Поэтому я попытался установить настройку "Копировать локальную" к true.

К сожалению, это еще не копирует .dll в проект ссылки Y.

Есть ли способ сделать это, или эта Visual Studio очень умна, и реализовать проект Y не нужен этот .dll и, таким образом, отказаться от его копирования?

(Поскольку Project Z нуждается в фактической ссылке, а Project X загружает эту сборку @время выполнения, нет "жесткой" ссылки между Z и X)

Может ли любой гений Stackoverflow пролить свет на это, так как честно я хотел бы знать, почему он ведет себя таким образом (и в идеале это способ заставить его вести себя так, как я этого хочу).

Ответ 1

Теперь я понял, что добавлю сборку в проект X, чтобы убедиться, что эта ссылка скопирована на другие проекты с использованием проекта X. Этого не произошло.... Поэтому я попытался установить настройку "Копировать локальную" к true.

Вы все еще говорите о Microsoft.SqlServer.Types.dll правильно?

У меня были те же проблемы некоторое время назад, на самом деле типы sqlserver не должны копироваться и перераспределяться с вашей установкой. Правильный способ "установить" это загрузка среды выполнения sql-сервера (которая включена в инструменты управления сервером sql, поэтому она работает для вас локально).

Поскольку это было какое-то время назад, я не уверен на 100%, если следующая информация верна и будет работать, но просто попробуйте установить Только для типов Microsoft® System CLR для Microsoft® SQL Server® 2012. На этой странице загрузки разверните "Инструкции по установке" и прокрутите вниз до загрузки типов CLR...

Используйте эту ссылку для SQL Server 2008

Установите это на целевом сервере. Это позволит установить только те вещи, которые необходимы для запуска DLL этих типов...

Ответ 2

На этот вопрос уже был дан ответ, но я подумал, что включу общий отказобезопасный метод для копирования всех косвенных ссылок в выходные каталоги проектов.

  • Установите Скопировать локальную в true для всех ссылок, которые вы хотите включить в свой вывод.
  • Сохраните код косвенных зависимостей копирования (см. ниже) в файл с именем CopyIndirectDependencies.targets и поместите файл целей в каталог проекта.
  • Отредактируйте .csproj или .vbproj, чтобы включить импорт в файл .targets, который вы добавили. См. Пример ниже.
  • Создайте свой проект, и вы должны иметь вторичные зависимости, автоматически скопированные на вывод сборки.

Содержимое CopyIndirectDependencies.targets.

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <CopyIndirectDependencies   
      Condition="'$(CopyIndirectDependencies)'==''">true</CopyIndirectDependencies>
    <CopyIndirectDependenciesPdb
      Condition="'$(CopyIndirectDependenciesPdb)'==''">false</CopyIndirectDependenciesPdb>
    <CopyIndirectDependenciesXml
      Condition="'$(CopyIndirectDependenciesXml)'==''">false</CopyIndirectDependenciesXml>
  </PropertyGroup>


  <!-- BuildXxx part -->

  <Target Name="CopyIndirectDependencies"
          Condition="'$(CopyIndirectDependencies)'=='true'"
          DependsOnTargets="DetectIndirectDependencies">
    <Copy Condition="'%(IndirectDependency.FullPath)'!=''"
          SourceFiles="%(IndirectDependency.FullPath)"
          DestinationFolder="$(OutputPath)"
          SkipUnchangedFiles="true" >
      <Output TaskParameter="CopiedFiles"
              ItemName="IndirectDependencyCopied" />
    </Copy>
    <Message Importance="low"
             Condition="'%(IndirectDependencyCopied.FullPath)'!=''
               and '%(IndirectDependencyCopied.Extension)'!='.pdb'
               and '%(IndirectDependencyCopied.Extension)'!='.xml'"
             Text="Indirect dependency copied: %(IndirectDependencyCopied.FullPath)" />
  </Target>

  <Target Name="DetectIndirectDependencies"
          DependsOnTargets="ResolveAssemblyReferences">

    <Message Importance="low"
             Text="Direct dependency: %(ReferencePath.Filename)%(ReferencePath.Extension)" />
    <Message Importance="low"
             Text="Indirect dependency: %(ReferenceDependencyPaths.Filename)%(ReferenceDependencyPaths.Extension)" />

    <!-- Creating indirect dependency list -->
    <CreateItem Include="%(ReferenceDependencyPaths.FullPath)"
                Condition="'%(ReferenceDependencyPaths.CopyLocal)'=='true'">
      <Output TaskParameter="Include"
              ItemName="_IndirectDependency"/>
    </CreateItem>
    <CreateItem Include="%(ReferenceDependencyPaths.RootDir)%(ReferenceDependencyPaths.Directory)%(ReferenceDependencyPaths.Filename).xml"
                Condition="'%(ReferenceDependencyPaths.CopyLocal)'=='true' and '$(CopyIndirectDependenciesXml)'=='true'">
      <Output TaskParameter="Include"
              ItemName="_IndirectDependency"/>
    </CreateItem>
    <CreateItem Include="%(ReferenceDependencyPaths.RootDir)%(ReferenceDependencyPaths.Directory)%(ReferenceDependencyPaths.Filename).pdb"
                Condition="'%(ReferenceDependencyPaths.CopyLocal)'=='true' and '$(CopyIndirectDependenciesPdb)'=='true'">
      <Output TaskParameter="Include"
              ItemName="_IndirectDependency"/>
    </CreateItem>

    <!-- Filtering indirect dependency list by existence -->
    <CreateItem Include="%(_IndirectDependency.FullPath)"
                Condition="Exists('%(_IndirectDependency.FullPath)')">
      <Output TaskParameter="Include"
              ItemName="IndirectDependency"/>
    </CreateItem>

    <!-- Creating copied indirect dependency list -->
    <CreateItem Include="@(_IndirectDependency->'$(OutputPath)%(Filename)%(Extension)')">
      <Output TaskParameter="Include"
              ItemName="_ExistingIndirectDependency"/>
    </CreateItem>

    <!-- Filtering copied indirect dependency list by existence -->
    <CreateItem Include="%(_ExistingIndirectDependency.FullPath)"
                Condition="Exists('%(_ExistingIndirectDependency.FullPath)')">
      <Output TaskParameter="Include"
              ItemName="ExistingIndirectDependency"/>
    </CreateItem>

  </Target>


  <!-- Build sequence modification -->

  <PropertyGroup>
    <CoreBuildDependsOn>
      $(CoreBuildDependsOn);
      CopyIndirectDependencies
    </CoreBuildDependsOn>
  </PropertyGroup>
</Project>

Пример проекта с импортом

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  ...

  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <Import Project="CopyIndirectDependencies.targets" /> <!-- ADD THIS LINE!! -->

  ...

</Project>

Источник: http://blog.alexyakunin.com/2009/09/making-msbuild-visual-studio-to.html