La DLL dependiente no se copia a la carpeta de salida de comstackción en Visual Studio

Tengo una solución de estudio visual. Tengo muchos proyectos en la solución. Hay un proyecto principal que actúa como inicio y usa otros proyectos. Hay un proyecto que dice “ProyectoX”. Su referencia se agrega al proyecto principal. El ProjectX hace referencia a otro DLL .NET (digamos abc.dll) que no es parte de la solución.

Ahora, este archivo abc.dll debe copiarse en la carpeta bin / debug del proyecto principal, pero no se copiará allí. ¿Por qué no se copia, alguna razón conocida?

Encontré que si ProjectX hacía referencia al abc.dll pero no usaba directamente ninguno de los tipos DEFINED en abc.dll, entonces abc.dll NO se copiaría a la carpeta de salida principal. (Se copiaría en la carpeta de salida de ProjectX, para hacerlo más confuso).

Por lo tanto, si no está utilizando explícitamente ninguno de los tipos de abc.dll en ninguna parte de ProjectX, coloque una statement ficticia en algún lugar de uno de los archivos en ProjectX.

AbcDll.AnyClass dummy006; // this will be enough to cause the DLL to be copied 

No necesita hacer esto para cada clase, solo una vez será suficiente para hacer que la copia DLL y todo funcione como se espera.

Adición: tenga en cuenta que esto puede funcionar para el modo de depuración, pero NO para la versión. Ver la respuesta de @nvirth para más detalles.

Sí, deberá configurar Copy Local en true . Sin embargo, estoy bastante seguro de que también deberá hacer referencia a ese ensamblaje desde el proyecto principal y también establecer Copy Local en true – no solo se copiará de un ensamblaje dependiente.

Puede acceder a la propiedad Copy Local haciendo clic en el conjunto debajo de References y presionando F4.

Solo una nota al margen de la respuesta de Overlord Zurg.

He agregado la referencia ficticia de esta manera, y funcionó en el modo de depuración:

 public class DummyClass { private static void Dummy() { var dummy = typeof(AbcDll.AnyClass); } } 

Pero en el modo Release, el dll dependiente aún no se copió.
Esto funcionó sin embargo:

 public class DummyClass { private static void Dummy() { Action noop = _ => {}; var dummy = typeof(AbcDll.AnyClass); noop(dummy); } } 

Esta información en realidad me costó horas averiguarlo, así que pensé en compartirla.

Se ve bien cuando lo convierte en un atributo de ensamblaje

 [AttributeUsage(AttributeTargets.Assembly)] public class ForceAssemblyReference: Attribute { public ForceAssemblyReference(Type forcedType) { //not sure if these two lines are required since //the type is passed to constructor as parameter, //thus effectively being used Action noop = _ => { }; noop(forcedType); } } 

El uso será:

 [assembly: ForceAssemblyReference(typeof(AbcDll.AnyClass))] 

Se encontró con este mismo problema. Información general: antes de construir, había agregado un nuevo Proyecto X a la solución. El Proyecto Y dependía del Proyecto X y el Proyecto A, B, C dependía del Proyecto Y.

Los errores de comstackción se debieron a que no se encontraron los dlls del Proyecto A, B, C, Y y X.

La causa principal fue que el Proyecto X creado recientemente se enfocó en .NET 4.5, mientras que el rest de los proyectos de solución se enfocaron en .NET 4.5.1. El proyecto X no se compiló, lo que provocó que el rest de los proyectos tampoco se construyeran.

Asegúrese de que los proyectos recién agregados estén orientados a la misma versión de .NET que el rest de la solución.

No estoy seguro de si esto ayuda, pero para mí, muchas veces hago referencia a un archivo DLL (que automáticamente lo agrega a la carpeta bin por supuesto). Sin embargo, esa DLL podría necesitar DLL adicionales (dependiendo de qué funciones estoy usando). NO quiero hacer referencia a los de mi Proyecto porque simplemente necesitan terminar en la misma carpeta que el DLL que estoy usando.

Lo logro en Visual Studio “Agregar un archivo existente”. Debería poder agregarlo en cualquier lugar excepto en la carpeta Add_data. personalmente, simplemente lo agrego a la raíz.

Luego cambie las propiedades de ese archivo a …

Build Action = None (teniendo esto configurado como algo como Content, en realidad copia la versión “raíz” a la raíz, más una copia en el contenedor).

Copiar a la carpeta de salida = Copiar si es más nuevo (Básicamente lo coloca en la carpeta BIN solo si falta, pero no lo hace después de eso)

Cuando publico … mi DLL agregada solo existe en la carpeta BIN y en ningún otro lugar en la ubicación de publicación (que es lo que quiero).

También puede verificar para asegurarse de que las DLL que está buscando no están incluidas en el GAC. Creo que Visual Studio es inteligente al no copiar esos archivos si ya existe en el GAC en la máquina de comstackción.

Recientemente corrí en esta situación en la que había estado probando un paquete SSIS que necesitaba ensamblajes para existir en el GAC. Desde entonces, lo había olvidado y me preguntaba por qué esos archivos DLL no aparecían durante una comstackción.

Para comprobar lo que hay en el GAC (desde un símbolo del sistema de Visual Studio Developer):

 gacutil -l 

O envíe a un archivo para que sea más fácil de leer:

 gacutil -l > output.txt notepad.exe output.txt 

Para eliminar un conjunto:

 gacutil -u MyProjectAssemblyName 

También debo señalar que, una vez que eliminé los archivos del GAC, se publicaron correctamente en el directorio \ bin después de una comstackción (incluso para los ensamblados a los que no se hizo referencia directamente en el proyecto raíz). Esto fue en Visual Studio 2013 Update 5.

Si hace clic con el botón derecho en el conjunto al que se hace referencia, verá una propiedad llamada Copiar local . Si Copiar local se establece en verdadero, entonces el conjunto debe incluirse en el contenedor. Sin embargo , parece que hay un problema con Visual Studio, que a veces no incluye el dll referenciado en la carpeta bin … esta es la solución que funcionó para mí:

enter image description here

Este es un pequeño cambio en el ejemplo de nvirth

 internal class DummyClass { private static void Dummy() { Noop(typeof(AbcDll.AnyClass)); } private static void Noop(Type _) { } } 

Puede establecer tanto el proyecto principal como la ruta de salida de construcción de ProjectX en la misma carpeta, luego puede obtener todos los dlls que necesita en esa carpeta.

Asegúrese de que el dll dependiente utilizado por usted no tenga el .net framework de destino más alto que el framework .net de destino de la Aplicación de su proyecto.

Puede verificar esto seleccionando su proyecto, luego presione ALT + ENTRAR, luego seleccione Aplicación desde el lado izquierdo y luego seleccione Marco objective de su proyecto.

Supongamos que, dll dependiente Target Framework = 4.0 y Application dll Target Framework = 3.5, entonces cambie esto a 4.0

¡Gracias!

Aparte de los comunes anteriores, tenía una solución multiproyecto para publicar. Aparentemente, algunos archivos se dirigen a diferentes marcos.

Entonces mi solución: Propiedades> Versión específica (False)

SIN NECESIDAD DE DUMMY EN EL CÓDIGO
Sólo :

agregar una referencia al proyecto ejecutable

y / y asegurar que la referencia en el proyecto ejecutable tenga "Copy Local" establecido en TRUE (que fue mi ” falla “) parece que esto “sobrescribió” la configuración en el proyecto de biblioteca de referencia base …

Agregue el archivo DLL como un elemento existente a uno de los proyectos y se debe ordenar

Lo agregaría a los eventos Postbuild para copiar las bibliotecas necesarias a los directorios de salida. Algo así como XCopy pathtolibraries targetdirectory

Puede encontrarlos en las propiedades del proyecto -> Eventos de comstackción.

En mi caso, fue lo más estúpido, causado por un comportamiento predeterminado de TFS / VS con el que estoy en desacuerdo.

Debido a que no fue posible agregar el dll como referencia al proyecto principal, decidí agregarlo como un “Artículo existente”, con Copiar local = Siempre. Incluso entonces el archivo no estaba allí.

Resulta que, aunque el archivo está presente en la Solución VS y todo lo comstackdo tanto localmente como en el servidor, VS / TFS no agregó realmente agrega el archivo al control de fuente. No fue incluido en los “Cambios Pendientes” en absoluto. Tuve que ir manualmente al Source Control Explorer y hacer clic explícitamente en el icono “Agregar elementos a la carpeta”.

Estúpido porque he estado desarrollando durante 15 años en VS. Me he encontrado con esto antes, simplemente no lo recuerdo y de alguna manera me lo perdí porque todo se compiló porque el archivo era una referencia regular, pero el archivo que se agregó como elemento existente no se copió porque no existía en el servidor de control de fuente.

Espero que esto le ahorre a alguien algo de tiempo, ya que perdí 2 días de mi vida por esto.