c# - supero - Visual Studio no copia los archivos de contenido del proyecto de referencia indirecta
no se puede quitar el directorio bin debug app publish (4)
Agregue la referencia de Library1 al proyecto ejecutable.
Tengo la siguiente estructura de proyecto:
Library1 <--[project reference]-- Library2 <--[ref]-- Executable
-------- -------- ----------
ContentFile .cs files .cs files
.cs files
Todas las referencias del proyecto tienen CopyLocal = true.
Cuando ContentFile
el proyecto, ContentFile
se copia en el directorio de salida de ContentFile
, pero no en el directorio de salida de Executable
, lo que significa que falta el archivo ContentFile
cuando se ejecuta la aplicación.
¿Por qué el archivo de contenido se copia en el directorio de salida de Library2, pero no en el de Executable
? ¿Hay alguna forma de copiarlo también al último (me gustaría hacerlo sin compilar eventos porque estoy seguro de que la gente lo olvidará)?
Estoy buscando una solución razonable y mantenible ; uno que requiera un esfuerzo mínimo al agregar nuevos proyectos o nuevos archivos de contenido de referencia indirecta, de modo que sea tan improbable como sea posible que simplemente se olvide de hacerlo.
Uso de eventos posteriores a la compilación (como xcopy ../Library/bin/Debug/SomeDll.dll bin/Debug
); y la configuración manual del directorio de salida de los proyectos en $(SolutionDir)/bin/...
lugar del valor predeterminado (por proyecto), se han convertido rápidamente en un gran desastre. Agregar los archivos de contenido como enlaces en el "proyecto principal" también fue demasiado tedioso. Estaría bien si C # tuviera la misma configuración predeterminada para el archivo de salida que Visual C ++ (es decir, $SolutionDir/$Platform/$Configuration
), pero no es así.
También consideré no usar el procedimiento estándar de MSBuild y escribir un objetivo de compilación personalizado (como usar gcc en Atmel Studio), pero no llegué muy lejos. Además, quiero que los comandos estándar de "compilación" y "depuración" de Visual Studio funcionen como lo hacen normalmente.
ACTUALIZAR:
Aquí hay más detalles sobre lo que estoy haciendo.
Tengo una solución con un proyecto Executable
. Además, hay un montón de proyectos que podrías llamar Plugin
s. Executable
referencia a todos esos Plugin
a través de una referencia de proyecto administrado.
Dado que los proyectos de complementos se adaptan al ejecutable, pero pueden tener componentes reutilizables, la funcionalidad principal a menudo se implementa en un proyecto External
, dejando el proyecto de Plugin
como un simple envoltorio (aunque no siempre es así).
Dichos proyectos External
veces usan DLL nativos proporcionados por terceros. Esos archivos DLL se agregan al proyecto External
como un archivo de contenido y tienen Copy to output dir
configurado en Copy always
. Así que la estructura se parece al diagrama de arriba:
External <---------------[is not aware of]--------------------+
-------- |
.cs files <--[reference]-- PluginWrapper <--[reference]-- Executable
"Native DLL" ------------- ----------
.cs files .cs files
Lo extraño es que la "DLL nativa" se copia al directorio de salida de External
(obviamente), así como a PluginWrapper
, pero no a Executable
.
El flujo de trabajo del desarrollador sería escribir un External
que funcione como una entidad completamente aislada (se están reutilizando muy a menudo), envolverlo con un PluginWrapper
y luego solo agregar una referencia del proyecto al PluginWrapper
al Executable
. Me parece extraño que esto sea aparentemente una cosa tan poco común de hacer.
Pensé que tal vez la edición del XML objetivo de MSBuild de Executable
(para incluir también archivos de contenido de referencia indirecta) podría haber solucionado el problema.
Es posible que desee considerar agregar los DLL a los proyectos como recursos incrustados como se sugiere, pero incrustar DLL nativos como eso me parece extraño. Al final, cambiar el flujo de trabajo del desarrollador eliminando ''[no tiene conocimiento de]'' del diagrama anterior y agregar una referencia del proyecto a External
, como sugirió Brenda Bell, podría ser la solución más sensata, aunque no sea la ideal.
Actualización 2
Tenga en cuenta que la idea de recursos incrustados puede no funcionar en todos los casos. Si es necesario colocar una dependencia en el directorio del ejecutable (no cwd ni nada), es posible que esto no funcione debido a la falta de privilegios de administrador en la carpeta de instalación (para desempaquetar el archivo del recurso incrustado). Suena raro, pero este fue un problema grave con una de las bibliotecas de terceros que estábamos usando.
EDITAR:
Puede colocar todo el contenido en un proyecto separado, establecer todas sus entradas en "contenido" y "copiar siempre" y hacer referencia a ese proyecto desde Externo y Ejecutable
-
En mi opinión, está buscando un recurso incorporado, no archivos de contenido.
Cuando compila la Biblioteca 1, los archivos de contenido se colocan en su carpeta bin. Cuando se compila la Biblioteca 2, el compilador reconoce el código de referencia y lo incluye (Library 1.dll), pero los archivos de contenido no se reconocen ya que no se mencionan en ninguna parte de la Biblioteca 2. Lo mismo ocurre cuando se vincula la Biblioteca 2 con el ejecutable.
Si sus archivos de contenido son relativamente pequeños (íconos, plantillas, etc.) y no prevé que deba editarlos si pierde el código fuente, puede incrustarlos como recursos y proporcionar un método público para devolver los contenidos, como :
public static Stream GetResourceContent(string rName){
string resName = System.Reflection.Assembly
.GetExecutingAssembly().GetManifestResourceNames()
.FirstOrDefault(rn => rn.EndsWith("."+rName));
if(resName!=null)
return System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(resName);
else
return null;
}
Si su contenido está obligado a cambiar, como plantillas, etc., considere incluir una copia con el proyecto ejecutable
Otra opción sería incrustar ContentFile como un recurso dentro del ensamblaje de Library1 y extraerlo utilizando Assembly.GetManifestResource ().
Vea estos enlaces para más información:
http://www.attilan.com/2006/08/accessing-embedded-resources-using.html
Una variante de la respuesta de Brenda sería agregar el (los) archivo (s) de contenido de Library1 como enlace (s) en el proyecto ejecutable. Todavía tendría las entradas en el proyecto pero no necesitaría administrar varias copias de cada archivo.