📜 ⬆️ ⬇️

C # + WPF + third-party builds -> one .exe-shnik

Sometimes you have to develop a small application in C # and WPF, but as a result of using third-party builds (for example, SharpZipLib, Unity), it turns out that at the output, in addition to our little .exe file, we also get a bunch of .dll-ok, and we need to there was just one .exe-shnik.

Few knowledgeable people here will remember the utility ILMerge from Microsoft, but unfortunately there are problems with WPF-applications due to the peculiarities of compiling XAML-files.
There are also problems with tricky assemblies, which were walked by decent obfuscators.

I suggest another way that I use in some of my products - to include all third-party assemblies as embedded resources, and in App.xaml.cs, do this:

public partial class App : Application { // private void OnStartup( object sender, StartupEventArgs e) { // AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; } // static Assembly ResolveAssembly( object sender, ResolveEventArgs args) { // ( ) Assembly thisAssembly = Assembly .GetExecutingAssembly(); // var name = args.Name.Substring(0, args.Name.IndexOf( ',' )) + ".dll" ; // var resourceName = thisAssembly.GetManifestResourceNames().First(s => s.EndsWith(name)); using ( Stream stream = thisAssembly.GetManifestResourceStream(resourceName)) { // byte [] block = new byte [stream.Length]; stream.Read(block, 0, block.Length); // return Assembly .Load(block); } } } * This source code was highlighted with Source Code Highlighter .
  1. public partial class App : Application { // private void OnStartup( object sender, StartupEventArgs e) { // AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; } // static Assembly ResolveAssembly( object sender, ResolveEventArgs args) { // ( ) Assembly thisAssembly = Assembly .GetExecutingAssembly(); // var name = args.Name.Substring(0, args.Name.IndexOf( ',' )) + ".dll" ; // var resourceName = thisAssembly.GetManifestResourceNames().First(s => s.EndsWith(name)); using ( Stream stream = thisAssembly.GetManifestResourceStream(resourceName)) { // byte [] block = new byte [stream.Length]; stream.Read(block, 0, block.Length); // return Assembly .Load(block); } } } * This source code was highlighted with Source Code Highlighter .
  2. public partial class App : Application { // private void OnStartup( object sender, StartupEventArgs e) { // AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; } // static Assembly ResolveAssembly( object sender, ResolveEventArgs args) { // ( ) Assembly thisAssembly = Assembly .GetExecutingAssembly(); // var name = args.Name.Substring(0, args.Name.IndexOf( ',' )) + ".dll" ; // var resourceName = thisAssembly.GetManifestResourceNames().First(s => s.EndsWith(name)); using ( Stream stream = thisAssembly.GetManifestResourceStream(resourceName)) { // byte [] block = new byte [stream.Length]; stream.Read(block, 0, block.Length); // return Assembly .Load(block); } } } * This source code was highlighted with Source Code Highlighter .
  3. public partial class App : Application { // private void OnStartup( object sender, StartupEventArgs e) { // AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; } // static Assembly ResolveAssembly( object sender, ResolveEventArgs args) { // ( ) Assembly thisAssembly = Assembly .GetExecutingAssembly(); // var name = args.Name.Substring(0, args.Name.IndexOf( ',' )) + ".dll" ; // var resourceName = thisAssembly.GetManifestResourceNames().First(s => s.EndsWith(name)); using ( Stream stream = thisAssembly.GetManifestResourceStream(resourceName)) { // byte [] block = new byte [stream.Length]; stream.Read(block, 0, block.Length); // return Assembly .Load(block); } } } * This source code was highlighted with Source Code Highlighter .
  4. public partial class App : Application { // private void OnStartup( object sender, StartupEventArgs e) { // AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; } // static Assembly ResolveAssembly( object sender, ResolveEventArgs args) { // ( ) Assembly thisAssembly = Assembly .GetExecutingAssembly(); // var name = args.Name.Substring(0, args.Name.IndexOf( ',' )) + ".dll" ; // var resourceName = thisAssembly.GetManifestResourceNames().First(s => s.EndsWith(name)); using ( Stream stream = thisAssembly.GetManifestResourceStream(resourceName)) { // byte [] block = new byte [stream.Length]; stream.Read(block, 0, block.Length); // return Assembly .Load(block); } } } * This source code was highlighted with Source Code Highlighter .
  5. public partial class App : Application { // private void OnStartup( object sender, StartupEventArgs e) { // AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; } // static Assembly ResolveAssembly( object sender, ResolveEventArgs args) { // ( ) Assembly thisAssembly = Assembly .GetExecutingAssembly(); // var name = args.Name.Substring(0, args.Name.IndexOf( ',' )) + ".dll" ; // var resourceName = thisAssembly.GetManifestResourceNames().First(s => s.EndsWith(name)); using ( Stream stream = thisAssembly.GetManifestResourceStream(resourceName)) { // byte [] block = new byte [stream.Length]; stream.Read(block, 0, block.Length); // return Assembly .Load(block); } } } * This source code was highlighted with Source Code Highlighter .
  6. public partial class App : Application { // private void OnStartup( object sender, StartupEventArgs e) { // AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; } // static Assembly ResolveAssembly( object sender, ResolveEventArgs args) { // ( ) Assembly thisAssembly = Assembly .GetExecutingAssembly(); // var name = args.Name.Substring(0, args.Name.IndexOf( ',' )) + ".dll" ; // var resourceName = thisAssembly.GetManifestResourceNames().First(s => s.EndsWith(name)); using ( Stream stream = thisAssembly.GetManifestResourceStream(resourceName)) { // byte [] block = new byte [stream.Length]; stream.Read(block, 0, block.Length); // return Assembly .Load(block); } } } * This source code was highlighted with Source Code Highlighter .
  7. public partial class App : Application { // private void OnStartup( object sender, StartupEventArgs e) { // AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; } // static Assembly ResolveAssembly( object sender, ResolveEventArgs args) { // ( ) Assembly thisAssembly = Assembly .GetExecutingAssembly(); // var name = args.Name.Substring(0, args.Name.IndexOf( ',' )) + ".dll" ; // var resourceName = thisAssembly.GetManifestResourceNames().First(s => s.EndsWith(name)); using ( Stream stream = thisAssembly.GetManifestResourceStream(resourceName)) { // byte [] block = new byte [stream.Length]; stream.Read(block, 0, block.Length); // return Assembly .Load(block); } } } * This source code was highlighted with Source Code Highlighter .
  8. public partial class App : Application { // private void OnStartup( object sender, StartupEventArgs e) { // AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; } // static Assembly ResolveAssembly( object sender, ResolveEventArgs args) { // ( ) Assembly thisAssembly = Assembly .GetExecutingAssembly(); // var name = args.Name.Substring(0, args.Name.IndexOf( ',' )) + ".dll" ; // var resourceName = thisAssembly.GetManifestResourceNames().First(s => s.EndsWith(name)); using ( Stream stream = thisAssembly.GetManifestResourceStream(resourceName)) { // byte [] block = new byte [stream.Length]; stream.Read(block, 0, block.Length); // return Assembly .Load(block); } } } * This source code was highlighted with Source Code Highlighter .
  9. public partial class App : Application { // private void OnStartup( object sender, StartupEventArgs e) { // AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; } // static Assembly ResolveAssembly( object sender, ResolveEventArgs args) { // ( ) Assembly thisAssembly = Assembly .GetExecutingAssembly(); // var name = args.Name.Substring(0, args.Name.IndexOf( ',' )) + ".dll" ; // var resourceName = thisAssembly.GetManifestResourceNames().First(s => s.EndsWith(name)); using ( Stream stream = thisAssembly.GetManifestResourceStream(resourceName)) { // byte [] block = new byte [stream.Length]; stream.Read(block, 0, block.Length); // return Assembly .Load(block); } } } * This source code was highlighted with Source Code Highlighter .
  10. public partial class App : Application { // private void OnStartup( object sender, StartupEventArgs e) { // AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; } // static Assembly ResolveAssembly( object sender, ResolveEventArgs args) { // ( ) Assembly thisAssembly = Assembly .GetExecutingAssembly(); // var name = args.Name.Substring(0, args.Name.IndexOf( ',' )) + ".dll" ; // var resourceName = thisAssembly.GetManifestResourceNames().First(s => s.EndsWith(name)); using ( Stream stream = thisAssembly.GetManifestResourceStream(resourceName)) { // byte [] block = new byte [stream.Length]; stream.Read(block, 0, block.Length); // return Assembly .Load(block); } } } * This source code was highlighted with Source Code Highlighter .
  11. public partial class App : Application { // private void OnStartup( object sender, StartupEventArgs e) { // AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; } // static Assembly ResolveAssembly( object sender, ResolveEventArgs args) { // ( ) Assembly thisAssembly = Assembly .GetExecutingAssembly(); // var name = args.Name.Substring(0, args.Name.IndexOf( ',' )) + ".dll" ; // var resourceName = thisAssembly.GetManifestResourceNames().First(s => s.EndsWith(name)); using ( Stream stream = thisAssembly.GetManifestResourceStream(resourceName)) { // byte [] block = new byte [stream.Length]; stream.Read(block, 0, block.Length); // return Assembly .Load(block); } } } * This source code was highlighted with Source Code Highlighter .
  12. public partial class App : Application { // private void OnStartup( object sender, StartupEventArgs e) { // AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; } // static Assembly ResolveAssembly( object sender, ResolveEventArgs args) { // ( ) Assembly thisAssembly = Assembly .GetExecutingAssembly(); // var name = args.Name.Substring(0, args.Name.IndexOf( ',' )) + ".dll" ; // var resourceName = thisAssembly.GetManifestResourceNames().First(s => s.EndsWith(name)); using ( Stream stream = thisAssembly.GetManifestResourceStream(resourceName)) { // byte [] block = new byte [stream.Length]; stream.Read(block, 0, block.Length); // return Assembly .Load(block); } } } * This source code was highlighted with Source Code Highlighter .
  13. public partial class App : Application { // private void OnStartup( object sender, StartupEventArgs e) { // AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; } // static Assembly ResolveAssembly( object sender, ResolveEventArgs args) { // ( ) Assembly thisAssembly = Assembly .GetExecutingAssembly(); // var name = args.Name.Substring(0, args.Name.IndexOf( ',' )) + ".dll" ; // var resourceName = thisAssembly.GetManifestResourceNames().First(s => s.EndsWith(name)); using ( Stream stream = thisAssembly.GetManifestResourceStream(resourceName)) { // byte [] block = new byte [stream.Length]; stream.Read(block, 0, block.Length); // return Assembly .Load(block); } } } * This source code was highlighted with Source Code Highlighter .
  14. public partial class App : Application { // private void OnStartup( object sender, StartupEventArgs e) { // AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; } // static Assembly ResolveAssembly( object sender, ResolveEventArgs args) { // ( ) Assembly thisAssembly = Assembly .GetExecutingAssembly(); // var name = args.Name.Substring(0, args.Name.IndexOf( ',' )) + ".dll" ; // var resourceName = thisAssembly.GetManifestResourceNames().First(s => s.EndsWith(name)); using ( Stream stream = thisAssembly.GetManifestResourceStream(resourceName)) { // byte [] block = new byte [stream.Length]; stream.Read(block, 0, block.Length); // return Assembly .Load(block); } } } * This source code was highlighted with Source Code Highlighter .
  15. public partial class App : Application { // private void OnStartup( object sender, StartupEventArgs e) { // AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; } // static Assembly ResolveAssembly( object sender, ResolveEventArgs args) { // ( ) Assembly thisAssembly = Assembly .GetExecutingAssembly(); // var name = args.Name.Substring(0, args.Name.IndexOf( ',' )) + ".dll" ; // var resourceName = thisAssembly.GetManifestResourceNames().First(s => s.EndsWith(name)); using ( Stream stream = thisAssembly.GetManifestResourceStream(resourceName)) { // byte [] block = new byte [stream.Length]; stream.Read(block, 0, block.Length); // return Assembly .Load(block); } } } * This source code was highlighted with Source Code Highlighter .
  16. public partial class App : Application { // private void OnStartup( object sender, StartupEventArgs e) { // AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; } // static Assembly ResolveAssembly( object sender, ResolveEventArgs args) { // ( ) Assembly thisAssembly = Assembly .GetExecutingAssembly(); // var name = args.Name.Substring(0, args.Name.IndexOf( ',' )) + ".dll" ; // var resourceName = thisAssembly.GetManifestResourceNames().First(s => s.EndsWith(name)); using ( Stream stream = thisAssembly.GetManifestResourceStream(resourceName)) { // byte [] block = new byte [stream.Length]; stream.Read(block, 0, block.Length); // return Assembly .Load(block); } } } * This source code was highlighted with Source Code Highlighter .
  17. public partial class App : Application { // private void OnStartup( object sender, StartupEventArgs e) { // AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; } // static Assembly ResolveAssembly( object sender, ResolveEventArgs args) { // ( ) Assembly thisAssembly = Assembly .GetExecutingAssembly(); // var name = args.Name.Substring(0, args.Name.IndexOf( ',' )) + ".dll" ; // var resourceName = thisAssembly.GetManifestResourceNames().First(s => s.EndsWith(name)); using ( Stream stream = thisAssembly.GetManifestResourceStream(resourceName)) { // byte [] block = new byte [stream.Length]; stream.Read(block, 0, block.Length); // return Assembly .Load(block); } } } * This source code was highlighted with Source Code Highlighter .
  18. public partial class App : Application { // private void OnStartup( object sender, StartupEventArgs e) { // AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; } // static Assembly ResolveAssembly( object sender, ResolveEventArgs args) { // ( ) Assembly thisAssembly = Assembly .GetExecutingAssembly(); // var name = args.Name.Substring(0, args.Name.IndexOf( ',' )) + ".dll" ; // var resourceName = thisAssembly.GetManifestResourceNames().First(s => s.EndsWith(name)); using ( Stream stream = thisAssembly.GetManifestResourceStream(resourceName)) { // byte [] block = new byte [stream.Length]; stream.Read(block, 0, block.Length); // return Assembly .Load(block); } } } * This source code was highlighted with Source Code Highlighter .
  19. public partial class App : Application { // private void OnStartup( object sender, StartupEventArgs e) { // AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; } // static Assembly ResolveAssembly( object sender, ResolveEventArgs args) { // ( ) Assembly thisAssembly = Assembly .GetExecutingAssembly(); // var name = args.Name.Substring(0, args.Name.IndexOf( ',' )) + ".dll" ; // var resourceName = thisAssembly.GetManifestResourceNames().First(s => s.EndsWith(name)); using ( Stream stream = thisAssembly.GetManifestResourceStream(resourceName)) { // byte [] block = new byte [stream.Length]; stream.Read(block, 0, block.Length); // return Assembly .Load(block); } } } * This source code was highlighted with Source Code Highlighter .
  20. public partial class App : Application { // private void OnStartup( object sender, StartupEventArgs e) { // AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; } // static Assembly ResolveAssembly( object sender, ResolveEventArgs args) { // ( ) Assembly thisAssembly = Assembly .GetExecutingAssembly(); // var name = args.Name.Substring(0, args.Name.IndexOf( ',' )) + ".dll" ; // var resourceName = thisAssembly.GetManifestResourceNames().First(s => s.EndsWith(name)); using ( Stream stream = thisAssembly.GetManifestResourceStream(resourceName)) { // byte [] block = new byte [stream.Length]; stream.Read(block, 0, block.Length); // return Assembly .Load(block); } } } * This source code was highlighted with Source Code Highlighter .
  21. public partial class App : Application { // private void OnStartup( object sender, StartupEventArgs e) { // AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; } // static Assembly ResolveAssembly( object sender, ResolveEventArgs args) { // ( ) Assembly thisAssembly = Assembly .GetExecutingAssembly(); // var name = args.Name.Substring(0, args.Name.IndexOf( ',' )) + ".dll" ; // var resourceName = thisAssembly.GetManifestResourceNames().First(s => s.EndsWith(name)); using ( Stream stream = thisAssembly.GetManifestResourceStream(resourceName)) { // byte [] block = new byte [stream.Length]; stream.Read(block, 0, block.Length); // return Assembly .Load(block); } } } * This source code was highlighted with Source Code Highlighter .
  22. public partial class App : Application { // private void OnStartup( object sender, StartupEventArgs e) { // AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; } // static Assembly ResolveAssembly( object sender, ResolveEventArgs args) { // ( ) Assembly thisAssembly = Assembly .GetExecutingAssembly(); // var name = args.Name.Substring(0, args.Name.IndexOf( ',' )) + ".dll" ; // var resourceName = thisAssembly.GetManifestResourceNames().First(s => s.EndsWith(name)); using ( Stream stream = thisAssembly.GetManifestResourceStream(resourceName)) { // byte [] block = new byte [stream.Length]; stream.Read(block, 0, block.Length); // return Assembly .Load(block); } } } * This source code was highlighted with Source Code Highlighter .
  23. public partial class App : Application { // private void OnStartup( object sender, StartupEventArgs e) { // AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; } // static Assembly ResolveAssembly( object sender, ResolveEventArgs args) { // ( ) Assembly thisAssembly = Assembly .GetExecutingAssembly(); // var name = args.Name.Substring(0, args.Name.IndexOf( ',' )) + ".dll" ; // var resourceName = thisAssembly.GetManifestResourceNames().First(s => s.EndsWith(name)); using ( Stream stream = thisAssembly.GetManifestResourceStream(resourceName)) { // byte [] block = new byte [stream.Length]; stream.Read(block, 0, block.Length); // return Assembly .Load(block); } } } * This source code was highlighted with Source Code Highlighter .
  24. public partial class App : Application { // private void OnStartup( object sender, StartupEventArgs e) { // AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; } // static Assembly ResolveAssembly( object sender, ResolveEventArgs args) { // ( ) Assembly thisAssembly = Assembly .GetExecutingAssembly(); // var name = args.Name.Substring(0, args.Name.IndexOf( ',' )) + ".dll" ; // var resourceName = thisAssembly.GetManifestResourceNames().First(s => s.EndsWith(name)); using ( Stream stream = thisAssembly.GetManifestResourceStream(resourceName)) { // byte [] block = new byte [stream.Length]; stream.Read(block, 0, block.Length); // return Assembly .Load(block); } } } * This source code was highlighted with Source Code Highlighter .
  25. public partial class App : Application { // private void OnStartup( object sender, StartupEventArgs e) { // AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; } // static Assembly ResolveAssembly( object sender, ResolveEventArgs args) { // ( ) Assembly thisAssembly = Assembly .GetExecutingAssembly(); // var name = args.Name.Substring(0, args.Name.IndexOf( ',' )) + ".dll" ; // var resourceName = thisAssembly.GetManifestResourceNames().First(s => s.EndsWith(name)); using ( Stream stream = thisAssembly.GetManifestResourceStream(resourceName)) { // byte [] block = new byte [stream.Length]; stream.Read(block, 0, block.Length); // return Assembly .Load(block); } } } * This source code was highlighted with Source Code Highlighter .
  26. public partial class App : Application { // private void OnStartup( object sender, StartupEventArgs e) { // AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; } // static Assembly ResolveAssembly( object sender, ResolveEventArgs args) { // ( ) Assembly thisAssembly = Assembly .GetExecutingAssembly(); // var name = args.Name.Substring(0, args.Name.IndexOf( ',' )) + ".dll" ; // var resourceName = thisAssembly.GetManifestResourceNames().First(s => s.EndsWith(name)); using ( Stream stream = thisAssembly.GetManifestResourceStream(resourceName)) { // byte [] block = new byte [stream.Length]; stream.Read(block, 0, block.Length); // return Assembly .Load(block); } } } * This source code was highlighted with Source Code Highlighter .
  27. public partial class App : Application { // private void OnStartup( object sender, StartupEventArgs e) { // AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; } // static Assembly ResolveAssembly( object sender, ResolveEventArgs args) { // ( ) Assembly thisAssembly = Assembly .GetExecutingAssembly(); // var name = args.Name.Substring(0, args.Name.IndexOf( ',' )) + ".dll" ; // var resourceName = thisAssembly.GetManifestResourceNames().First(s => s.EndsWith(name)); using ( Stream stream = thisAssembly.GetManifestResourceStream(resourceName)) { // byte [] block = new byte [stream.Length]; stream.Read(block, 0, block.Length); // return Assembly .Load(block); } } } * This source code was highlighted with Source Code Highlighter .
public partial class App : Application { // private void OnStartup( object sender, StartupEventArgs e) { // AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; } // static Assembly ResolveAssembly( object sender, ResolveEventArgs args) { // ( ) Assembly thisAssembly = Assembly .GetExecutingAssembly(); // var name = args.Name.Substring(0, args.Name.IndexOf( ',' )) + ".dll" ; // var resourceName = thisAssembly.GetManifestResourceNames().First(s => s.EndsWith(name)); using ( Stream stream = thisAssembly.GetManifestResourceStream(resourceName)) { // byte [] block = new byte [stream.Length]; stream.Read(block, 0, block.Length); // return Assembly .Load(block); } } } * This source code was highlighted with Source Code Highlighter .

')
Accordingly, with such an approach, we mean that we normally call assembly files.

It is important to remember that with this method I just show the idea, there are no handlers for possible errors, or much more.

What else can be improved - you can reduce the size of the output .exe file, keeping the assemblies compressed via the DeflateStream and reading them out respectively by unpacking through it. You can periodically check to see if the build has been updated, and if it has been updated, to load it from the network (especially if this is something fine).

And yes, the important point is that it most likely will not work - with such an assembly, assemblies with native methods will most likely not work, i.e. written in C ++ / CLI. Correct me if I'm wrong, but they didn't work for me.

[update]
About C ++ / CLI - according to MSDN - a BadImageFormatException exception is thrown if the C ++ compiler deletes the .reloc section from the .exe file. If you compile an assembly on C ++ / CLI with / fixed: no, then maybe it will load successfully

Source: https://habr.com/ru/post/67836/


All Articles