Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to embed a satellite assembly into the EXE file

I got the problem that I need to distribute a C# project as a single EXE file which is not an installer but the real program. It also needs to include a translation which currently resides in a subdirectory.

Is it possible to embed it directly into the binary?

like image 432
rmbl Avatar asked Sep 21 '09 10:09

rmbl


People also ask

What is satellite DLL in c#?

A satellite assembly is a compiled library (DLL) that contains “localizable” resources specific to a given culture such as strings, bitmaps, etc. You are likely to use satellite assemblies when creating a multilingual UI application.

What is satellite assembly in c# net?

A satellite assembly is a .NET Framework assembly containing resources specific to a given language. Using satellite assemblies, you can place resources for different languages in different assemblies, and the correct assembly is loaded into memory only if the user selects to view the application in that language. 0.

What is a satellite assembly Mcq?

What is a satellite assembly? Satellite assemblies are assemblies that are used to deploy language and culture specific resources for an application. In an application, a separate product ID is assigned to each language and a satellite assembly is installed in a language specific sub-directory.


3 Answers

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.

like image 114
Dale Avatar answered Sep 28 '22 18:09

Dale


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

like image 43
binball Avatar answered Sep 28 '22 16:09

binball


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;
    }
}
like image 24
csharptest.net Avatar answered Sep 28 '22 16:09

csharptest.net