Visual Studio bloquea el archivo de salida en la compilación

80

Tengo una solución simple de WinForms en VS 2010. Siempre que la compilo, el archivo de salida (bin \ debug \ app.exe) termina bloqueado y las compilaciones posteriores fallan con un mensaje como "The process cannot access the file 'bin\Debug\app.exe' because it is being used by another process." La única forma de compilar el proyecto es reiniciar VS después cada construcción, lo cual es muy incómodo.

Encontré esta antigua publicación de blog http://blogs.geekdojo.net/brian/archive/2006/02/17/VS2005FileLocking.aspx ; parece que el problema es realmente antiguo. ¿Alguien sabe lo que está sucediendo aquí, o al menos alguna solución?

Actualizar

En realidad, no ejecuto el archivo. El bloqueo ocurre después de la compilación, no después de la depuración (es decir, iniciar VS - build - build - fail!) Y traté de apagar el antivirus. No ayuda.

Actualización 2

Process Explorer muestra que devenv.exe ha cargado el archivo (en DLL, no en Handles). Parece que un error durante la compilación impidió la descarga, pero la (primera) compilación se completa sin ningún mensaje que no sea "1 tuvo éxito, o falló" /

No importa
fuente
ocasionalmente tengo un problema similar; ¿Usas Windows 7? En mi caso, no es VS que bloquea el archivo: puedo eliminarlo en el explorador y la compilación funciona bien. Noté que el problema ocurre con más frecuencia si tengo una ventana del explorador abierta en el directorio de salida. No usar un escáner de virus por cierto.
stijn
El mismo problema ocurre ocasionalmente en Win7, cuando se usa NUnit, lo cual es extremadamente molesto cuando se usa TDD.
Mathias
@stijn: ¿No usas un escáner de virus en tiempo real? Doooh ...
TheBlastOne
Esto también me ocurre con VS 2013 cuando estoy depurando pruebas unitarias y detengo el código antes de que VS complete la ejecución de la prueba. Si espero unos segundos adicionales para que VS descargue el corredor de prueba, no sucede.
StingyJack
Quizás esto ayude: sevenforums.com/tutorials/…
Saturn Technologies

Respuestas:

69

Tuve el mismo problema, pero encontré una solución (gracias a Keyvan Nayyeri ):

Pero, ¿cómo solucionar esto? Hay varias formas según el tipo de proyecto, pero una solución simple que recomiendo a los desarrolladores de complementos de Visual Studio es agregar un código simple a los eventos de compilación de su proyecto.

Puede agregar las siguientes líneas de código a la línea de comando del evento de preconstrucción de su proyecto.

if exist "$(TargetPath).locked" del "$(TargetPath).locked"
if exist "$(TargetPath)" if not exist "$(TargetPath).locked" move "$(TargetPath)" "$(TargetPath).locked"
Stormenet
fuente
También funcionó para mí. He tenido ese problema desde hace algún tiempo.
ritcoder
Esto funciona para mi. Probé la versión% aleatoria% de esto según Vladimir Datsyuk a continuación, pero descubrí que en mi caso, el único archivo que se bloquea es el de la primera compilación después de iniciar VS, por lo que solo necesita funcionar una vez. Estoy en VS 2013, y tampoco estoy usando el diseñador de interfaz gráfica de usuario, solo una gran solución con muchas referencias y proyectos de plantilla T4.
Davos
5
Necesitaba cambiar el nombre de la AP también, ya que estaba cerrada también: 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
Funciona también para mí (Visual Studio 2013). Thx
Anónimo
Sigue trabajando en VS2017. ¡Lo sorprendente es que el problema persiste en VS2017!
Carvo Loco
24

No es un problema de virus. Es un error de Visual Studio 2010. Parece que el problema está relacionado con el uso de Visual Studio GUI Designer.

La solución aquí es mover el archivo de salida bloqueado a otro temporal en el evento previo a la compilación. Tiene sentido generar un nombre de archivo temporal al azar.

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

En caso de utilizar nombres de archivos temporales constantes, simplemente pospondrá los bloqueos:

Esa solución funciona exactamente una vez

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

También encontré una solución con 2 archivos temporales que funciona exactamente 2 veces.

Vladimir Datsyuk
fuente
1
A mí también me pasa, pero solo si ejecuto mi aplicación. Sospecho que es el sistema operativo vigilando lo ejecutable para el almacenamiento en caché o por cualquier motivo. Además, parece suceder solo para las aplicaciones que llaman a System.Reflection.Assembly.GetExecutingAssembly (), al menos en mi caso.
TheBlastOne
2
De acuerdo, parece que sucede solo si la última ejecución se llamó System.Reflection.Assembly.GetExecutingAssembly, o -y eso es noticia- si el código fuente de algún componente en tiempo de diseño (código fuente de cualquier componente en tiempo de diseño que esté activo en la barra de herramientas del componente) que hace una llamada a System.Reflection.Assembly.GetExecutingAssembly durante el tiempo de diseño estaba abierta en el editor cuando comenzó la última ejecución. ¿Entendido?
TheBlastOne
1
Creo que este problema apareció de repente ... Ahora he perdido 30 minutos de mi vida tratando de construir una configuración de proyecto ... ¡porque tengo problemas de bloqueo!
Ni
1
stackoverflow.com/questions/3312646/… eso funcionó para mí
GorillaApe
1
Adicional para el archivo PBD: 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

El problema también se me ocurrió a mí.

Mi escenario era el siguiente: ejecutar Windows 7 (pero también podría suceder en Windows XP) y mientras trabajaba en un proyecto con WPF User Control pude compilar todo el tiempo, hasta abrir el archivo XAML del User Control - Desde allí, yo ' tengo una compilación, y luego los archivos están bloqueados.

Además, me di cuenta de que estaba ejecutando Visual Studio (Devenv.exe) como administrador, comencé a ejecutar Visual Studio sin privilegios de administrador y el problema desapareció. .

Déjame saber si también te ayudó. Buena suerte.

Shani Elharrar
fuente
1
He tenido exactamente el mismo problema en todas las versiones de VS11, pero aún no he logrado encontrar una solución (desafortunadamente, no tener privilegios de administrador no ayudó). ¡Cualquier idea apreciada!
Dan Nolan
4

He visto esto en un software de escaneo de virus codicioso o si app.exe no se cierra correctamente. Asegúrese de que el proceso aún no se esté ejecutando.

McAden
fuente
3

¿Qué pasa con los escáneres de virus en su máquina? ¿Puede ver algún proceso que tenga identificadores en su archivo (use Process Explorer para averiguarlo)?

¿Quizás haya "app.exe" visible en su lista de procesos, es decir, la última versión que depuró todavía se está ejecutando? Cuando desarrolla aplicaciones que tienen varios subprocesos, esto puede suceder si no los tiene jointodos.

ingenuos
fuente
3

Tuve el mismo problema y descubrí que VS solo bloquea el exe cuando abrí un Form o UserControl en VS antes de construir. La solución fue bastante fácil, solo tuve que cerrar cualquier Form / UserControl antes de construir la solución y funcionó.

Enyra
fuente
3

Basado en la gran respuesta de Stormenet , puse un pequeño script que debería funcionar en todos los casos.

Aquí está el código para poner en el cuadro de texto del evento previo a la compilación

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

Evento previo a la construcción

Aquí está el script para copiar en el archivo $(SolutionDir)\BuildProcess\PreBuildEvents.bat (por supuesto, puede modificar esta ruta):

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 del equipo de NDepend
fuente
2

También existe un problema conocido 533411 en el que el uso de la actualización automática de números de compilación puede causar el problema de bloqueo. Solución alternativa del informe de errores

La solución temporal sería deshabilitar la actualización de la versión de ensamblado después de la reconstrucción. En el archivo AssemblyInfo.cs, elimine el comodín del atributo AssemblyVersion, por ejemplo:
reemplace esto:
[assembly: AssemblyVersion ("1.4. *")]
[Assembly: AssemblyFileVersion ("1.4")]
por esto:
[assembly: AssemblyVersion ("1.4.0.0")]
[ensamblado: AssemblyFileVersion ("1.4.0.0")]

Robert MacLean
fuente
2

Tuve este problema y lo resolví con un código personalizado. Vea aquí: Problemas de bloqueo de archivos de compilación de Visual Studio 2010

Compile la utilidad en la respuesta aceptada y haga referencia a ella durante el paso de compilación como se describe para solucionar el problema. Todavía apago VS 2010 en el almuerzo para limpiar el trabajo de la mañana.

La razón del código personalizado fue que la solución recomendada a menudo solo funcionó una vez y luego los archivos renombrados también se bloquearon, evitando el cambio de nombre. Aquí simplemente agregamos la información de tiempo de datos al archivo para que las versiones renombradas no entren en conflicto.

Godeke
fuente
0

Lo único que funcionó para mí fue salir de Visual Studio 2012, eliminar las carpetas BIN y OBJ para el proyecto que tenía problemas y abrir Visual Studio nuevamente.

Problema resuelto ... Hasta la próxima.

willem
fuente
0

Si su $ (TargetPath) apunta a una DLL que usa COM, asegúrese de tener un constructor predeterminado. No estoy seguro de por qué el constructor predeterminado no se infiere allí. Agregar el constructor predeterminado funcionó para mí en este escenario.

Onyximo
fuente
0

Cerrar Visual Studio, reabrir y recargar la solución más reciente soluciona el problema para mí. (Visual Studio 2013 Ultimate)

Arrendajo
fuente
1
Sí, tengo que hacer eso cada vez. eso no es solución
John Demetriou
0

Me encontré con lo mismo desarrollando aplicaciones xamarin en VS2017.

Resultó que Windows Defender bloqueaba el archivo exe / dll con devenv.exe.

Puede ir a Win Defender y agregar

devenv.exe
msbuild.exe

a la lista de exclusión de procesos.

michael g
fuente
¿Cómo averiguaste que era Windows Defender?
Mike
mi solución funcionó un poco, pero descubrí que en realidad era un error importante en una nueva versión de actualización de VS2017 para mí. developercommunity.visualstudio.com/content/problem/54945/…
michael g
0

Esta es la solución que descubro

  1. Desmarque el proceso de alojamiento de Visual Studio en la configuración del proyecto como se muestra a continuación

ingrese la descripción de la imagen aquí

  1. Mata al exe. será su nombre de aplicación.vshost.exe de taskmanager

ingrese la descripción de la imagen aquí

  1. Ahora puede reconstruir su aplicación y ejecutarla.

Nota: Puede volver a habilitar esta opción sin problemas.

Ramankingdom
fuente
0

Logré solucionar este problema desactivando el análisis en tiempo real de McAfee LiveSafe. Mi archivo .exe se bloquearía como describe el OP y no tendría forma de eliminar el archivo, lo que significaba que no podía construir la solución. Después de deshabilitar la función de McAfee, el problema desapareció.

Luego, por supuesto, procedí a desinstalar completamente McAfee, que solo se instaló porque mi PC es nueva y venía con el programa ya instalado.

Konrad Skagerberg
fuente
-8

Creé una nueva solución en blanco y le agregué todos los archivos antiguos. Esto de alguna manera resolvió el problema.

No importa
fuente
Ésta no puede ser la respuesta. Otros han proporcionado razones mucho más claras para el problema y soluciones alternativas adecuadas que no requieren la creación de un nuevo archivo de solución, lo cual es inaceptable cuando se trabaja con el control de versiones porque se perdería el historial.
Bernhard Hofmann
Sí, esta es una mala respuesta. Otros son aún peores. Cambiar el nombre de los archivos de salida no es una solución, es una solución difícil de manejar. Si tiene mejores ideas, ¿por qué no publica una respuesta?
importa
Crear una nueva solución solo resolvió temporalmente el problema para mí. La mejor respuesta parece ser la de Vladimir Datsyuk.
user492238
1
¿Esta solución suya sería óptima si tiene como 15 proyectos en una solución?
Shittu Joseph Olugbenga