ILMerge peut combiner des assemblages en un seul assemblage à condition que l'assemblage ne contienne que du code géré. Vous pouvez utiliser l'application en ligne de commande, ou ajouter une référence à l'exe et fusionner de manière programmatique. Pour une version GUI, il existe Eazfuscator et aussi .netz qui sont toutes deux gratuites. Les applications payantes comprennent BoxedApp et SmartAssembly .
Si vous devez fusionner des assemblages avec du code non géré, je suggérerais SmartAssembly . Je n'ai jamais eu le hoquet avec SmartAssembly mais avec tous les autres. Ici, il peut intégrer les dépendances requises en tant que ressources à votre exe principal.
Vous pouvez faire tout cela manuellement sans avoir à vous soucier de savoir si l'assemblage est géré ou en mode mixte en intégrant la dll à vos ressources et en vous appuyant sur l'assemblage d'AppDomain. ResolveHandler
. Il s'agit d'une solution unique qui adopte le pire des cas, c'est-à-dire des assemblages avec du code non géré.
static void Main()
{
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
{
string assemblyName = new AssemblyName(args.Name).Name;
if (assemblyName.EndsWith(".resources"))
return null;
string dllName = assemblyName + ".dll";
string dllFullPath = Path.Combine(GetMyApplicationSpecificPath(), dllName);
using (Stream s = Assembly.GetEntryAssembly().GetManifestResourceStream(typeof(Program).Namespace + ".Resources." + dllName))
{
byte[] data = new byte[stream.Length];
s.Read(data, 0, data.Length);
//or just byte[] data = new BinaryReader(s).ReadBytes((int)s.Length);
File.WriteAllBytes(dllFullPath, data);
}
return Assembly.LoadFrom(dllFullPath);
};
}
La clé ici est d'écrire les octets dans un fichier et de les charger depuis son emplacement. Pour éviter le problème de la poule et de l'œuf, vous devez vous assurer que vous déclarez le gestionnaire avant d'accéder à l'assemblage et que vous n'accédez pas aux membres de l'assemblage (ou n'instanciez rien qui ait à voir avec l'assemblage) pendant la partie chargement (résolution de l'assemblage). Veillez également à ce que GetMyApplicationSpecificPath()
n'est pas un répertoire temporaire car les fichiers temporaires pourraient être effacés par d'autres programmes ou par vous-même (non pas qu'ils soient effacés pendant que votre programme accède à la dll, mais au moins c'est une nuisance. AppData est un bon emplacement). Notez également que vous devez écrire les octets à chaque fois, vous ne pouvez pas charger à partir d'un emplacement juste parce que la dll y réside déjà.
Pour les dlls gérées, vous n'avez pas besoin d'écrire des octets, mais de charger directement depuis l'emplacement de la dll, ou simplement de lire les octets et de charger l'assemblage depuis la mémoire. Comme ceci ou ainsi :
using (Stream s = Assembly.GetEntryAssembly().GetManifestResourceStream(typeof(Program).Namespace + ".Resources." + dllName))
{
byte[] data = new byte[stream.Length];
s.Read(data, 0, data.Length);
return Assembly.Load(data);
}
//or just
return Assembly.LoadFrom(dllFullPath); //if location is known.
Si l'assemblage est totalement non géré, vous pouvez voir ceci lien ou ce sur la façon de charger de telles dlls.
0 votes
Je vous recommande de consulter l'utilitaire .NETZ, qui compresse également l'assemblage avec un schéma de votre choix : http://madebits.com/netz/help.php#single
2 votes
C'est possible, mais vous vous retrouverez avec un exécutable volumineux (Base64 sera utilisé pour encoder votre dll).
0 votes
Outre ILMerge si vous ne voulez pas vous embêter avec les commutateurs de ligne de commande, je recommande vraiment ILMerge-Gui . C'est un projet open source, vraiment bon !
2 votes
@PaweDyda : Vous pouvez incorporer des données binaires brutes dans une image PE (cf. RCDATA ). Aucune transformation n'est requise (ou recommandée).