Установить "Копировать локальный" в Ложь по умолчанию? - PullRequest
34 голосов
/ 23 июня 2010

Могу ли я установить для параметра по умолчанию «Копировать локальный» в Visual Studio значение False?В большинстве случаев, когда я добавляю dll в качестве зависимости проекта, я хочу, чтобы свойство Copy Local было установлено в False.По умолчанию это правда.Есть ли способ изменить поведение Visual Studio по умолчанию?(2008)

Ответы [ 6 ]

38 голосов
/ 23 июня 2010

Нет - Visual Studio использует внутренний набор правил, чтобы определить, на что установить Copy Local.

С MSDN :

  1. Если ссылка - это другой проект, называемый ссылкой «проект-проект», то значение равно true .
  2. Если сборка найдена в глобальном кэше сборок, значение равно false .
  3. В особом случае значение для ссылки mscorlib.dll равно false .
  4. Если сборка находится в папке Framework SDK, то значение равно false .
  5. В противном случае значение равно true .
27 голосов
/ 31 мая 2012

На самом деле, вы можете. Вам нужна пара вещей:

  1. Создать .targets файл, который делает copylocal (точнее, тег <Private>) false по умолчанию .
  2. Импорт цели в .csproj файлах. Вы можете добавить его в самой последней строке, перед закрытием тега </Project> он будет выглядеть как <Import Project="..\Build\yourtarget.targets" />.

Теперь у каждого проекта с этой целью по умолчанию отключен copylocal.

Недостатком является то, что вам нужно изменить каждый файл csproj, включая новые. Вы можете обойти новую проблему проекта, изменив шаблон проекта VS . Вместо Class.cs, описанного в статье блога, вам нужно изменить Class.vstemplate (в том же zip-файле).

При таком подходе есть еще одна проблема - сам путь. Если вы используете жестко запрограммированный относительный путь во вновь создаваемых файлах csproj, они могут быть неправильными (если у вас нет плоской структуры проекта).

Вы можете:

  • Заставить VS генерировать правильный относительный путь. Не уверен, как это сделать, и если это вообще возможно.
  • Игнорируйте его и изменяйте путь вручную для каждого нового csproj (в зависимости от количества новых проектов, которые у вас есть, хотя это и не идеально, но это может быть допустимо).
  • Используйте переменную среды вместо относительного пути. В этом случае каждому разработчику потребуется один и тот же набор переменных.

Должно быть лучшее решение для этого, но оно еще не найдено.

7 голосов
/ 29 апреля 2014

Мы не используем файлы .targets (как предложено в ответе ya23), поэтому мы просто редактируем файл проекта .csproj вручную в текстовом редакторе и добавляем элемент <Private> в ссылку, например:

<Reference Include="[...]">
  <Private>False</Private>
  [...]
</Reference>

Значение элемента <Private> соответствует значению свойства «Копировать локально».Например, если для <Private> установлено значение «Ложь», то «Копировать локально» также ложно.

4 голосов
/ 08 июня 2018

Начиная с msbuild v 15, вы можете скопировать один файл с именем Directory.Build.props в корневую папку, содержащую ваш источник:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemDefinitionGroup>
  <Reference>
    <Private>False</Private>
  </Reference>
  <ProjectReference>
     <Private>False</Private>
  </ProjectReference>
</ItemDefinitionGroup>
</Project>

Больше ничего не нужно делать!Это хорошо работает с Visual Studio 2017, а также с vNext Build.Возможно, вам придется закрыть Visual Studio, а затем снова открыть свое решение, чтобы применить эффект файла.

https://docs.microsoft.com/en-us/visualstudio/msbuild/customize-your-build#directorybuildprops-and-directorybuildtargets

4 голосов
/ 24 января 2013

Подняв это, потому что кажется, что теперь есть пакет nuget, позволяющий именно это ...

https://nuget.org/packages/CopyLocalFalse

Еще не пробовал, просто надеясь, что это поможет.

1 голос
/ 16 января 2018

Что касается решения, опубликованного @herzbube, если вы хотите отключить «Копировать локально» для всех (или большинства) ссылок в файле .csproj , вам не нужно устанавливать <Private>False</Private> индивидуально на каждом Reference, вы можете просто поместить следующее непосредственно в .csproj :

<ItemDefinitionGroup>
  <Reference>
    <Private>False</Private>
  </Reference>
</ItemDefinitionGroup>

Это не влияет на проекты, на которые ссылается <ProjectReference>, но вы можете сделать то же самое - вместо этого или также для них:

<ItemDefinitionGroup>
  <ProjectReference>
    <Private>False</Private>
  </ProjectReference>
</ItemDefinitionGroup>

Если вы хотите оба из них, вы можете объединить их в одну группу:

<ItemDefinitionGroup>
  <Reference>
    <Private>False</Private>
  </Reference>
  <ProjectReference>
    <Private>False</Private>
  </ProjectReference>
</ItemDefinitionGroup>

Убедитесь, что вы поместили эти переопределения до первого фактического <Reference ...> или <ProjectReference ...>, на который вы хотите повлиять, потому что эти блоки будут применяться только к тем ссылкам, которые появляются под ними. Затем, если есть некоторые из них, которые вы делаете на самом деле хотите скопировать локально, вы можете просто переопределить эти back индивидуально (т.е. внутри самого отдельного тега ), на этот раз используя True.

Для более сложных случаев вы можете переключать значение переопределения вперед и назад между True и False несколько раз в одном и том же файле .csproj. Другим продвинутым методом было бы стратегически разместить некоторые из ваших ссылок под этими блоками, а другие выше, чтобы на них не влияли.

Все это должно сделать XML в вашем .csproj намного чище и легче для чтения. Но есть и другие хорошие новости, так что читайте дальше ...


Что касается выбора, какие проекты должны быть отмечены <Private>False</Private>, это обычно зависит от конкретной ситуации, но есть что-то фундаментальное каждый может и должен сделать для начинающих. Это настолько простой, простой и эффективный шаг, который обеспечивает такие огромные MSBuild улучшения надежности 1. и ускорение во время сборки - и с небольшими недостатками - что каждое крупное решение, которое использует по умолчанию (т. е. локальный для проекта) C # выходные местоположения почти всегда должны делать эту настройку:

В любом решении Visual Studio, которое создает несколько библиотек классов C # с любым нетривиальным числом <ProjectReference> взаимозависимостей и которое завершается созданием еще одного приложений (т.е. исполняемые файлы):

  1. В верхней части .csproj для каждой библиотеки классов , вставьте блок <ProjectReference>, показанный выше.
    ПРИЧИНА: Нет необходимости для .dll собирать какие-либо библиотеки, на которые он ссылается, в свой собственный подкаталог, поскольку из этого расположения никогда не запускается ни один исполняемый файл. Такое безудержное копирование является бесполезной занятой работой и может излишне замедлять вашу сборку, возможно, весьма радикально.

  2. С другой стороны, не измените .csproj для любого из приложений вашего решения .
    ПРИЧИНА: Исполняемые файлы должны иметь все необходимые частные библиотеки в своих соответствующих подкаталогах, но сборка для каждого отдельного приложения должна отвечать за индивидуальный сбор каждой зависимости непосредственно из соответствующего подкаталога в подкаталог приложения. каталог.

Это прекрасно работает, потому что .csproj для библиотеки классов может ссылаться на несколько других библиотек классов, но .csproj для исполняемого файла обычно никогда не ссылается на другой исполняемый файл. Таким образом, для каждой локальной библиотеки только .dll в ее папке bin будет сам по себе, тогда как каждое локально созданное приложение будет содержать полный набор локально собранных библиотек, на которые оно ссылается.

Удобно, что ничего не меняется для ссылочных библиотек, которые не созданы вашим решением, так как они обычно используют <Reference> вместо <ProjectReference>, и мы вообще не изменяли прежний тег. Но обратите внимание на только что упомянутое предположение; если он нарушается некоторыми вашими проектами, возможно, вам придется внести некоторые коррективы.

[1.] Повышение надежности может быть связано с коллизиями файлов, которые могут возникать при сборе одной и той же библиотеки из нескольких непересекающихся путей в графе зависимостей, особенно в параллельных сборках.

...