Multilinguality under C# .NET

Hello!

I am a newbie for C#, although I have several years of experience with OOP.

For a project in the design phase, I was chosen to find out how multilinguality can be done under C#. For the project, I am currently using Microsoft Visual Studio 2010 Express…

WHAT I HAVE DONE TILL NOW
I read about several articles on this subject, like „System.Resources FAQ“ (https://www.google.com/bookmarks/url?url=http://msdn…), „Multilingual Applications in .NET“ (https://www.google.com/bookmarks/url?url=http://www…) or „C# multilingual support“ (https://www.google.com/bookmarks/url?url=http://www…), but still have problems getting my demo to run.

My demo worked without resource files with hard-coded text for all cultures (ar-SA, en-UK, de-DE, no, sv-SE, and tr). I run into problems when I tried it with resource files.

HOW I TRIED TO SOLVE IT
To solve it, I created a resource file for each culture, called Resource…resx. All the tutorials were not written for MS VS 2010, so there was no information about the combo box on the resources, which I had left at default („no code generation“) instead of „Internal“. :frowning:

Now, I have the resource files for the six languages:

Resource.ar-SA.resx
Resource.de-DE.resx
etc.

I determined the IDE-generated *.resources files and and determine the path for each of it according to the selected language.

When I run the code, I get stuck with the message



MainWindow:smiley:etermineResourceManager(): Exception: System.BadImageFormatException: Im Modul wurde ein Assemblymanifest erwartet. (Ausnahme von HRESULT: 0x80131018)

bei System.Reflection.RuntimeAssembly.nLoadFile(String path, Evidence evidence)

bei System.Reflection.Assembly.LoadFile(String path)

bei WpfApplication1.MainWindow.DetermineResourceManager() in C:\Documents and Settings\z002zatp\My Documents\Visual Studio 2010\Projects\WpfApplication1\WpfApplication1\MainWindow.xaml.cs:Zeile 136.

OK

So, a so-called assembly manifest is missing.

MY QUESTION
What have I to do let the IDE create the assembly manifest properly?

Thank you for your replies!

______________________________________________________
THE CODE:

The problematic line is marked below. I checked and found out that the files at C:\Documents and Settings\z002zatp\My Documents\Visual Studio 2010\Projects\WpfApplication1\WpfApplication1\obj\x86\Debug do exist.

______________________________________________________
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

using System.Globalization; // class CultureInfo
using System.Resources; // class Thread
using System.Threading; //

namespace WpfApplication1
{
///
/// Interaktionslogik für MainWindow.xaml
///
///

public partial class MainWindow : Window
{
static string[,] culture = new string[,] { { „ar-SA“, „Arabic“, „Saudi Arabia“ }, { „de-DE“, „German“, „Germany“ },
{ „en-UK“, „English“, „United Kingdom“}, // { „en-US“, „English“, „United States of America“},
{ „no“, „Norwegian (Bokmål)“, „Norway“}, { „sv-SE“, „Swedish“, „Sweden“},
{ „tr“, „Turkish“, null } };
static string[] label = new string[] { „Caption“, „Message“ };

static short selectedCulture = 1; // de-DE
ResourceManager rm = null;

public MainWindow()
{
InitializeComponent();
textBox1.AppendText(culture[selectedCulture, 1]);
Keyboard.Focus(btnMessage);
}

private void btnMessage_Click(object sender, RoutedEventArgs rea)
{
const string METHOD = "MainWindow:btnMessage_Click: ";

try
{
DetermineResourceManager();

MessageBox.Show(rm.GetString(label[1]), rm.GetString(label[0]),
MessageBoxButton.OK, MessageBoxImage.None, MessageBoxResult.None);
}
catch (MissingManifestResourceException mmre)
{
MessageBox.Show(METHOD + "Exception: " + mmre, „Error“);
}
catch (Exception e)
{
MessageBox.Show(METHOD + "Unexpected exception: " + e, „Error“);
}

SwitchLanguage();
textBox1.Text = culture[selectedCulture, 1];
}

private void DetermineResourceManager()
{
const string METHOD = "MainWindow:smiley:etermineResourceManager(): ";
string path = „C:\Documents and Settings\z002zatp\My Documents\Visual Studio 2010\Projects\“ +
„WpfApplication1\WpfApplication1\obj\x86\Debug\“;
string resource = „WpfApplication1.Resource.“ + culture[selectedCulture, 0] + „.resources“;

System.Reflection.Assembly assembly = null;
//MessageBox.Show(METHOD + "Resource to be loaded: " + path + resource);

try
{
>>> assembly = System.Reflection.Assembly.LoadFile(path + resource); = culture.Length/3)
selectedCulture = 0;
}
}
}
______________________________________________________

Hi,

have you checked the version of loaded CLR and the compiletarget in the IDE? This error may occur if you compile for .net 3, 3.5 or 4 while the CLR 2 (or more general: a version smaller then the compiletarget) is loaded.

Another possibility is, that the file even doesn’t contain a regular CLR-ressourcefile. You may analyse the parameters of the exception as described here: http://msdn.microsoft.com/en-us/library/system.badim… for detailed information about the reason.

Hope, that helps…

Bye

Thanks for your reply!

Good tip that I would follow, if I knew how to check it. There is no hint in the menu (Extras / Options), and I do not know where to find the current CLR version and the compiletarget.

Best regards

Hi,

have you checked the version of loaded CLR and the
compiletarget in the IDE? This error may occur if you compile

Solution found for my problem
Here is the solution of the problem I got from another site:

///
/// Interaktionslogik für MainWindow.xaml
///
///

public partial class MainWindow : Window
{
static string[,] culture = new string[,] { { „ar-SA“, „Arabic“, „Saudi Arabia“ }, { „de-DE“, „German“, „Germany“ },
{ „en-GB“, „English“, „United Kingdom“}, // { „en-US“, „English“, „United States of America“},
{ „no“, „Norwegian (Bokmål)“, „Norway“}, { „sv-SE“, „Swedish“, „Sweden“},
{ „tr“, „Turkish“, null } };
static string[] label = new string[] { „Caption“, „Message“ };

static short selectedCulture = 1; // de-DE
ResourceManager rm = null;

public MainWindow()
{
InitializeComponent();
textBox1.AppendText(culture[selectedCulture, 1]);
Keyboard.Focus(btnMessage);
}

private void btnMessage_Click(object sender, RoutedEventArgs rea)
{
const string METHOD = "MainWindow:btnMessage_Click: ";

try
{
DetermineResourceManager();

if (culture[selectedCulture, 0].Substring(0, 2) != „ar“)
{
MessageBox.Show(rm.GetString(label[1]), rm.GetString(label[0]),
MessageBoxButton.OK, MessageBoxImage.None, MessageBoxResult.None);
}
else
{
MessageBox.Show(rm.GetString(label[1]), rm.GetString(label[0]),
MessageBoxButton.OK, MessageBoxImage.None, MessageBoxResult.None,
MessageBoxOptions.RightAlign | MessageBoxOptions.RtlReading);
}
}
catch (MissingManifestResourceException mmre)
{
MessageBox.Show(METHOD + "Exception: " + mmre, „Error“);
}
catch (Exception e)
{
MessageBox.Show(METHOD + "Unexpected exception: " + e, „Error“);
}

SwitchLanguage();
textBox1.Text = culture[selectedCulture, 1];
}

private void DetermineResourceManager()
{
const string METHOD = "MainWindow:smiley:etermineResourceManager(): ";

string resource = „WpfApplication1.Resource.“ + culture[selectedCulture, 0] + „.resources“;

try
{
Thread.CurrentThread.CurrentUICulture = new CultureInfo(culture[selectedCulture, 0], false);

rm = new ResourceManager(„WpfApplication1.Resource“, Assembly.GetExecutingAssembly());
}
catch (Exception e)
{
MessageBox.Show(METHOD + ", unexpected exception: " + e);
throw e;
}
}

private void SwitchLanguage()
{
if (++selectedCulture >= culture.Length/3)
selectedCulture = 0;
}
}
}

Hi,

I haven’t dealt with multilinguality yet, but I might give some hints though.
First of all the resource manager handles the selection of resource files by itself. That’s why there are naming conventions (at least as far as I understand it).
Why are you trying to load a new assembly in the DetermineResourceManager()? Resource files are part of your assembly. You only have to load a new one, if you are trying to access these from another assembly. But in your case that should not be the case. Don’t use the full path to the resource file and don’t use the complete name. Instead try:

ResourceManager rm = new ResourceManager( "myresources", Assembly.GetExecutingAssembly() );

With „myresources“ being the name of your resource files (without extensions). That should suffice as long as CurrentCulture and CurrentUICulture are set to the correct one.

Nico

http://msdn.microsoft.com/de-de/library/ms745650.aspx

Hello, I never worked with multi lingual resources, so I can’t give you any advice. Sorry.