2010-06-22 16 views
20

Tengo un proyecto de Visual Studio 2008 que "actualicé" a Visual Studio 2010. Desde la actualización he tenido muchos problemas con el proyecto (un proyecto que fue y sigue siendo trooper en 2008 podría agregar).Problema de bloqueo de archivos de compilación de Visual Studio 2010

El primer problema es que al crear el ejecutable principal se bloquea el ejecutable, lo que hace que las reconstrucciones posteriores fallen. Esto se describe en una pregunta relacionada: Visual Studio locks output file on build donde recogí la solución:

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

Excepto que esta solución funciona exactamente vez. El archivo .locked también es bloqueado por devenv.exe y debe ser movido. He estado trabajando alrededor de esto agregando .1.locked, .2.locked, etc. La única vez que se quitan los bloqueos para que los archivos puedan ser borrados está en el apagado de devenv.exe (tarda unos segundos después la interfaz de usuario desaparece, luego los archivos se pueden eliminar).

El hecho de que el depurador no tiene que ser utilizado para causar este problema apunta a un problema bastante grave con el sistema de compilación 2010.

Algunas teorías creo que puedo descontar:

  • antivirus u otras tareas de fondo: si esto era un problema parecería 2008 sería un fracaso. Sin embargo, al ser un complemento, eliminé el avast! sistema completamente sin suerte.

ACTUALIZACIÓN: Este proyecto tiene los mismos síntomas en una máquina sin antivirus ni utilidad de copia de seguridad. Las máquinas en la oficina ejecutan XP SP3 32 bits, mi máquina local es Windows 7 de 64 bits. Esto parece ser independiente del sistema operativo.

  • El depurador está bloqueando el archivo: todo lo que se necesita para reproducir esto es repetir el proceso de compilación sin depuración. ProcessExplorer muestra que devenv.exe es el titular de los bloqueos, no vshost y que el vshost.exe no elimina los bloqueos de todos modos.

Tengo un problema secundario que comienza a ocurrir una vez que los archivos se bloquean: los diseñadores de formularios dejan de cargar con un error de "no se puede encontrar el ensamblaje". Sospecho que están relacionados con el problema de bloqueo anterior, ya que los diseñadores dispararon hasta anterior a una compilación, pero realizar cualquier cambio y reconstrucción hará colapsar a todos los diseñadores con ese error (incluso los que tengo abiertos y como la vista actual))

Es lamentable ver un formulario cerca de la pantalla de error blanco simplemente porque ha cambiado "dummy = 1" a "dummy = 2" donde "dummy" no hace más que forzar una recompilación en un ensamblado completamente diferente.

Actualización: He intentado algunos remedios más: Habilitar el paso de la fuente .NET no está marcado, por lo que ese no es el problema. La eliminación de .SUO (opciones de usuario de solución) simplemente funciona durante el tiempo que un reinicio normalmente eliminaría el problema (dos compilaciones: la primera porque no hay un archivo bloqueado y la segunda porque hay una, pero el script puede cambiarle el nombre))

Error 28 Unable to copy file "obj\Debug\PolicyTracker3.exe" to "bin\Debug\PolicyTracker3.exe". 
The process cannot access the file 'bin\Debug\PolicyTracker3.exe' because it is being used by another process. 
+0

¿Alguna vez resolvió esto? –

+0

En cuanto a la información en la única respuesta que obtuve aquí en SO, la característica mencionada (origen de .NET framework) no está habilitada y nunca fue habilitada. – Godeke

+0

Para el registro, también estoy recibiendo este problema, y ​​la solución también es una convertida desde 2008, así que tal vez eso tiene algo que ver con eso. No entiendo los problemas del diseñador de formularios, pero todo lo demás es casi exactamente como usted lo describe. –

Respuesta

15

Hasta que llegue un parche para esto, tengo la siguiente solución. Simplemente llame usando algo como "C:\MyBin\VisualStudioLockWorkaround.exe" "$(TargetPath)" (reemplazando MyBin con la ubicación donde coloca el ejecutable).

Cree esto como una aplicación de consola C# y se utiliza en la sección Preconstrucción de la misma manera que el renombrado previo a la compilación original (consulte la parte superior de la pregunta original para obtener más información).

using System; 
using System.IO; 

namespace VisualStudioLockWorkaround 
{ 
    class Program 
    { 
    static void Main(string[] args) 
    { 
    string file = args[0]; 
    string fileName = Path.GetFileName(file); 
    string directory = Path.GetDirectoryName(args[0]); 
    if (!Directory.Exists(directory)) //If we don't have a folder, nothing to do. 
    { 
    Console.WriteLine(String.Format("Folder {0} not found. Exiting.", directory)); 
    return; 
    } 
    if (!File.Exists(file)) //If the offending executable is missing, no reason to remove the locked files. 
    { 
    Console.WriteLine(String.Format("File {0} not found. Exiting.", file)); 
    return; 
    } 
    foreach (string lockedFile in Directory.EnumerateFiles(directory, "*.locked")) 
    { 
    try //We know IOExceptions will occur due to the locking bug. 
    { 
     File.Delete(lockedFile); 
    } 
    catch (IOException) 
    { 
     //Nothing to do, just absorbing the IO error. 
    } 
    catch (UnauthorizedAccessException) 
    { 
     //Nothing to do, just absorbing the IO error. 
    }           
    } 

    //Rename the executable to a .locked 
    File.Move(file, Path.Combine(directory, String.Format("{0}{1:ddmmyyhhmmss}.locked", fileName, DateTime.Now))); 
    } 
    } 
} 
+0

Revisado para incluir la excepción de acceso no autorizado. ¿Curioso si esto es exactamente lo que arroja un archivo bloqueado (obviamente estaba esperando la IOException en su lugar) o si apunta a parte del problema? – Godeke

+0

Super excelente respuesta –

3

Existe un error conocido de fuga de identificador de archivo en la característica de paso a nivel de origen de .NET Framework. Fácil de evitar desactivando la opción en Herramientas + Opciones + Depurador. Sin embargo, es poco probable que sea su problema si nunca tiene el depurador funcionando.

No está claro por qué Visual Studio estaría interesado en absoluto en el resultado de compilación, y mucho menos cargarlo y bloquearlo. ¿Quizás abriste el .exe una vez? Elimine el archivo oculto .suo en el directorio de la solución para estar seguro. No hay ningún informe de comentarios sobre connect.microsoft.com que coincida con su problema, le recomiendo que inicie el suyo propio. Necesitarán algo reproducible para que lo echen un vistazo, asegúrese de incluir un proyecto de muestra que muestre este comportamiento.

+0

¿Tiene alguna referencia al problema de escalonamiento de origen? Encontré referencia con respecto a 2008, pero afirman que se corrigió en 2010 (lo que sería exactamente al revés de mi experiencia). No es que sea la principal preocupación con el problema de compilación, pero tengo curiosidad por los detalles. – Godeke

+0

Lo encontré al navegar los informes de conexión. Fue un problema de 2010. Desde que perdí el enlace, estoy seguro de que puedes encontrarlo de nuevo. –

+0

Por extraño que parezca, nuking del archivo .suo parece haber hecho algún tipo de diferencia. Voy a suponer que la conversión lo corrompió de alguna manera (aunque esperaba que se eliminara para ser honesto en la conversión). – Godeke

2

Desafortunadamente, cambiar de nombre/mover el archivo bloqueado no funcionó para mí (los identificadores se abrieron solo con FILE_SHARE_READ), pero lo que funcionó fue matar esos identificadores (presumiblemente filtrados) en el proceso de Visual Studio. Puede usar KillHandle para automatizar este paso.

+0

KillHandle no funcionó para mí. Imprimió "KillHandle: Killed handle 0x000036F0 en proceso 0x00000060" pero VS todavía tenía el archivo bloqueado. – serg

1

En mi caso, tengo una versión altamente personalizada para una extensión en Visual Studio 2010 que funcionó sin problemas en Visual Studio 2008. En un punto de la compilación, algunos ensambles de salida se cargan en un dominio de aplicación separado para generación de documentación y luego el dominio descargado. La descarga del dominio funcionaba correctamente y se confirmó inspeccionando la lista de dominios de la aplicación antes y después.

Visual Studio 2010 parece contener bloqueos de identificador de archivo en cualquier ensamblado cargado con las API Assembly.Load * basadas en archivos que operan en los identificadores o rutas de archivos. Pude ver que el identificador del archivo aparece en ProcessExplorer tan pronto como se ejecutó Assembly.Load, y el identificador nunca se lanzó, incluso después de que se descargó el AppDomain.

Pude solucionar el problema cargando los bytes del ensamblado sin procesar utilizando FileStream y la sobrecarga de Assembly.Load de byte [].

0

Llego un poco tarde a la fiesta, pero este problema se produjo por primera vez después de actualizar a VS2015. ¡Nunca sucedió con VS2010!

Desarrollamos frecuentemente con varias instancias de VS abiertas al mismo tiempo, es una aplicación cliente/servidor y estamos haciendo cambios en ambas capas simultáneamente.

Después de actualizar a VS2015, las dos instancias de VS se "bloquearían entre sí" de obj \ Debug y una instancia terminaría no pudiendo construir los proyectos comunes ("compartidos"), es decir, nuestro DTO, entidad proyectos marco.

Probé el script de precompilación y funcionó en alguna ocasión. Simplemente no era confiable para nuestro caso: a veces el dll estaba tan bloqueado que ni siquiera podía renombrarse/moverse.

Terminé simplemente usando diferentes configuraciones de compilación de soluciones para cada solución (copiadas de Debug). Esto creó nuevos directorios específicos de obj y bin de solución y evitó por completo la disputa sobre dlls correspondientes a proyectos comunes.

Espero que esto ayude a alguien más.

Cuestiones relacionadas