Question

Utilisez-vous ILMerge ?Utilisez-vous ILMerge pour fusionner plusieurs assemblys afin de faciliter le déploiement de DLL ?Avez-vous rencontré des problèmes de déploiement/de gestion des versions en production après la fusion des assemblys ILMerging ?

Je recherche des conseils sur l'utilisation d'ILMerge pour réduire les frictions de déploiement, si cela est même possible.

Était-ce utile?

La solution

J'utilise ILMerge pour presque toutes mes différentes applications.Je l'ai intégré directement dans le processus de construction de la version, donc je me retrouve avec un exe par application sans DLL supplémentaires.

Vous ne pouvez pas fusionner des assemblys C++ contenant du code natif.Vous ne pouvez pas non plus fusionner par ILMerge des assemblys contenant du XAML pour WPF (du moins, je n’ai pas eu de succès avec cela).Il se plaint au moment de l'exécution que les ressources ne peuvent pas être localisées.

J'ai écrit un exécutable wrapper pour ILMerge dans lequel je transmets le nom de l'exe de démarrage du projet que je souhaite fusionner, ainsi qu'un nom d'exe de sortie, puis il reflète les assemblys dépendants et appelle ILMerge avec les paramètres de ligne de commande appropriés.C'est beaucoup plus facile maintenant lorsque j'ajoute de nouveaux assemblys au projet, je n'ai plus besoin de penser à mettre à jour le script de construction.

Autres conseils

Introduction

Cet article montre comment remplacer tous .exe + .dll files avec un seul combined .exe.Il conserve également le débogage .pdb dossier intact.

Pour les applications console

Voici la base Post Build String pour Visual Studio 2010 SP1, en utilisant .NET 4.0.Je construis une console .exe avec tous les fichiers sub-.dll inclus.

"$(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

Conseils de base

  • La sortie est un fichier "AssemblyName.all.exe" qui combine toutes les sous-dll en un seul .exe.
  • Remarquez le ILMerge\ annuaire.Vous devez soit copier l'utilitaire ILMerge dans le répertoire de votre solution (afin de pouvoir distribuer la source sans avoir à vous soucier de documenter l'installation d'ILMerge), soit modifier ce chemin pour pointer vers l'emplacement où réside ILMerge.exe.

Conseils avancés

Si vous rencontrez des problèmes avec le fonctionnement, allumez Output, et sélectionnez Show output from: Build.Vérifiez la commande exacte réellement générée par Visual Studio et recherchez les erreurs.

Exemple de script de construction

Ce script remplace tout .exe + .dll files avec un seul combined .exe.Il conserve également le fichier de débogage .pdb intact.

Pour l'utiliser, collez-le dans votre Post Build étape, sous le Build Events dans un projet C# et assurez-vous d'ajuster le chemin de la première ligne pour qu'il pointe vers 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

Nous utilisons ILMerge sur les blocs d'application Microsoft - au lieu de 12 fichiers DLL séparés, nous avons un seul fichier que nous pouvons télécharger sur nos zones client, et la structure du système de fichiers est beaucoup plus soignée.

Après avoir fusionné les fichiers, j'ai dû modifier la liste des projets de Visual Studio, supprimer les 12 assemblages séparés et ajouter le fichier unique comme référence, sinon il se plaindrait de ne pas pouvoir trouver l'assemblage spécifique.Je ne suis pas trop sûr de la façon dont cela fonctionnerait après le déploiement, cela pourrait valoir la peine d'essayer.

Je sais que c'est une vieille question, mais nous utilisons non seulement ILMerge pour réduire le nombre de dépendances mais aussi pour internaliser les dépendances "internes" (par exemple automapper, restsharp, etc.) qui sont utilisées par l'utilitaire.Cela signifie qu'ils sont complètement abstraits et que le projet utilisant l'utilitaire fusionné n'a pas besoin de les connaître.Cela réduit encore une fois les références requises dans le projet et lui permet d'utiliser/mettre à jour sa propre version de la même bibliothèque externe si nécessaire.

Nous utilisons ILMerge sur de nombreux projets.Le Usine de logiciels de services Web, par exemple, produit quelque chose comme 8 assemblages en sortie.Nous fusionnons toutes ces DLL en une seule DLL afin que l'hôte du service n'ait à référencer qu'une seule DLL.

Cela rend la vie un peu plus facile, mais ce n'est pas grave non plus.

Nous avons eu le même problème avec la combinaison des dépendances WPF....ILMerge ne semble pas s'en occuper.Cependant, Costura.Fody a parfaitement fonctionné pour nous et a pris environ 5 minutes pour démarrer...une très bonne expérience.

Installez simplement avec Nuget (en sélectionnant le projet par défaut correct dans la console du gestionnaire de packages).Il s'introduit dans le projet cible et les paramètres par défaut ont immédiatement fonctionné pour nous.

Il fusionne toutes les DLL marquées "Copy Local" = true et produit un .EXE fusionné (à côté de la sortie standard), dont la taille est bien compressée (beaucoup inférieure à la taille totale de la sortie).

La licence est MIT, vous pouvez donc modifier/distribuer selon vos besoins.

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

Notez que pour les programmes Windows GUI (par exemple WinForms), vous devrez utiliser le /target :vinexe changer.
La cible:exe le commutateur crée une fusion console application.

Nous avons rencontré des problèmes lors de la fusion de DLL contenant des ressources dans le même espace de noms.Au cours du processus de fusion, l'un des espaces de noms de ressources a été renommé et les ressources n'ont donc pas pu être localisées.Peut-être que nous faisons simplement quelque chose de mal, tout en enquêtant sur le problème.

Nous venons de commencer à utiliser ILMerge dans nos solutions qui sont redistribuées et utilisées dans nos autres projets et jusqu'ici tout va bien.Tout semble bien fonctionner.Nous avons même obscurci directement l’assemblage emballé.

Nous envisageons de faire de même avec les assemblys MS Enterprise Library.

Le seul vrai problème que je vois est la gestion des versions des assemblys individuels du package.

J'ai récemment eu un problème où j'avais fusionné l'assemblage dans l'assemblage. J'avais certaines classes qui étaient appelées via une réflexion dans le CMS open source Umbraco.

Les informations permettant d'effectuer l'appel via la réflexion provenaient de la table de base de données contenant le nom de l'assembly et l'espace de noms de la classe implémentée et de l'interface.Le problème était que l'appel de réflexion échouait lorsque la DLL était fusionnée, mais si la DLL était séparée, tout fonctionnait bien.Je pense que le problème peut être similaire à celui de Longeasy ?

Je commence tout juste à utiliser ILMerge dans le cadre de ma version CI pour combiner de nombreux contrats WCF finement détaillés dans une seule bibliothèque.Cela fonctionne très bien, mais la nouvelle bibliothèque fusionnée ne peut pas facilement coexister avec ses bibliothèques de composants ou d'autres bibliothèques qui dépendent de ces bibliothèques de composants.

Si, dans un nouveau projet, vous faites référence à la fois à votre bibliothèque ILMerged et également à une bibliothèque existante qui dépend de l'une des entrées que vous avez données à ILMerge, vous constaterez que vous ne pouvez transmettre aucun type de la bibliothèque ILMerged à aucune méthode dans la bibliothèque héritée sans effectuer une sorte de mappage de type (par ex.automapper ou cartographie manuelle).En effet, une fois tout compilé, les types sont effectivement qualifiés avec un nom d'assembly.

Les noms entreront également en collision, mais vous pouvez résoudre ce problème en utilisant alias externe.

Mon conseil serait d'éviter d'inclure dans votre assemblage fusionné toute bibliothèque accessible au public exposée par votre assemblage fusionné (par ex.via un type de retour, un paramètre de méthode/constructeur, un champ, une propriété, un générique...) sauf si vous êtes sûr que l'utilisateur de votre assembly fusionné ne dépend pas et ne dépendra jamais de la version autonome de la même bibliothèque.

Il me semble que la meilleure pratique ILMerge n°1 est de ne pas utiliser ILMerge.Utilisez plutôt Assemblage intelligent.L'une des raisons à cela est que la meilleure pratique ILMerge n°2 consiste à toujours exécuter PEVerify après avoir effectué un ILMerge, car ILMerge ne garantit pas qu'il fusionnera correctement les assemblys dans un exécutable valide.

Autres inconvénients d'ILMerge :

  • lors de la fusion, il supprime les commentaires XML (si cela m'intéressait, j'utiliserais un outil d'obscurcissement)
  • il ne gère pas correctement la création d'un fichier .pdb correspondant

Un autre outil auquel il convient de prêter attention est Mono.Cecil et l'outil Mono.Linker [2].

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top