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 всегда будет перестраивать этот проект. Является ли это ошибкой или предполагаемым/ожидаемым поведением?
Спасибо всем!
Ответы
Ответ 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", устанавливающий файл, всегда установленный для копирования.
Ответ 6
Команда MSBuild собирает документацию о расследовании проблем с инкрементностью сборки здесь:
https://github.com/Microsoft/MSBuild/wiki/Rebuilding%20when%20nothing%20changed
Ответ 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). Я удалил это - пустое значение будет делать по умолчанию правильно - и моя проблема ушла.