Подтвердить что ты не робот

Visual Studio перестраивает немодифицированные проекты

Итак, по мере того как заголовок читает, у меня есть VS2010-решение с ~ 50 проектами в нем прямо сейчас. Если я внес изменения в проект "верхнего уровня", который ничего не ссылается, VS все еще перестраивает все 50 проектов. Я запускаю Visual Studio 2010 Ultimate без каких-либо надстроек. Я использую ILMerge для объединения всех проектов в один файл.

Я проверил это, проверив отметки времени DLL нижнего уровня и убедившись, что они действительно восстановлены, хотя их код не был затронут.

Я прочитал все ответы и комментарии для:

Visual Studio 2008 продолжает перестраивать

Visual studio продолжает строить все

В моем решении произошел сбой Strong VS2010

Причины для проектов С# для перестройки в Visual Studio

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

Я включил "Инструменты" > "Параметры" > "Проекты и решения" > "Сборка и запуск" > Создавать только проекты запуска и зависимости от запуска ", но без эффекта.

Кроме того, если я просто перестрою проект "среднего уровня", который имеет только 8 (в) прямых зависимостей, то он все еще строит все 8 проектов, хотя ILMerge не вызывается и ни один из зависимых проектов не был изменен.

Спасибо всем за понимание, которое вы можете предоставить.

Добавлен

Чтобы проверить некоторые предложения, я создал новый проект WinForms с нуля. Затем я создал два новых проекта внутри этого решения. Я скопировал весь код и ресурсы (не файл проекта) из моих двух проектов "самого низкого уровня" в два новых проекта (я сделал это, отбросив файлы и папки из Проводника в проект в Visual Studio).

Самый низкий проект, позвонив ему B, не ссылался ни на какой другой проект. Следующий проект, A, ссылается только на B. Поэтому, как только я добавлю необходимые ссылки на .NET и внешние сборки для проектов, тогда будет построено решение.

Затем у меня была моя новая ссылка на проект WinForm A и была выполнена полная сборка. Таким образом, цепочка ref:

WinForm A B

Затем я модифицировал WinForm и сделал стандартную сборку (F6). Как и раньше, Visual Studio перестроила все три проекта.

После некоторого систематического изложения исходных файлов в проекте B я обнаружил, что если бы я удалил мои Resources.Designer.cs и Resources.resx (и закомментировал код, в котором использовался объект .Properties.Resources эти ресурсы), то модификация WinForm больше не будет перестраивать все решение и будет только перестроить WinForm.

Добавление Resources.resx и Resources.Designer.cs назад к проекту B (но оставив ссылочный код закомментированным, чтобы ничто не использовало ресурсы) переведет полное поведение сборки.

Чтобы узнать, были ли повреждены мои файлы ресурсов, я удалил их еще раз, а затем создал новый (через Project Properties → Resources) и повторно добавил тот же ресурс, что и раньше, который был единственным файлом Excel. С помощью этой установки все еще будет выполнено полное восстановление.

Затем я удалил единственный ресурс, но оставил файл ресурсов в проекте B. Даже если ресурсы не добавлены, но файл ресурсов все еще находится в проекте, произойдет полная (ненужная) перестройка.

Похоже, что просто наличие файла ресурсов, добавленного в проект (.NET 3.5), приведет к тому, что Visual Studio 2010 всегда будет перестраивать этот проект. Является ли это ошибкой или предполагаемым/ожидаемым поведением?

Спасибо всем!

4b9b3361

Ответ 1

Хотя я не думаю, что это исправление, это обходное решение, которое сработало для моей ситуации...

У меня первоначально было около 5 проектов из 50, содержащих раздел Resources. Эти проекты всегда будут перестроены, и, следовательно, все, от чего они зависят, также будет перестроено. Один из этих 5 проектов был "базовой" библиотекой уровня, на которую ссылались 48 других проектов, поэтому 96% моего проекта будут перестраиваться каждый раз, даже если это ему не нужно.

Мое обходное решение заключалось в использовании инъекций зависимостей, интерфейсов и выделенного проекта "Ресурсы" . Вместо того, чтобы эти 5 проектов ссылались на свой собственный объект Resources, я создал интерфейс в каждом проекте, который обеспечивал бы нужные ресурсы. Затем классы, которым нужны эти ресурсы, потребовали бы, чтобы интерфейс был передан во время их создания в конструкторе (вставка конструктора).

Затем я создал отдельный проект "Ресурсы" , в котором был фактический раздел "Ресурсы" , как обычно. Этот проект содержит только ресурсы и класс для каждого интерфейса, который необходим для предоставления этих ресурсов через интерфейс. Этот проект будет ссылаться на все другие проекты, которые имеют зависимость от ресурсов и реализуют интерфейс, необходимый для проекта.

Наконец, в моем проекте "Верхний уровень", в котором ничего не упоминалось (и где exe фактически был построен, и мой корень состава живет), я ссылался на проект "Ресурсы" , подключил DI, и мы ушли.

Это означает, что каждый раз будут восстановлены только два проекта ( "Ресурсы" и "Верхний уровень" ), и если я сделаю частичную сборку (Shift-F6), они не будут полностью восстановлены.

Опять же, не большая работа вокруг, но с 48 проектами, которые строятся каждый раз, когда сборка займет около 3 минут, я теряю 30-90 минут в день с ненужными перестройками. Некоторое время потребовалось рефакторинг, но я думаю, что это была хорошая инвестиция.

Вот упрощенная диаграмма. Обратите внимание, что зависимости от Main.exe до Proj1 и Proj2 не показаны для уменьшения помех.

Diagram of solution

В этом дизайне я могу сделать сборку Proj1 или Proj2 без запуска полной перестройки, так как у них нет зависимостей в разделе Resources. Только Main знает о реализации Resources.

Ответ 2

Откройте "Инструменты" - "Параметры", выберите "Проекты и решения" - "Построить и запустить" в дереве, а затем установите "Детализация вывода сборки проекта MSBuild" на "Диагностика". Это выведет причину построения проекта, т.е.

Проект 'ReferencedProject' не обновлен. Элемент проекта "c:\some.xml" имеет атрибут "Копировать в выходной каталог", установленный на "Всегда копировать".

или же

Проект "MyProject" не обновлен. Входной файл "c:\ReferencedProject.dll" изменяется после выходного файла "c:\MyProject.pdb".

В этом случае исправление заключается в копировании файла some.xml, только если он более новый.

События до и после сборки также могут запускать сборку.

Ответ 3

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

Просто просмотрите все файлы в проекте и найдите тот, у которого нет стрелки для расширения рядом с ним.

Ответ 4

У меня была такая же проблема в VS 2015.

Что для меня было трюком:

  • Один проект ссылался на собственную копию в каком-то другом билете проекта (магия, да). Этот тип материала можно найти при переключении на вывод диагностической сборки (в вариантах построения), а затем попытаться построить проекты один за другим из иерархии проектов - если вы видите проект, который перестраивается, даже если ничего не было изменено, ссылки.
  • Я изменил все файлы "копировать всегда" во всех проектах, чтобы "копировать, если новый". В принципе, во всех файлах .csproj замените <CopyToOutputDirectory>Always</CopyToOutputDirectory> на <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
  • Затем я отключил туннелирование NTFS, как описано в этой статье с этой powershell script:

New-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" -Name "MaximumTunnelEntries" -Value 0 -PropertyType "DWord"

После этого мне нужно было перестроить и, похоже, сейчас работает.

Ответ 5

В моем случае виновником был параметр "Копировать локальный" ссылочной dll, установленный в true, и "Copy to Output Directory", устанавливающий файл, всегда установленный для копирования.

Ответ 7

Наконец-то я нашел еще одного преступника, которого мне было трудно найти, увеличив степень детализации журнала сборки.

В некоторых случаях MSBuild ищет vc120.pdb в выходной папке, и если этот файл не существует, он перестраивает весь проект. Это происходит, даже если вы отключили генерацию символов отладки.

Обходной путь здесь состоит в том, чтобы включить символы отладки и позволить этому файлу генерироваться, затем отключить настройку снова, не удаляя файл PDB.

Ответ 8

У меня была такая же проблема, и она оказалась связана с парой проектов, которые имели локальную ссылку на копию в dll в своем собственном каталоге вывода.

Ключом к обнаружению этого было наличие диагностического вывода, установленного для вывода сборки, а также знание того, что искать в журнале. Поиск: " не в курсе " был ключом.

Ответ 9

Вот ответ от VS2010 всегда перестраивает решение?

Эта проблема решается путем изменения файлов проекта, решения для очистки, удаляя все папки с папками вручную, перезапуская Visual Studio и перестраивая все.

Ответ 10

Основываясь на ваших наблюдениях, похоже, что у вас есть проекты, выражающие зависимости к другим проектам таким образом, что это не очевидно. Возможно, что сиротные зависимости остаются в файлах проекта, не проявляясь в пользовательском интерфейсе. Просмотрели ли вы файл проекта с ошибкой после его открытия в текстовом редакторе? Проверяемые зависимости сборки решения?

Если вы ничего не заметили, попробуйте воссоздать один из ваших проектов с нуля, чтобы узнать, показывает ли новый проект ту же проблему. Если чистый проект строит правильно, вы будете знать, что у вас есть нежелательные зависимости, выраженные где-то. Насколько мне известно, они должны быть в файле проекта или файле решения, если у вас нет файлов makefile или других необычных шагов сборки.

Ответ 11

У меня были те же проблемы с тобой. Я обнаружил, что это произошло из некоторых удаленных файлов. Когда я удалил файлы из моего проекта, проблемы исчезли. С наилучшими пожеланиями.

Ответ 12

Для этой категории проблем с настройкой задания вывода MSBuild для "диагностики" действительно является необходимым первым шагом. В большинстве случаев заявленная причина для повторных построений будет достаточной для того, чтобы действовать, НО иногда MSBuild ошибочно утверждает, что некоторые файлы модифицированы и их необходимо скопировать.

Если это так, вам нужно либо отключить туннелирование NTFS, либо дублировать вашу выходную папку на новое место. Вот несколько слов.

Ответ 13

Другая проблема, которая часто возникает, - это когда какой-то элемент в вашем решении имеет модифицированную марку, которая в будущем. Это может произойти, если вы установите часы вперед, а затем установите часы на правильное время. Это произошло во время установки Linux.

В этом случае вы можете рекурсивно коснуться всех файлов с помощью git bash (да, в Windows):

find . -exec touch {} \;

Ответ 14

У меня возникла проблема с перестройкой проектов Visual Studio при обновлении с Visual Studio 2015 до 2017 года, и я добавляю этот ответ для тех, кто может столкнуться с подобными проблемами, поскольку, похоже, он нигде не документирован.

В моем случае проблема заключалась в том, что все проекты в решении имели один и тот же промежуточный выходной путь (obj). Файл GeneratedInternalTypeHelper.cs генерируется всеми проектами, содержащими XAML. Вплоть до Visual Studio 2015 процесс сборки, по-видимому, не проверял дату файла для этого файла и, следовательно, никаких проблем с ним не возникало. В VS2017 проверяется дата файла этого файла, и поскольку более поздний проект в процессе сборки перезапишет его (с тем же содержимым), более ранний проект будет перестроен, повторно запустив более позднюю сборку, до бесконечности.

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

Ответ 15

В моем случае (смешанное решение С#, C++/CLI и нативное решение C++) некоторые проекты C++ связывались, даже если ничего не изменилось. Я потратил целую вечность, пытаясь понять, что происходит. В итоге из опции "Командная строка" я понял, что путь вывода PDB (опция /Fd) не может обработать настройку папки $ (IntDir). Я удалил это - пустое значение будет делать по умолчанию правильно - и моя проблема ушла.