How to embed a satellite assembly into the EXE file

Here it is the simplest solution which I saw in the Internet:

  • How to embed your application’s dependent DLLs inside your EXE file

also handy implementation of this solution: http://code.google.com/p/costura/wiki/HowItWorksEmbedTask


The short answer is yes, there is a program called Assembly Linker (AL.exe) that will embed assemblies in this way. Its main use case is localization, sounds like that is what you need it for too. If so, it should be straightforward.

Eg:

al /t:lib /embed:strings.de.resources /culture:de /out:MyApp.resources.dll

or

al.exe /culture:en-US /out:bin\Debug\en-US\HelloWorld.resources.dll /embed:Resources\MyResources.en-US.resources,HelloWorld.Resources.MyResources.en-US.resources /template:bin\Debug\HelloWorld.exe

This is an example walkthrough of it MSDN with the above examples and more. Also you may want to read this blog post which explains its usage a bit further.


Another option is to embed the other assemblies as an EmbededResource. Then handle the app domains AssemblyResolve, from here you can read the assembly from the resource and load it into the runtime. Something like the following:

public class HookResolver
{
    Dictionary<string, Assembly> _loaded;

    public HookResolver()
    {
        _loaded = new Dictionary<string, Assembly>(StringComparer.OrdinalIgnoreCase);
        AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
    }

    System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
    {
        string name = args.Name.Split(',')[0];
        Assembly asm;
        lock (_loaded)
        {
            if (!_loaded.TryGetValue(name, out asm))
            {
                using (Stream io = this.GetType().Assembly.GetManifestResourceStream(name))
                {
                    byte[] bytes = new BinaryReader(io).ReadBytes((int)io.Length);
                    asm = Assembly.Load(bytes);
                    _loaded.Add(name, asm);
                }
            }
        }
        return asm;
    }
}