Visual Studio sperrt die Ausgabedatei beim Erstellen

80

Ich habe eine einfache WinForms-Lösung in VS 2010. Jedes Mal, wenn ich sie erstelle, wird die Ausgabedatei (bin \ debug \ app.exe) gesperrt, und nachfolgende Builds schlagen mit der Meldung fehl. "The process cannot access the file 'bin\Debug\app.exe' because it is being used by another process." Die einzige Möglichkeit, das Projekt zu erstellen, besteht darin, VS danach neu zu starten Jeder Build, der sehr umständlich ist.

Ich habe diesen alten Blog-Beitrag gefunden http://blogs.geekdojo.net/brian/archive/2006/02/17/VS2005FileLocking.aspx - es scheint, dass das Problem wirklich alt ist. Weiß jemand, was hier passiert, oder zumindest eine Problemumgehung?

Aktualisieren

Ich führe die Datei nicht wirklich aus . Das Sperren erfolgt nach dem Build, nicht nach dem Debuggen (dh VS starten - Build - Build - Fail!) Und ich habe versucht, Antivirus auszuschalten. Es hilft nicht.

Update 2

Der Prozess-Explorer zeigt an, dass devenv.exe die Datei geladen hat (in DLLs, nicht in Handles). Es scheint, als ob ein Fehler während des Builds das Entladen verhindert hat, aber der (erste) Build wird ohne andere Meldungen als "1 erfolgreich, o fehlgeschlagen" abgeschlossen.

Keine Ursache
quelle
gelegentlich habe ich ein ähnliches Problem; Verwenden Sie Windows 7? In meinem Fall ist es nicht VS, die Datei zu sperren: Ich kann sie einfach im Explorer löschen, und der Build läuft einwandfrei. Ich habe festgestellt, dass das Problem häufiger auftritt, wenn im Ausgabeverzeichnis ein Explorer-Fenster geöffnet ist. Übrigens keinen Virenscanner verwenden.
Stijn
Das gleiche Problem tritt gelegentlich unter Win7 auf, wenn NUnit verwendet wird. Dies ist äußerst ärgerlich, wenn Sie TDD ausführen.
Mathias
@stijn: Verwenden Sie keinen On-Access-Virenscanner? Doooh ...
TheBlastOne
Dies fällt mir auch bei VS 2013 ein, wenn ich Komponententests debugge und den Code stoppe, bevor VS die Testausführung abschließt. Wenn ich einige Sekunden länger warte, bis VS den Testläufer entladen hat, passiert dies nicht.
StingyJack
Vielleicht hilft dies: Sevenforums.com/tutorials/…
Saturn Technologies

Antworten:

69

Hatte das gleiche Problem, fand aber eine Lösung (danke an Keyvan Nayyeri ):

Aber wie kann man das lösen? Abhängig von Ihrem Projekttyp gibt es verschiedene Möglichkeiten. Eine einfache Lösung, die ich Visual Studio-Add-In-Entwicklern empfehle, besteht darin, den Build-Ereignissen ihres Projekts einen einfachen Code hinzuzufügen.

Sie können der vorgefertigten Ereignisbefehlszeile Ihres Projekts die folgenden Codezeilen hinzufügen.

if exist "$(TargetPath).locked" del "$(TargetPath).locked"
if exist "$(TargetPath)" if not exist "$(TargetPath).locked" move "$(TargetPath)" "$(TargetPath).locked"
Stormenet
quelle
Hat auch für mich gearbeitet. Ich habe dieses Problem schon seit einiger Zeit.
Ritcoder
Das funktioniert bei mir. Ich habe die% random% -Version gemäß Vladimir Datsyuk unten ausprobiert, aber festgestellt, dass in meinem Fall die einzige gesperrte Datei vom ersten Build nach dem Start von VS stammt, sodass sie nur einmal funktionieren muss. Ich bin auf VS 2013 und benutze auch nicht den GUI-Designer, sondern nur eine große Lösung mit vielen Referenzen und T4-Vorlagenprojekten.
Davos
5
Ich musste das PDB auch umbenennen, da es auch gesperrt war : if exist "$(TargetDir)$(TargetName).pdb.locked" del "$(TargetDir)$(TargetName).pdb.locked" ,if exist "$(TargetDir)$(TargetName).pdb" if not exist "$(TargetDir)$(TargetName).pdb.locked" move "$(TargetDir)$(TargetName).pdb" "$(TargetDir)$(TargetName).pdb.locked"
Tobias J
Funktioniert auch für mich (Visual Studio 2013). Thx
Anonym
Arbeitet weiter an VS2017. Überraschend ist, dass das Problem in VS2017 weiterhin besteht!
Carvo Loco
24

Es ist kein Virenproblem. Es ist ein Visual Studio 2010-Fehler. Es scheint, dass das Problem mit der Verwendung von Visual Studio GUI Designer zusammenhängt.

Die Problemumgehung besteht darin, die gesperrte Ausgabedatei im Pre-Build-Ereignis in eine andere temporäre Datei zu verschieben. Es ist sinnvoll, temporäre Dateinamen zufällig zu generieren.

del "$(TargetPath).locked.*" /q 
if exist "$(TargetPath)"  move "$(TargetPath)" "$(TargetPath).locked.%random%"
exit /B 0

Wenn Sie konstante temporäre Dateinamen verwenden, verschieben Sie einfach die Sperren:

Diese Problemumgehung funktioniert genau einmal

 if exist "$(TargetPath).locked" del "$(TargetPath).locked"
    if exist "$(TargetPath)" if not exist "$(TargetPath).locked" move "$(TargetPath)" "$(TargetPath).locked"

Ich habe auch eine Lösung mit 2 temporären Dateien gefunden, die genau 2 Mal funktioniert.

Vladimir Datsyuk
quelle
1
Das passiert mir auch, aber nur, wenn ich meine App starte. Ich vermute, es ist das Betriebssystem, das die ausführbare Datei für das Caching oder aus welchen Gründen auch immer im Auge behält. Außerdem scheint es zumindest in meinem Fall nur für Apps zu passieren, die System.Reflection.Assembly.GetExecutingAssembly () aufrufen.
TheBlastOne
2
OK, es scheint, dass es nur passiert, wenn der letzte Lauf System.Reflection.Assembly.GetExecutingAssembly heißt oder - und das ist neu - wenn der Quellcode einer Design-Time-Komponente (Quellcode einer Design-Time-Komponente, die in der Komponentensymbolleiste aktiv ist). Dadurch wird ein Aufruf von System.Reflection.Assembly.GetExecutingAssembly während der Entwurfszeit ausgeführt, der im Editor geöffnet war, als der letzte Lauf gestartet wurde. Ich habs?
TheBlastOne
1
Ich denke, dass dieses Problem plötzlich aufgetreten ist ... Jetzt habe ich 30 Minuten meines Lebens damit verbracht, ein Projekt-Setup zu erstellen ... weil ich Probleme beim Sperren habe! Ich
starte
1
stackoverflow.com/questions/3312646/… das hat bei mir
funktioniert
1
Zusätzlich für die pbd-Datei: del "$(TargetPath).locked.*" /q if exist "$(TargetPath)" move "$(TargetPath)" "$(TargetPath).locked.%random%" del "$(TargetDir)$(TargetName).pdb.locked.*" /q if exist "$(TargetDir)$(TargetName).pdb" move "$(TargetDir)$(TargetName).pdb" "$(TargetDir)$(TargetName).pdb.locked.%random%" exit /B 0
Marv
6

Das Problem ist mir auch eingefallen.

Mein Szenario war folgendes: Ausführen von Windows 7 (aber möglicherweise auch in Windows XP) und während der Arbeit an einem Projekt mit WPF User Control konnte ich alle Male erstellen, bis ich die XAML-Datei des User Control öffnete - Von dort aus habe ich ' Ich habe einen Build und dann sind die Dateien gesperrt.

Außerdem habe ich festgestellt, dass ich Visual Studio (Devenv.exe) als Administrator ausgeführt habe, Visual Studio ohne Administratorrechte ausgeführt habe und das Problem behoben war! .

Lassen Sie mich wissen, ob es Ihnen auch geholfen hat. Viel Glück.

Shani Elharrar
quelle
1
Ich hatte genau das gleiche Problem in allen VS11-Versionen, konnte aber noch keinen Fix finden (leider hat es nicht geholfen, auf Administratorrechte zu verzichten). Irgendwelche Ideen geschätzt!
Dan Nolan
4

Ich habe dies entweder auf einer gierigen Virenscan-Software gesehen oder wenn app.exe nicht richtig heruntergefahren wird. Stellen Sie sicher, dass der Prozess noch nicht ausgeführt wird.

McAden
quelle
3

Was ist mit Virenscannern auf Ihrem Computer? Können Sie Prozesse sehen, die Handles für Ihre Datei enthalten (verwenden Sie den Prozess-Explorer , um dies herauszufinden)?

Möglicherweise ist in Ihrer Prozessliste "app.exe" sichtbar, dh die letzte Version, die Sie debuggt haben, wird noch ausgeführt? Wenn Sie Anwendungen mit mehreren Threads entwickeln, kann dies passieren, wenn Sie nicht joinalle verwenden.

Naivisten
quelle
3

Ich hatte das gleiche Problem und fand heraus, dass VS die Exe nur sperrt, wenn ich vor dem Erstellen ein Formular oder UserControl in VS öffnete. Die Lösung war recht einfach. Ich musste nur ein Formular / UserControl schließen, bevor ich die Lösung erstellte, und es funktionierte.

Enyra
quelle
3

Basieren Sie auf der großartigen Stormenet-Antwort ich ein kleines Skript erstellt, das in jedem Fall funktionieren sollte.

Hier ist der Code, der in das Textfeld für das Ereignis vor dem Erstellen eingefügt werden soll

$(SolutionDir)\BuildProcess\PreBuildEvents.bat  "$(TargetPath)"  "$(TargetFileName)"  "$(TargetDir)"  "$(TargetName)"

Pre-Build-Ereignis

Hier ist das Skript, das in die Datei kopiert werden soll $(SolutionDir)\BuildProcess\PreBuildEvents.bat (natürlich können Sie diesen Pfad ändern):

REM This script is invoked before compiling an assembly, and if the target file exist, it moves it to a temporary location
REM The file-move works even if the existing assembly file is currently locked-by/in-use-in any process.
REM This way we can be sure that the compilation won't end up claiming the assembly cannot be erased!

echo PreBuildEvents 
echo  $(TargetPath) is %1
echo  $(TargetFileName) is %2 
echo  $(TargetDir) is %3   
echo  $(TargetName) is %4

set dir=C:\temp\LockedAssemblies

if not exist %dir% (mkdir %dir%)

REM delete all assemblies moved not really locked by a process
del "%dir%\*" /q

REM assembly file (.exe / .dll) - .pdb file - eventually .xml file (documentation) are concerned
REM use %random% to let coexists several process that hold several versions of locked assemblies
if exist "%1"  move "%1" "%dir%\%2.locked.%random%"
if exist "%3%4.pdb" move "%3%4.pdb" "%dir%\%4.pdb.locked%random%"
if exist "%3%4.xml.locked" del "%dir%\%4.xml.locked%random%"

REM Code with Macros
REM   if exist "$(TargetPath)"  move "$(TargetPath)" "C:\temp\LockedAssemblies\$(TargetFileName).locked.%random%"
REM   if exist "$(TargetDir)$(TargetName).pdb" move "C:\temp\LockedAssemblies\$(TargetName).pdb" "$(TargetDir)$(TargetName).pdb.locked%random%"
REM   if exist "$(TargetDir)$(TargetName).xml.locked" del "C:\temp\LockedAssemblies\$(TargetName).xml.locked%random%"
Patrick vom NDepend-Team
quelle
2

Es ist auch ein Problem 533411 bekannt, bei dem die Verwendung der automatischen Aktualisierung von Build-Nummern das Sperrproblem verursachen kann. Problemumgehung aus dem Fehlerbericht

Vorübergehende Problemumgehung ist das Deaktivieren der Aktualisierung der Assemblyversion nach der Neuerstellung. Entfernen Sie in der Datei AssemblyInfo.cs den Platzhalter aus dem AssemblyVersion-Attribut.
Ersetzen Sie beispielsweise Folgendes:
[Assembly: AssemblyVersion ("1.4. *")]
[Assembly: AssemblyFileVersion ("1.4")]
durch Folgendes:
[Assembly: AssemblyVersion ("1.4.0.0")]
[Assembly: AssemblyFileVersion ("1.4.0.0")]

Robert MacLean
quelle
2

Ich hatte dieses Problem und löste es mit einem benutzerdefinierten Code. Siehe hier: Probleme beim Erstellen von Dateisperren für Visual Studio 2010

Kompilieren Sie das Dienstprogramm in der akzeptierten Antwort und verweisen Sie während des Erstellungsschritts darauf, wie beschrieben, um das Problem zu umgehen. Ich schalte VS 2010 immer noch beim Mittagessen aus, um die morgendliche Arbeit aufzuräumen.

Der Grund für den benutzerdefinierten Code war, dass die häufig empfohlene Lösung nur einmal funktionierte und dann auch die umbenannten Dateien gesperrt wurden, wodurch das Umbenennen verhindert wurde. Hier hängen wir einfach die Datenzeitinformationen an die Datei an, damit die umbenannten Versionen nicht in Konflikt geraten können.

Godeke
quelle
0

Das einzige, was für mich funktioniert hat, war, Visual Studio 2012 zu beenden, die Ordner BIN und OBJ für das Projekt mit Problemen zu löschen und Visual Studio erneut zu öffnen.

Problem gelöst ... Bis zum nächsten Mal.

Willem
quelle
0

Wenn Ihr $ (TargetPath) auf eine DLL verweist, die COM verwendet, stellen Sie sicher, dass Sie einen Standardkonstruktor haben. Nicht sicher, warum der Standardkonstruktor dort nicht abgeleitet wird. Das Hinzufügen des Standardkonstruktors hat in diesem Szenario für mich funktioniert.

Onyximo
quelle
0

Das Schließen des Visual Studios, das erneute Öffnen und das erneute Laden der neuesten Lösung umgehen das Problem für mich. (Visual Studio 2013 Ultimate)

Jay
quelle
1
Ja, das muss ich jedes Mal machen. das ist keine Lösung
John Demetriou
0

Ich bin auf dasselbe gestoßen, als ich in VS2017 Xamarin-Apps entwickelt habe.

Es war zufällig Windows Defender, der die exe / dll mit devenv.exe sperrte.

Sie können zu Win Defender gehen und hinzufügen

devenv.exe
msbuild.exe

zur Prozessausschlussliste.

michael g
quelle
Wie haben Sie herausgefunden, dass es Windows Defender ist?
Mike
Meine Lösung hat ein bisschen funktioniert, aber ich habe herausgefunden, dass es tatsächlich ein schwerwiegender Fehler in einer neuen VS2017-Update-Version für mich war. Developercommunity.visualstudio.com/content/problem/54945/…
Michael G
0

Dies ist die Lösung, die ich herausfinde

  1. Deaktivieren Sie den Visual Studio-Hosting-Prozess in den Projekteinstellungen wie unten gezeigt

Geben Sie hier die Bildbeschreibung ein

  1. Töte die Exe. Es wird Ihr applicationname.vshost.exe vom Taskmanager sein

Geben Sie hier die Bildbeschreibung ein

  1. Jetzt können Sie Ihre Anwendung neu erstellen und ausführen.

Hinweis: Sie können diese Option ohne Probleme wieder aktivieren.

Ramankingdom
quelle
0

Ich konnte dieses Problem beheben, indem ich das Echtzeit-Scannen von McAfee LiveSafe deaktivierte. Meine EXE-Datei würde sich wie im OP beschrieben abstürzen und ich hätte keine Möglichkeit, die Datei zu entfernen, was bedeutete, dass ich die Lösung nicht erstellen konnte. Nach dem Deaktivieren der McAfee-Funktion war das Problem behoben.

Dann habe ich natürlich McAfee vollständig deinstalliert, das nur installiert wurde, weil mein PC neu ist und das Programm bereits installiert war.

Konrad Skagerberg
quelle
-8

Ich habe eine neue leere Lösung erstellt und alle alten Dateien hinzugefügt. Dies löste irgendwie das Problem.

Keine Ursache
quelle
Dies kann unmöglich die Antwort sein. Andere haben weitaus klarere Gründe für das Problem und geeignete Problemumgehungen angegeben, für die keine neue Lösungsdatei erstellt werden muss, was bei der Arbeit mit der Versionskontrolle nicht akzeptabel ist, da der Verlauf verloren gehen würde.
Bernhard Hofmann
Ja, das ist eine schlechte Antwort. Andere sind noch schlimmer. Das Umbenennen von Ausgabedateien ist keine Lösung, sondern eine unhandliche Problemumgehung. Wenn Sie bessere Ideen haben, warum nicht eine Antwort posten?
Nevermind
Das Erstellen einer neuen Lösung hat das Problem für mich nur vorübergehend gelöst. Die beste Antwort scheint die von Vladimir Datsyuk zu sein.
user492238
1
Wäre Ihre Lösung optimal, wenn Sie 15 Projekte in einer Lösung hätten?
Shittu Joseph Olugbenga