Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Embedding Localization Resources .DLL's to the Executable in C#?

I want to make my program multilingual. I have successfully made the program multilingual via Form's Localizable and Language properties. It made some .resx files. Then I deleted non-needed files such as images (which they are the same in all langauges) etc from the .resx files.

The problem is, for example, it also generates a folder called "en" and in that folder, another generated file is called "ProjectName.resources.dll".

Is there anyway to embed this resource file to the .exe? Adding it to the resources and setting Build Action to "Embedded Resource" doesn't work also.

Thanks.

like image 819
PythEch Avatar asked Sep 20 '11 17:09

PythEch


People also ask

What is the easiest way to embed all DLL's into exe in C# Windows Forms?

Just right-click your project in Visual Studio, choose Project Properties -> Resources -> Add Resource -> Add Existing File… And include the code below to your App.

How do I convert DLL to EXE?

DLL to EXE 1.1 Simply put, type in "dll_to_exe filename. dll filename.exe" where filename is replaced with the DLL file and the output executable name you want.

How to add DLL as Embedded resource c#?

Add DLL As Embedded Resource First, add the DLL as Reference. Then, add the same DLL as file into the project. Right click the project's name > Add > Existing Item... The same DLL will exist twice in different folder in the project.

What are DLL files in C?

In Windows, a dynamic-link library (DLL) is a kind of executable file that acts as a shared library of functions and resources. Dynamic linking is an operating system capability. It enables an executable to call functions or use resources stored in a separate file.


2 Answers

In .NET Framework 4 you can embed resource library into executable.

http://msdn.microsoft.com/en-us/library/system.appdomain.assemblyresolve.aspx

Just create same structure ( with localized folders 'lib/en', 'lib/de' ) and embed them.

private static Assembly MyResolveEventHandler(object sender, ResolveEventArgs args) {
    AssemblyName MissingAssembly = new AssemblyName(args.Name);
    CultureInfo ci = MissingAssembly.CultureInfo;

    ...
    resourceName = "MyApp.lib." + ci.Name.Replace("-","_") + "." + MissingAssembly.Name + ".dll";
    var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName)
    ...
}
like image 105
IvanP Avatar answered Oct 14 '22 00:10

IvanP


You've asked this question a while ago and you've already accepted an answer, but still I'll try to provide an alternative way. I had the same problem and this is how I solved it:

I added the dll as a Ressource to my C#-Project and added this code to my Main-Method (the one that starts your main winform).

public static void Main(string[] args)
{
    if (InitdeDEDll()) // Create dll if it's missing.
    {
        // Restart the application if the language-package was added
        Application.Restart();
        return;
    }
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new YOURMAINFORM());
}

private static bool InitdeDEDll() // Initialize the German de-DE DLL
{
    try
    {
        // Language of my package. This will be the name of the subfolder.
        string language = "de-DE";
        return TryCreateFileFromRessource(language, @"NAMEOFYOURDLL.dll",
            NAMESPACEOFYOURRESSOURCE.NAMEOFYOURDLLINRESSOURCEFILE);
    }
    catch (Exception)
    {
        return false;
    }
}

private static bool TryCreateFileFromRessource(string subfolder, string fileName, byte[] buffer)
{
    try
    {
        // path of the subfolder
        string subfolderPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + (subfolder != "" ? @"\" : "") + subfolder;

        // Create subfolder if it doesn't exist
        if (!Directory.Exists(subfolder))
            Directory.CreateDirectory(subfolderPath);


        fileName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"\" + subfolder + (subfolder!=""?@"\":"") + fileName;
        if (!File.Exists(fileName)) // if the dll doesn't already exist, it has to be created
        {
            // Write dll
            Stream stream = File.Create(fileName);
            stream.Write(buffer, 0, buffer.GetLength(0));
            stream.Close();
        }
        else
        {
            return false;
        }
    }
    catch
    {
        return false;
    }

    return true;
}

}

Note: This will create the folder and language-dll again if it's missing, so you don't have to care anymore that you copy that folder and the dll with your exe-file. If you want it to be completely vanished this won't be the right approach of course.

like image 44
Mickey Avatar answered Oct 14 '22 00:10

Mickey