.NET Referencia "Copia Local" Verdadero/Falso se establece según el contenido de GAC
assemblies reference (5)
¿Puede asegurarse de que la suya se usa agregando una hintpath de hintpath al archivo msbuild / proj?
Desde el enlace de arriba:
HintPath : Ruta relativa o absoluta del ensamblaje.
Tuvimos un problema muy interesante con un proyecto de Win Forms. Se ha resuelto Sabemos lo que pasó, pero queremos entender por qué sucedió. Esto puede ayudar a otras personas en el futuro que tengan un problema similar.
El proyecto WinForms falló en 2 de las PC de nuestros clientes. El error fue un error kernel.dll oscuro. El proyecto funcionó bien en otras 3 PC.
Encontramos que faltaba un archivo .DLL (log4net.dll - una biblioteca de registro de código abierto muy popular) en nuestra carpeta de lanzamiento. Estaba previamente en nuestra carpeta de lanzamiento. ¿Por qué faltaba en este último lanzamiento?
Faltaba porque debí haber instalado un programa en mi caja de Dev que usaba log4net.dll y se agregó a Global Assembly Cache.
Cuando verifiqué las referencias de la solución para log4net.dll, se cambiaron a "copiar local = FALSO". Deben haber cambiado automáticamente porque log4net.dll estaba presente en mi GAC.
Aquí es donde comienza mi pregunta:
¿Por qué mi referencia para log4net.dll se cambió de COPY LOCAL = TRUE a COPY LOCAL = FALSE? Sospecho que es porque fue agregado a mi GAC por otro programa.
¿Cómo podemos evitar que esto vuelva a suceder? Tal como está ahora, si instalo un software que usa una biblioteca común y lo agrega a mi GAC, entonces mis SLN que hacen referencia a esa DLL cambiarán de Copiar VERDADERO Local a FALSO.
Acabo de encontrar este problema en nuestros servidores de compilación también. Este es un comportamiento muy molesto (e inesperado) de Visual Studio. Dos soluciones:
- Retire los conjuntos de la GAC.
- Agregue un evento PostBuild para copiar manualmente los ensamblajes en el directorio de salida.
En el tiempo de ejecución, los ensamblajes deben estar en una de dos ubicaciones: la ruta de salida del proyecto o la caché de ensamblajes global (consulte Trabajar con ensamblajes y la caché de ensamblados global). Si el proyecto contiene una referencia a un objeto que no está en una de estas ubicaciones, entonces, cuando se construye el proyecto, la referencia debe copiarse en la ruta de salida del proyecto. La propiedad CopyLocal indica si esta copia debe realizarse. Si el valor es verdadero, se copia la referencia. Si es falso, la referencia no se copia.
El valor asignado por el proyecto de CopyLocal se determina en el siguiente orden:
- Si la referencia es otro proyecto, llamado referencia proyecto a proyecto, el valor es verdadero.
- Si el ensamblaje se encuentra en el caché de ensamblados global, el valor es falso.
- Como un caso especial, el valor para la referencia mscorlib.dll es falso.
- Si el ensamblaje se encuentra en la carpeta Framework SDK, el valor es falso. De lo contrario, el valor es verdadero.
Un saludo ... Muse VSExtensions
Encontré una solución para nosotros en nuestros servidores de compilación.
Problema: en una fecha específica sin motivo (ahora asumo que el archivo se agregó a la GAC), el conjunto System.Web.MVC.dll desapareció de muchos de nuestros proyectos. Estoy seguro de que esto se aplica a cualquier dll con el problema.
Solución: en Visual Studio, cambie la referencia (suponiendo que Copiar Local ya es Verdadero).
- Cambiar Copia Local = Cierto a Copiar Local = Falso
- Cambiar Copia Local Volver a Verdadero
- Observe que en el archivo .csproj se agrega
<Private>True</Private>
. - Compile ahora y verá que la dll sí se incluye aunque el mensaje sigue siendo el mismo.
Solución 2: Agregue la propiedad <private>True</private>
manualmente.
Conclusiones: Mi entendimiento de <Private>
es que es Copia local, por lo tanto, si Copia Local = Verdadera se debe agregar la propiedad privada, pero en nuestro caso al menos no lo fue.
Consideraciones adicionales:
- Probado utilizando Visual Studio 2013 y 2015.
- Probado utilizando msbuild 12 y 14.
- Probado utilizando TFS build Template.
- Nuestro código se ha actualizado del estudio visual de 2008 a 2015, es posible que la bandera se haya estropeado en algún momento de ese tiempo, pero el problema no comenzó hasta que el ensamblado se agregó al GAC de alguna manera.
Resultado final:
<Reference Include="System.Web.Mvc, Version=4.0.0.1, Culture=neutral,PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>packages/Microsoft.AspNet.Mvc.4.0.40804.0/lib/net40/System.Web.Mvc.dll </HintPath>
<Private>True</Private>
</Reference>
Eso sucedió porque no tiene sentido tener Copia Local = Verdadero si se instala un ensamblaje en la GAC. Debido a que esa copia local nunca se utilizará, la GAC siempre se busca primero. Si lo deja sin cambiar, causaría una gran confusión, usted pensaría que está utilizando la copia local, pero en lugar de eso obtendrá otra. Cambiarlo también causa una confusión, si no lo nota, tal vez podría haberse solucionado con un cuadro de mensaje en el momento de carga de la solución.
Log4net es un alborotador, hay demasiadas versiones en la naturaleza sin ningún procedimiento de implementación que garantice que esas versiones no se mordan entre sí. Algo que Apache aparentemente no quería abordar, dejándolo en manos del programador. Tener productos que dependan de Log4net y hacer algo respecto a la percepción del riesgo del infierno es algo inevitable. Dándole un problema de infierno DLL a cambio.
No hay respuestas simples y claras, más allá de saber lo que está instalado en su máquina. Considere publicar en connect.microsoft.com para solicitar una advertencia cuando Visual Studio actualice automáticamente la propiedad Copiar local. Es una pregunta razonable.