wake-up-neo.com

Visual Studio erstellt unveränderte Projekte neu

Wie der Titel lautet, habe ich jetzt eine VS2010-Lösung mit ~ 50 Projekten. Wenn ich eine Änderung an einem "Top-Level" -Projekt vornehme, auf das nichts verweist, erstellt VS immer noch alle 50 Projekte neu. Ich verwende Visual Studio 2010 Ultimate ohne Add-Ons. Ich verwende ILMerge, um alle Projekte in einer einzigen Datei zusammenzufassen.

Ich habe dies überprüft, indem ich die Zeitstempel der untergeordneten DLLs überprüfe und sehe, dass sie tatsächlich neu erstellt werden, obwohl ihr Code nicht berührt wurde.

Ich habe alle Antworten und Kommentare gelesen für:

Visual Studio 2008 wird immer wieder neu erstellt

Visual Studio baut alles auf

Seltsame VS2010-Build-Störung tritt in meiner Lösung auf

Gründe für die Neuerstellung von C # -Projekten in Visual Studio

Die meisten von ihnen bieten jedoch lediglich Vorschläge zum Entladen von Projekten, um die Bauzeiten zu beschleunigen, aber nichts Konkretes bezüglich einer Lösung. Ich versuche herauszufinden, warum VS der Meinung ist, dass diese abhängigen Projekte neu aufgebaut werden müssen, wenn sie es nicht tun, und das Problem beheben.

Ich habe "Tools> Optionen> Projekte und Lösungen> Erstellen und Ausführen> Nur Startprojekte und Abhängigkeiten beim Ausführen erstellen" aktiviert, jedoch ohne Auswirkung.

Wenn ich nur ein "Mid-Level" -Projekt neu aufbaue, das nur 8 direkte Abhängigkeiten hat, werden immer noch alle 8 Projekte erstellt, auch wenn ILMerge nicht aufgerufen wird und keines der abhängigen Projekte geändert wurde.

Ich danke Ihnen allen für Ihre Einsichten.

Hinzugefügt

Um einige der Vorschläge zu testen, habe ich ein neues WinForms-Projekt von Grund auf erstellt. Ich habe dann zwei neue Projekte in dieser Lösung erstellt. Ich habe den gesamten Code und die Ressourcen (nicht die Projektdatei) aus meinen zwei "niedrigsten" Projekten in die beiden brandneuen Projekte kopiert (dazu habe ich die Dateien und Ordner aus dem Explorer in das Projekt in Visual Studio gezogen).

Das unterste Projekt, nennen wir es B, hat kein anderes Projekt referenziert. Das nächste Projekt, A, verwies nur auf B. Sobald ich die erforderlichen .NET- und externen Assembly-Referenzen zu den Projekten hinzugefügt hatte, wurde die Lösung erstellt.

Ich hatte dann meine neue WinForm-Projektreferenz A und machte einen vollständigen Build. Die Ref-Kette lautet also:

WinForm -> A -> B

Ich habe dann WinForm _ ​​nur geändert und einen Standard-Build (F6) erstellt. Wie zuvor hat Visual Studio alle drei Projekte neu erstellt.

Nach einer systematischen Eliminierung der Quelldateien in Projekt B fand ich heraus, dass wenn ich Resources.Designer.cs und Resources.resx entfernte (und den Code, der das .Properties.Resources-Objekt dieser Ressourcen verwendete, auskommentierte), eine Änderung von WinForm vorgenommen wurde würde nicht mehr die gesamte Lösung neu erstellen, sondern nur WinForm.

Das Hinzufügen von Resources.resx und Resources.Designer.cs zu Projekt B (wobei der referenzierte Code jedoch auskommentiert wird, sodass die Ressourcen nicht verwendet werden), würde das vollständige Build-Verhalten erneut auftreten.

Um zu sehen, ob meine Ressourcendateien möglicherweise beschädigt waren, löschte ich sie erneut und erstellte dann eine neue (über Projekteigenschaften -> Ressourcen). Sie fügte dieselbe Ressource wie zuvor hinzu. Hierbei handelt es sich um eine einzelne Excel-Datei. Bei diesem Setup würde der vollständige Neuaufbau immer noch stattfinden.

Ich habe dann die einzelne Ressource entfernt, die Ressourcendatei jedoch im Projekt B belassen. Auch wenn keine Ressourcen hinzugefügt wurden, die Ressourcendatei jedoch noch im Projekt ist, würde die vollständige (nicht benötigte) Neuerstellung erfolgen.

Es scheint, dass durch das Hinzufügen einer Ressourcendatei zu einem (.NET 3.5) -Projekt Visual Studio 2010 dieses Projekt immer neu erstellt. Ist das ein Fehler oder beabsichtigtes/erwartetes Verhalten?

Vielen Dank nochmal!

64
Matt Klein

Ich glaube zwar nicht, dass dies ein Fix ist, aber es ist eine Problemumgehung, die für meine Situation funktioniert hat ...

Ich hatte ursprünglich etwa fünf von 50 Projekten, die eine Resources-Sektion enthielten. Diese Projekte würden immer wieder aufgebaut und somit auch alles, worauf sie angewiesen waren, wieder aufgebaut. Eines dieser fünf Projekte war eine Bibliothek auf "Basis" -Ebene, auf die sich 48 der anderen Projekte bezogen haben. Daher würden 96% meines Projekts jedes Mal neu erstellt, auch wenn es nicht benötigt wurde.

Mein Workaround bestand darin, Abhängigkeitseingabe, Schnittstellen und ein dediziertes "Resources" -Projekt zu verwenden. Anstatt diese 5 Projekte auf ihr eigenes Resources-Objekt verweisen zu lassen, habe ich in jedem Projekt eine Schnittstelle erstellt, die die gewünschten Ressourcen bereitstellt. Für die Klassen, die diese Ressourcen benötigten, musste diese Schnittstelle während der Erstellung im Konstruktor übergeben werden (Konstruktorinjektion).

Ich erstellte dann ein separates "Resources" -Projekt, das einen normalen Abschnitt für Ressourcen hatte, der normal ist. Dieses Projekt enthielt nur die Ressourcen selbst und eine Klasse für jede Schnittstelle, die erforderlich war, um diese Ressourcen über eine Schnittstelle bereitzustellen. Dieses Projekt verweist auf jedes andere Projekt, das eine Ressourcenabhängigkeit hatte, und implementiert die Schnittstelle, die das Projekt benötigt.

Schließlich habe ich in meinem "Top Level" -Projekt, auf das nichts Bezug genommen hat (und wo das Exe tatsächlich gebaut wurde und meine Kompositionswurzel lebt), auf das "Resources" -Projekt verwiesen, das DI verkabelt, und los ging es.

Dies bedeutet, dass nur zwei Projekte (die "Ressourcen" und die "oberste Ebene") jedes Mal neu erstellt werden. Wenn ich einen Teilaufbau (Shift-F6) durchführe, werden sie überhaupt nicht neu erstellt.

Wiederum keine großartige Arbeit, aber mit 48 Projekten, die jedes Mal gebaut wurden, dauerte ein Build etwa 3 Minuten, sodass ich täglich 30 bis 90 Minuten mit unnötigen Neuerstellungen verlor. Es hat eine Weile gedauert, um zu refactorieren, aber ich denke, es war eine gute Investition.

Hier ist ein vereinfachtes Diagramm. Beachten Sie, dass die Abhängigkeiten von Main.exe zu Proj1 und Proj2 nicht angezeigt werden, um das Durcheinander zu reduzieren.

Diagram of solution

Mit diesem Entwurf kann ich einen Build von Proj1 oder Proj2 ausführen, ohne eine vollständige Neuerstellung auszulösen, da sie keine Abhängigkeiten von einem Resources-Abschnitt haben. Nur Main kennt die Resources-Implementierung.

17
Matt Klein

Öffnen Sie Extras - Optionen, wählen Sie Projekte und Lösungen - Erstellen und im Baum ausführen aus, und legen Sie "Ausführliche Ausgabe des MSBuild-Projekts für die Erstellung von Ausgaben" auf Diagnose fest.

Projekt 'Referenziertes Projekt' ist nicht auf dem neuesten Stand. Projektelement Für "c:\some.xml" ist das Attribut "In Ausgabeverzeichnis kopieren" auf "Kopieren .__" gesetzt. immer'.

oder

Projekt 'MyProject' ist nicht auf dem neuesten Stand. Eingabedatei 'c:\ReferencedProject.dll' wird nach der Ausgabedatei .__ geändert. 'c:\MeinProjekt.pdb'.

In diesem Fall besteht die Korrektur darin, some.xml nur dann zu kopieren, wenn es neuer ist.

Pre- und Post-Build-Ereignisse können auch Build auslösen.

112
user3285954

Dies geschieht, wenn ein Projekt eine Datei enthält, die nicht wirklich existiert.
Das Projekt kann nicht feststellen, ob die Datei geändert wurde (weil sie nicht vorhanden ist) und wird daher neu erstellt. 

Sehen Sie sich einfach alle Dateien im Projekt an und suchen Sie nach der Datei, in der sich kein erweiterbarer Pfeil befindet.

15
Yochai Timmer

Ich hatte das gleiche Problem in VS 2015.

Was für mich der Trick war, ist:

  1. Ein Projekt hat sich selbst auf eine Kopie in einer anderen Projektablage (magisch, ja) bezogen. Diese Art von Informationen könnte gefunden werden, wenn Sie zur Diagnose-Build-Ausgabe (in den Build-Optionen) wechseln und dann versuchen, Projekte nacheinander von oben in der Projekthierarchie zu erstellen. Wenn Sie das Projekt sehen, das sich neu erstellt, auch wenn nichts geändert wurde, sehen Sie es Verweise.
  2. Ich habe alle "immer kopieren" -Dateien in allen Projekten so geändert, dass sie "neuere kopieren". Grundsätzlich ersetzen Sie in allen .csproj-Dateien <CopyToOutputDirectory>Always</CopyToOutputDirectory> durch <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>.
  3. Dann habe ich das NTFS-Tunneln wie in this article mit diesem Powershell-Skript beschrieben deaktiviert:

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

Danach brauchte ich einen Umbau und es scheint für jetzt zu funktionieren.

9
Michael Logutov

In meinem Fall war der Täter die Einstellung "Copy Local" einer referenzierten DLL, die auf "true" gesetzt ist, und "Copy to Output Directory".

4
I-A-N

Das MSBuild-Team sammelt hier Dokumentationen zur Untersuchung von Inkrementalitätsproblemen im Build: https://github.com/Microsoft/MSBuild/wiki/Rebuilding%20when%20nothing%20changed

1
Kirill Osenkov

Ich hatte das gleiche Problem und es stellte sich heraus, dass es mit einem Projekt zu tun hatte, das eine Kopie der lokalen Referenz auf eine DLL in ihrem eigenen Ausgabeverzeichnis hatte.

Der Schlüssel dazu war, dass die Diagnoseausgabe für die Build-Ausgabe festgelegt wurde, aber auch wusste, wonach im Protokoll gesucht werden sollte. Suchen nach: ' nicht aktuell ' war der Schlüssel.

1
Ademund

Ich habe endlich einen weiteren Schuldigen gefunden, den ich nur schwer finden konnte, indem ich die Verbosität des Buildprotokolls erhöhte.

In einigen Fällen sucht MSBuild im Ausgabeordner nachvc120.pdb. Wenn diese Datei nicht vorhanden ist, wird das gesamte Projekt neu erstellt. Dies tritt auf, auch wenn Sie die Debug-Symbol-Generierung deaktiviert haben. 

Sie können dieses Problem umgehen, indem Sie Debug-Symbole aktivieren und diese Datei generieren lassen. Deaktivieren Sie die Einstellung erneut , ohne die PDB-Datei zu löschen.

1
Mehrdad

Für diese Kategorie von Build-Problemen ist es in der Tat ein notwendiger erster Schritt, die Ausgabebosität von MSBuild auf 'Diagnose' zu setzen. In den meisten Fällen würde der angegebene Grund für die Neuerstellungen ausreichen, um darauf zu reagieren, aber gelegentlich behauptete MSBuild, dass einige Dateien geändert wurden und kopiert werden müssen.

In diesem Fall müssen Sie entweder das NTFS-Tunneln deaktivieren oder den Ausgabeordner an einen neuen Speicherort kopieren. Hier ist es in mehr Worten.

0
Ofek Shilon

In meinem Fall (gemischte C # -, C++/CLI- und native C++ - Lösung) wurden einige C++ - Projekte erneut verknüpft, auch wenn sich nichts geändert hatte. Ich habe ewig versucht, herauszufinden, was los war. Am Ende habe ich anhand der Option "Command Line" herausgefunden, dass der PDB-Ausgabepfad (Option/Fd) die Ordnereinstellung $ (IntDir) nicht verarbeiten kann. Ich habe das entfernt - ein leerer Wert macht den Standard korrekt - und mein Problem ist verschwunden.

0
user11657883

Aufgrund Ihrer Beobachtungen klingt es so, als hätten Sie Projekte, die Abhängigkeiten zu anderen Projekten auf eine nicht offensichtliche Weise ausdrücken. Es ist möglich, dass verwaiste Abhängigkeiten in Projektdateien verbleiben, ohne in der Benutzeroberfläche sichtbar zu sein. Haben Sie eine fehlerhafte Projektdatei nach dem Öffnen in einem Texteditor durchgesehen? Geprüfte Abhängigkeiten beim Lösungsaufbau?

Wenn Sie nichts entdecken können, versuchen Sie, eines Ihrer Projekte von Grund auf neu zu erstellen, um zu sehen, ob das neue Projekt das gleiche Problem aufweist. Wenn das saubere Projekt korrekt erstellt wird, wissen Sie, dass irgendwo unerwünschte Abhängigkeiten zum Ausdruck kommen. Soweit ich weiß, müssten sich diese in der Projektdatei oder den Lösungsdateien befinden, es sei denn, Sie haben Makefiles oder andere ungewöhnliche Buildschritte.

0
Owen Wengerd

Hier ist eine Antwort von VS2010 baut immer wieder eine Lösung auf?

Dieses Problem wird durch Ändern der Projektdateien, der Bereinigungslösung, .__ gelöst. Löschen aller Ordnerordner von Hand, Neustarten von Visual Studio und alles neu aufbauen.

0
Ryan Byrne

Beim Aktualisieren von Visual Studio 2015 auf 2017 hatte ich das Problem, dass Visual Studio Projekte neu erstellt, und ich füge diese Antwort zum Vorteil derjenigen hinzu, die ähnliche Probleme haben könnten, da sie nirgendwo dokumentiert zu sein scheint.

In meinem Fall bestand das Problem darin, dass alle Projekte in der Lösung den gleichen Ausgabepfad (obj) hatten. Die Datei GeneratedInternalTypeHelper.cs wird von allen Projekten generiert, die XAML enthalten. Bis zu Visual Studio 2015 hat der Erstellungsprozess anscheinend nicht nach dem Dateidatum dieser Datei gesucht, und daher ist kein Problem damit aufgetreten. Mit VS2017 wird das Dateidatum dieser Datei geprüft. Da ein späteres Projekt im Erstellungsprozess diese Datei überschreibt (mit demselben Inhalt), wird das frühere Projekt neu erstellt, wodurch der spätere Build ad infinitum erneut ausgelöst wird.

Die Lösung besteht in diesem Fall darin, sicherzustellen, dass alle Projekte unterschiedliche Ausgabeverzeichnisse haben, wodurch das Problem behoben wird.

0
Flash

Ein anderes Problem, das häufig auftritt, ist, wenn ein Element in Ihrer Lösung einen geänderten Stempel hat, der in der Zukunft liegt. Dies kann passieren, wenn Sie Ihre Uhr vorwärts und dann auf die richtige Uhrzeit einstellen. Ich hatte dies während der Installation von Linux.

In diesem Fall können Sie alle Dateien rekursiv mit git bash (ja, in Windows) berühren:

find . -exec touch {} \;
0
Mikhail

Ich hatte die gleichen Probleme mit Ihnen ... Ich fand heraus, dass es aus gelöschten Dateien stammte. Als ich die Dateien aus meinem Projekt entfernt hatte, waren die Probleme verschwunden.

0
PhonPanom