it-swarm.com.ru

Visual Studio перестраивает неизмененные проекты

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

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

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

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

Визуальная студия все строит

Странный глюк сборки VS2010 происходит в моем решении

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

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

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

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

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

Добавлено

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

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

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

WinForm -> A -> B

Затем я изменил WinForm _ ​​только и выполнил стандартную сборку (F6). Как и прежде, Visual Studio перестроил все три проекта.

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

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

Чтобы проверить, не повреждены ли мои файлы ресурсов, я снова удалил их, а затем создал новый (через Свойства проекта -> Ресурсы) и повторно добавил тот же ресурс, что и раньше, который представлял собой один файл Excel. При такой настройке полная перестройка все равно будет происходить.

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

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

Спасибо всем еще раз!

64
Matt Klein

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

Первоначально у меня было около 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.

17
Matt Klein

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

Проект 'ReferencedProject' не обновлен. Элемент проекта «c:\some.xml» имеет атрибут «Copy to Output Directory», установленный на «Copy всегда'.

или же

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

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

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

112
user3285954

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

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

15
Yochai Timmer

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

Что сделал трюк для меня это:

  1. Один проект ссылался на саму копию в каком-то другом бине проекта (магия, да). Подобные вещи могут быть найдены при переключении на вывод диагностической сборки (в опциях сборки), а затем при попытке построить проекты один за другим из верхней части иерархии проектов - если вы видите проект, который перестраивается, даже если ничего не было изменено, посмотрите, что он Рекомендации.
  2. Я изменил все файлы «всегда копировать» во всех проектах на «копировать, если новее». Как правило, во всех файлах .csproj заменить <CopyToOutputDirectory>Always</CopyToOutputDirectory> на <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
  3. Затем я отключил туннелирование NTFS, как описано в this статье с помощью этого сценария powershell:

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

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

9
Michael Logutov

В моем случае виновником была установка «Копировать локально» для dll, на которую ссылаются, в значение «истина» и «Копировать в выходной каталог», задавая для файла значение «Копировать всегда».

4
I-A-N

Команда MSBuild собирает документацию по расследованию проблем с инкрементностью сборки здесь: https://github.com/Microsoft/MSBuild/wiki/Rebuilding%20when%20nothing%20changed

1
Kirill Osenkov

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

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

1
Ademund

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

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

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

1
Mehrdad

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

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

0
Ofek Shilon

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

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

0
Owen Wengerd

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

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

0
Ryan Byrne

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

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

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

0
Flash

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

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

find . -exec touch {} \;
0
Mikhail

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

0
PhonPanom