Pregunta

Por alguna razón, tenemos un script que crea archivos por lotes para XCOPY de nuestros ensamblados compilados, archivos de configuración y varios otros archivos en un recurso compartido de red para nuestros probadores beta. Tenemos un instalador, pero algunos no tienen los permisos necesarios para ejecutar el instalador, o se ejecutan sobre Citrix.

Si vomitó en todo su escritorio ante las menciones de XCOPY y Citrix, úselo como una excusa para irse a casa temprano. De nada.

El código actualmente tiene cientos de líneas como:

CreateScripts(basePath, "Client", outputDir, FileType.EXE | FileType.DLL | FileType.XML | FileType.CONFIG);

Solía ??ser peor, con 20 parámetros int (uno por tipo de archivo) que representan si copiar o no ese tipo de archivo en el directorio de salida.

Estos cientos de líneas crean archivos de carga / descarga por lotes con miles de líneas XCOPY. En nuestros proyectos de configuración, podemos hacer referencia a cosas como "Salida principal del cliente" y " Archivos de contenido del cliente " ;. Me encantaría poder hacerlo mediante programación desde un proyecto que no sea de configuración, pero estoy perdido.

Obviamente, MS lo hace, ya sea utilizando una API o analizando los archivos .csproj. ¿Cómo haría para hacer esto? Solo estoy buscando una manera de obtener una lista de archivos para cualquiera de las categorías de configuración, es decir:

  • Salida primaria
  • Recursos localizados
  • Archivos de contenido
  • Archivos de documentación

EDIT : Tengo un proyecto de instalación como Hath sugirió, y está a medio camino de lo que estoy buscando. El único problema para evitar que sea una solución perfecta es que varios proyectos dependen de que los mismos ensamblajes estén en su propia carpeta, y la configuración solo copiará el archivo una vez.

Ejemplo:

Los proyectos Administración, Cliente y Servidor se basan en ExceptionHandler.dll, y el Administrador y el Cliente dependen de Util.dll, mientras que el Servidor no. Esto es lo que estoy buscando:

  • administrador
    • Admin.exe
    • Admin.exe.config
    • ExceptionHandler.dll
    • Util.dll
  • cliente
    • Client.exe
    • Client.exe.config
    • ExceptionHandler.dll
    • Util.dll
  • servidor
    • Server.exe
    • Server.exe.config
    • ExceptionHandler.dll

Dado que los ensamblados a los que se hace referencia son todos iguales, lo que obtengo es esto:

  • administrador
    • Admin.exe
    • Admin.exe.config
    • ExceptionHandler.dll
    • Util.dll
  • cliente
    • Client.exe
    • Client.exe.config
  • servidor
    • Server.exe
    • Server.exe.config

Esto causa una excepción FileNotFoundException cuando el Cliente o el Servidor no pueden encontrar una de las dos DLL que está esperando.

¿Falta alguna propiedad de configuración para que siempre copie la salida, incluso si está duplicada en otro lugar en la salida de otro proyecto?

EDITAR DE NUEVO : todas las DLL a las que se hace referencia están configuradas en " Copiar Local " ;, y siempre lo han sido. Encontré un artículo decente sobre utilizando NAnt y XSLT para obtener la lista de archivos , así que puede ser una posible solución también, como sugirió neouser99.

SOLUCIÓN ACEPTADA : he vuelto prácticamente a donde empecé. Todas las salidas .exe y .dll se colocan en un "bin". Directorio en el proyecto de configuración, empaquetado libremente. Las otras carpetas por aplicación contienen accesos directos al ejecutable en ese directorio.

La diferencia ahora es que agregaré una acción personalizada al instalador para usar la reflexión, enumerar las dependencias para cada salida ejecutable y copiar los archivos .exe y .dll en los directorios separados. Poco doloroso, ya que supuse que había una manera de detectar mediante programación qué archivos se incluirían a través de alguna biblioteca de configuración.

¿Fue útil?

Solución

¿por qué no usar otro proyecto de configuración y simplemente establecer la configuración de 'Archivos de paquete' en Archivos sueltos sin compresión (propiedades del proyecto de configuración- >)? luego comparta la carpeta ... o algo así.

editar:

Ya veo, tienes 3 carpetas para tus salidas. pero el proyecto de instalación solo detecta ExceptionHandler.dll y Util.dll una vez, así que solo elegirá la primera carpeta y la colocará allí.

Podrías hacer un proyecto de configuración para cada proyecto, quizás un poco molesto ...

Puede agregar manualmente las dll a los proyectos a los que les falta el ensamblado ya sea agregando en el Archivo por 'agregar archivo' o 'agregar ensamblado' o 'agregar resultado de proyecto' si tiene esos proyectos en la misma solución ... (aunque dudo que ese sea el caso).

o simplemente volcarlos todos en un directorio de salida ...

Otros consejos

Aunque está diseñado como una herramienta de compilación, puede que NAnt sea extremadamente útil en lo que eres hablando sobre. Las tareas (compilación, copia, movimiento, eliminación, etc.) que puede definir permiten realizar búsquedas de archivos muy detalladas, hasta carpetas generales y completas. Si también incorporas NAnt en tu proceso de construcción, creo que podrías encontrar que te ayuda de más maneras que una.

Otro enfoque que me ha funcionado en el pasado es agregar el recurso compartido (ensamblado, DLL o proyecto) como referencia a cada uno de los proyectos de administración, servidor y cliente. Luego abra el panel de propiedades para el elemento referenciado en cada proyecto y configure "Copiar local". a verdadero.

Ahora, cuando construya los proyectos, cada uno tendrá su propia instancia del ensamblado copiado en su carpeta de salida.

Esto también debería hacer que los componentes compartidos agregados de esta manera se repliquen en cada una de las carpetas de salida en el paquete de instalación.

Un enfoque completamente diferente podría ser configurarlos como enlaces simbólicos en el recurso compartido de red. Un enlace simbólico es básicamente un atajo donde el sistema de archivos oculta el hecho de que es un atajo, por lo que todas las demás aplicaciones realmente creen que el archivo ha sido copiado ( http://en.wikipedia.org/wiki/NTFS_symbolic_link ).

Una ventaja de este enfoque es que el archivo se actualiza inmediatamente a medida que cambia el archivo y no solo cuando crea sus proyectos. Entonces, por ejemplo, cuando guarda uno de los archivos de configuración con un editor de texto, la actualización se aplica inmediatamente.

La siguiente parte del script MSBuild puede compilar su archivo SLN (puede reemplazarlo con .csproj) e informará una lista de todos los proyectos que fueron compilados (Dlls, EXEs).

 <MSBuild Projects="MySolution.sln" Targets="Clean; Rebuild" Properties="Configuration=$(BuildMode);">
    <Output TaskParameter="TargetOutputs"
                ItemName="AssembliesBuilt" />
    </MSBuild>

Ahora, esto realmente no resuelve tu problema, pero te da una lista de todo lo que se construyó. También tiene copylocal, por lo que probablemente podría tomar AssembiesBuild y copiar todos los archivos DLL y .CONFIG desde allí.

Ejemplo:

AssembliesBuild = c: \ myproj \ something1 \ build.dll

iría a c: \ myproj \ something1 \ y simplemente buscará todos los archivos * .dll y * .config e incluirlos. Puede hacerlo con bastante facilidad con MSBuild o powershell, si lo tiene instalado. Para generar una secuencia de comandos XCOPY de MSBuild, creo que necesitará tener instalado el proyecto de contribución de MSBuild.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top