66 votes

Fusionner des dlls dans un seul .exe avec wpf

Je travaille actuellement sur un projet où nous avons beaucoup de dépendances. J'aimerais compiler toutes les dll référencées dans le fichier .exe, comme vous le feriez avec des ressources intégrées. J'ai essayé ILMerge mais il ne peut pas gérer les ressources .xaml.

Ma question est donc la suivante : existe-t-il un moyen de fusionner un projet WPF avec plusieurs dépendances en un seul fichier .exe ?

0 votes

Vous cherchez uniquement des applications gratuites ou vous pouvez payer quelques dollars pour cela ?

0 votes

Si l'application est suffisamment bonne et peut gérer WPF, nous envisagerons probablement des applications commerciales également.

80voto

Wegged Points 1071

http://www.digitallycreated.net/Blog/61/combining-multiple-assemblies-into-a-single-exe-for-a-wpf-application

Cela a marché comme un charme pour moi :) et c'est complètement gratuit.

Ajout de code au cas où le blog disparaîtrait un jour.

1) Ajoutez ceci à votre .csproj fichier :

<Target Name="AfterResolveReferences">
  <ItemGroup>
    <EmbeddedResource Include="@(ReferenceCopyLocalPaths)" Condition="'%(ReferenceCopyLocalPaths.Extension)' == '.dll'">
      <LogicalName>%(ReferenceCopyLocalPaths.DestinationSubDirectory)%(ReferenceCopyLocalPaths.Filename)%(ReferenceCopyLocalPaths.Extension)</LogicalName>
    </EmbeddedResource>
  </ItemGroup>
</Target>

2) Faites votre principal Program.cs ressemble à ça :

[STAThreadAttribute]
public static void Main()
{
    AppDomain.CurrentDomain.AssemblyResolve += OnResolveAssembly;
    App.Main();
}

3) Ajouter le OnResolveAssembly méthode :

private static Assembly OnResolveAssembly(object sender, ResolveEventArgs args)
{
    Assembly executingAssembly = Assembly.GetExecutingAssembly();
    AssemblyName assemblyName = new AssemblyName(args.Name);

    var path = assemblyName.Name + ".dll";
    if (assemblyName.CultureInfo.Equals(CultureInfo.InvariantCulture) == false) path = String.Format(@"{0}\{1}", assemblyName.CultureInfo, path);

    using (Stream stream = executingAssembly.GetManifestResourceStream(path))
    {
        if (stream == null) return null;

        var assemblyRawBytes = new byte[stream.Length];
        stream.Read(assemblyRawBytes, 0, assemblyRawBytes.Length);
        return Assembly.Load(assemblyRawBytes);
    }
}

0 votes

Bonne solution. J'ai eu quelques problèmes lors du chargement des dlls en utilisant .LoadFrom() à cause d'un contexte différent, mais sinon, c'est une façon agréable et propre d'automatiser la fusion directement dans VS.

0 votes

Cette solution est-elle spécifique à MSBuild ?

5 votes

C'est certainement la meilleure réponse

48voto

Simon Points 11945

Costura est un outil open source qui est conçu pour gérer la fusion des assemblages wpf.

https://github.com/Fody/Costura#how-it-works

13voto

Timotei Points 984

{smartassembly} est l'un de ces produits. Il peut obstruer ou incorporer vos dlls.

Essayez ça : http://www.smartassembly.com/

Vous pouvez également apporter de nombreuses améliorations à votre application afin qu'elle fonctionne plus rapidement.

Et oui. Vous pouvez l'utiliser pour WPF.

Mise à jour 8/06/2015 : ILRepack 2.0.0 (qui est une alternative open-source à ILMerge) a maintenant un support pour la plupart des fusions de cas WPF : https://twitter.com/Gluckies/status/607680149157462016

0 votes

J'ai essayé ce produit et il a fonctionné correctement là où ILMerge a échoué. Il est très facile à utiliser.

0 votes

Il semble impressionnant, mais il ne vous permet pas d'indiquer les fichiers que vous souhaitez assembler (il vous limite aux fichiers détectés). En effet, toutes les dll de ressources (avec les chaînes traduites) sont laissées seules, et vous avez toujours un exécutable avec des dll supplémentaires. Je pensais que le but de la fusion était d'avoir un seul exécutable et 0 dll.

9voto

Matthieu Points 2635

Comme indiqué sur Site web d'ILMerge Traitez ces fichiers DLL comme des ressources, de Jeffrey Richter. aquí :

De nombreuses applications consistent en un fichier EXE qui dépend de plusieurs DLL de nombreux fichiers DLL. Lors du déploiement de cette application, tous les fichiers doivent être déployés. Cependant, il existe une technique que vous pouvez utiliser pour déployer un seul fichier EXE. Tout d'abord, identifiez tous les fichiers DLL que votre fichier EXE dont dépend votre fichier EXE et qui ne font pas partie de Microsoft .NET Framework lui-même. Ajoutez ensuite ces DLL à votre projet Visual Studio. Pour chaque fichier DLL que vous ajoutez, affichez ses propriétés et changez son "Build Action" en "Embedded Resource". Ainsi, le compilateur C# intégrer le(s) fichier(s) DLL dans votre fichier EXE, et vous pouvez déployer ce fichier EXE unique. fichier EXE. Au moment de l'exécution, le CLR ne sera pas en mesure de trouver les assemblages DLL dépendants, ce qui est un problème de sécurité. DLL dépendants, ce qui constitue un problème. Pour résoudre ce problème, lorsque votre application l'application, enregistrez une méthode de rappel avec l'événement ResolveAssembly ResolveAssembly de l'AppDomain. Le code devrait ressembler à ceci :

AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => {

   String resourceName = "AssemblyLoadingAndReflection." +

      new AssemblyName(args.Name).Name + ".dll";

   using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName)) {

      Byte[] assemblyData = new Byte[stream.Length];

      stream.Read(assemblyData, 0, assemblyData.Length);

      return Assembly.Load(assemblyData);

   }

}; 

Maintenant, la première fois qu'un thread appelle une méthode qui fait référence à un type dans un fichier DLL dépendant, l'événement AssemblyResolve sera déclenché et le code de code de rappel montré ci-dessus trouvera la ressource DLL intégrée désirée et la chargera en appelant une surcharge de la méthode Load de Assembly qui prend un Byte[] comme argument.

7voto

Hemant Points 7612

Réacteur .NET a la possibilité de fusionner les assemblages et n'est pas très coûteux.

0 votes

Peut-il également gérer les projets WPF ? Cela semble prometteur.

0 votes

Quelqu'un a-t-il réussi à utiliser Reactor pour résoudre ses problèmes de fusion WPF ? À 180 $, c'est un produit abordable pour un pauvre développeur de shareware comme moi, contrairement à SmartAssembly.

0 votes

Eh bien, je l'ai essayé et ça marche ! Cependant, je veux encore voir si je peux faire fonctionner les choses sans avoir à débourser près de 200 $.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X