Mejores prácticas de ILMerge

¿Usas ILMerge? ¿Utiliza ILMerge para fusionar varios ensambles para facilitar el despliegue de dll? ¿Ha encontrado problemas con la implementación / versiones en producción después de ensamblar ILMerging juntos?

Estoy buscando algunos consejos con respecto al uso de ILMerge para reducir la fricción de la implementación, si eso es posible.

Uso ILMerge para casi todas mis diferentes aplicaciones. Lo he integrado directamente en el proceso de comstackción de lanzamiento, así que lo que obtengo es un exe por aplicación sin dll’s adicionales.

No puede ILMerge ningún ensamblado en C ++ que tenga código nativo. Tampoco puedes ILMerge ningún ensamblado que contenga XAML para WPF (al menos no he tenido éxito con eso). Se queja en tiempo de ejecución de que los recursos no pueden ser ubicados.

Escribí un ejecutable contenedor para ILMerge donde paso el nombre del archivo ejecutable del proyecto que quiero fusionar, y un nombre de archivo de salida, y luego refleja los ensamblados dependientes y llama a ILMerge con los parámetros de línea de comando apropiados. Ahora es mucho más fácil cuando agrego nuevos ensambles al proyecto, no tengo que recordar actualizar el script de comstackción.

Introducción

Esta publicación muestra cómo reemplazar todos los .exe + .dll files con un único combined .exe . También mantiene intacto el archivo .pdb depuración.

Para aplicaciones de consola

Aquí está la Post Build String básica Post Build String para Visual Studio 2010 SP1, que usa .NET 4.0. Estoy construyendo un .exe de consola con todos los archivos sub-.dll incluidos en él.

 "$(SolutionDir)ILMerge\ILMerge.exe" /out:"$(TargetDir)$(TargetName).all.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll" /target:exe /targetplatform:v4,C:\Windows\Microsoft.NET\Framework64\v4.0.30319 /wildcards 

Indicaciones básicas

  • El resultado es un archivo ” AssemblyName.all.exe ” que combina todos los sub-dlls en un .exe.
  • Observe el directorio ILMerge\ . Debe copiar la utilidad ILMerge en el directorio de la solución (para poder distribuir la fuente sin tener que preocuparse de documentar la instalación de ILMerge), o cambie esta ruta para indicar dónde reside ILMerge.exe.

Consejos avanzados

Si tiene problemas para que no funcione, active Output y seleccione Show output from: Build . Compruebe el comando exacto que realmente generó Visual Studio y verifique si hay errores.

Script de creación de muestra

Este script reemplaza todos los .exe + .dll files con un solo combined .exe . También mantiene intacto el archivo .pdb de depuración.

Para usar, pégalo en tu paso de Post Build , en la pestaña Build Events en un proyecto de C #, y asegúrate de ajustar la ruta en la primera línea para que apunte a ILMerge.exe :

 rem Create a single .exe that combines the root .exe and all subassemblies. "$(SolutionDir)ILMerge\ILMerge.exe" /out:"$(TargetDir)$(TargetName).all.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll" /target:exe /targetplatform:v4,C:\Windows\Microsoft.NET\Framework64\v4.0.30319 /wildcards rem Remove all subassemblies. del *.dll rem Remove all .pdb files (except the new, combined pdb we just created). ren "$(TargetDir)$(TargetName).all.pdb" "$(TargetName).all.pdb.temp" del *.pdb ren "$(TargetDir)$(TargetName).all.pdb.temp" "$(TargetName).all.pdb" rem Delete the original, non-combined .exe. del "$(TargetDir)$(TargetName).exe" rem Rename the combined .exe and .pdb to the original project name we started with. ren "$(TargetDir)$(TargetName).all.pdb" "$(TargetName).pdb" ren "$(TargetDir)$(TargetName).all.exe" "$(TargetName).exe" exit 0 

Utilizamos ILMerge en los bloques de aplicaciones de Microsoft: en lugar de 12 archivos DLL separados, tenemos un solo archivo que podemos cargar en nuestras áreas de clientes, además de que la estructura del sistema de archivos es mucho más ordenada.

Después de fusionar los archivos, tuve que editar la lista de proyectos de Visual Studio, eliminar los 12 archivos asspeblies separados y agregar el archivo único como referencia, de lo contrario, se quejaría de que no podía encontrar el ensamblado específico. Sin embargo, no estoy seguro de cómo esto funcionaría en la implementación posterior, podría valer la pena intentarlo.

Sé que esta es una vieja pregunta, pero no solo utilizamos ILMerge para reducir el número de dependencias sino también para internalizar las dependencias “internas” (por ejemplo, automapper, restsharp, etc.) que utiliza la utilidad. Esto significa que están completamente abstraídos, y el proyecto que usa la utilidad combinada no necesita saber sobre ellos. Esto nuevamente reduce las referencias requeridas en el proyecto y le permite usar / actualizar su propia versión de la misma biblioteca externa si es necesario.

Usamos ILMerge en bastantes proyectos. La fábrica de software de servicios web , por ejemplo, produce algo así como 8 ensamblajes como salida. Combinamos todas esas DLL en una sola DLL para que el servidor de servicio solo tenga que hacer referencia a una DLL.

Hace la vida un poco más fácil, pero tampoco es gran cosa.

Tuvimos el mismo problema al combinar dependencias WPF … ILMerge no parece tratar con estos. Costura.Fody funcionó perfectamente para nosotros, sin embargo, tomó aproximadamente 5 minutos para ponerse en marcha … una muy buena experiencia.

Simplemente instale con Nuget (seleccionando el proyecto predeterminado correcto en la consola de Package Manager). Se introduce en el proyecto de destino y la configuración predeterminada funcionó de inmediato para nosotros.

Combina todas las DLL marcadas como “Copiar local” = verdadero y produce un .EXE fusionado (junto con la salida estándar), que está muy bien comprimido en tamaño (mucho menos que el tamaño de salida total).

La licencia es MIT, por lo que puede modificar / distribuir según sea necesario.

https://github.com/Fody/Costura/

Tenga en cuenta que para los progtwigs de GUI de Windows (por ejemplo, WinForms) querrá usar el modificador / target: winexe .
El modificador / target: exe crea una aplicación de consola fusionada.

Nos encontramos con problemas al fusionar archivos DLL que tienen recursos en el mismo espacio de nombres. En el proceso de fusión, se renombró uno de los espacios de nombres de recursos y, por lo tanto, no se pudieron ubicar los recursos. Tal vez solo estamos haciendo algo mal allí, aún estamos investigando el problema.

Recién comenzamos a usar ILMerge en nuestras soluciones que se redistribuyen y utilizan en nuestros otros proyectos y hasta ahora todo bien. Todo parece funcionar bien. Incluso ofuscamos el ensamblaje empaquetado directamente.

Estamos considerando hacer lo mismo con los ensamblajes de MS Enterprise Library.

El único problema real que veo con él es la versión de ensambles individuales del paquete.

Hace poco tuve problemas con el ensamblaje de la lámpara en el ensamblaje. Tuve algunas clases a las que se llamaba mediante reflexión en Umbraco opensource CMS.

La información para realizar la llamada a través de la reflexión se tomó de la tabla db que tenía el nombre del ensamblado y el espacio de nombres de la clase que se implementó e interconectó. El problema era que la llamada a la reflexión fallaría cuando dll se fusionara; sin embargo, si dll estuviera separado, todo funcionó bien. Creo que el problema puede ser similar al que Longeasy está teniendo?

Estoy empezando a utilizar ILMerge como parte de mi comstackción CI para combinar muchos contratos de WCF finamente granulares en una sola biblioteca. Funciona muy bien, sin embargo, la nueva biblioteca combinada no puede coexistir fácilmente con sus bibliotecas de componentes u otras bibliotecas que dependen de esas bibliotecas de componentes.

Si, en un proyecto nuevo, hace referencia tanto a su biblioteca ILMerged como a una biblioteca heredada que depende de una de las entradas que le proporcionó a ILMerge, encontrará que no puede pasar ningún tipo de la biblioteca ILMerged a ningún método en la biblioteca heredada sin hacer algún tipo de mapeo de tipo (p. ej., automapper o mapeo manual). Esto se debe a que una vez que se comstack todo, los tipos se califican de manera efectiva con un nombre de conjunto.

Los nombres también colisionarán, pero puedes arreglar eso usando alias extern .

Mi consejo sería evitar incluir en su ensamblado fusionado cualquier lib disponible públicamente que exponga su ensamblado fusionado (por ejemplo, a través de un tipo de devolución, método / parámetro constructor, campo, propiedad, genérico …) a menos que sepa con certeza que el usuario de su ensamblado fusionado no depende ni nunca dependerá de la versión autónoma de la misma biblioteca.

Me parece que la mejor práctica de ILMerge n. ° 1 es Do not Use ILMerge. En su lugar, use SmartAssembly . Una razón para esto es que la mejor práctica de ILMerge n. ° 2 es ejecutar siempre PEVerify después de realizar una ILMerge, porque ILMerge no garantiza que fusione ensamblajes correctamente en un ejecutable válido.

Otras desventajas de ILMerge:

  • cuando se fusiona, elimina XML Comments (si me preocupaba por esto, usaría una herramienta de ofuscación)
  • no maneja correctamente la creación de un archivo .pdb correspondiente

Otra herramienta a la que vale la pena prestarle atención es Mono.Cecil y la herramienta Mono.Linker [2].

[2]: http: // http://www.mono-project.com/Linker