10

My problem is this: Using MonoDevelop (which is the preferred environment for a number of projects I'm working on) I'm trying to figure out how to use resource files for localized messages and how to properly include them in the project as an embedded resource.

My goal is to have a resources file with simple name-value pairs for message keys and their values, and have separate files for their localized strings e.g.

Messages.resources

Hello.World = Hello World
Goodbye.Cruel.World = Goodbye, Cruel World

Messages.de.resources

Hello.World = Hallo Welt
Goodbye.Cruel.World = Auf Wiedersehen, grausame Welt

I'm having a couple of issues.

First, what is the difference (if any) between MonoDevelop's .resources file and Visual Studio's concept of resources. From what I understand, MonoDevelop (and SharpDevelop) allow you to create .resources files, whereas Visual Studio utilizes .resx files and compiles them into .resources files (a binary file type) through the resgen utility. When using resources in MonoDevelop do I need to compile my resources (e.g. Messages.resources) using resgen? When I try to use just the straight .resources files that MonoDevelop allows me to create through their wizard I get the following error:

"Stream is not a valid resource file."

Second, once I have an appropriately generated resource file, I can embed them to my project, which if I understand it correctly, makes the resources a part of the assembly. If I have two files though, Messages.resources and Messages.de.resources, MonoDevelop (at least) assigns them the same ID value when I embed them. Do I need to have my default localization included in the project and then a separate project for each supported locale? Following up on this, how does C# distinguish between my Messages.resources and Messages.de.resources files (or whatever files they are)?

I'm currently trying to resolve my message resources with the following code:

...
public string Translate(string messageKey, CultureInfo cultureInfo) {
    ResourceManager resourceManager = new ResourceManager("My.Project.Messages", Assembly.GetExecutingAssembly());
    string message = resourceManager.GetString(messageKey, cultureInfo);
    return message;
}
...

I feel like I'm missing some fundamental points in the effort of internationalization/localization/globalization etc. with C#. I have worked on internationalized projects in Java before, but for some reason I can't quite wrap my head around it in C#.

Also, as an aside--what is the "preferred" directory structure for resources in an internationalized project?

2 Answers 2

3

I'm not familiar with .NET localization (I use gettext), but as I understand it, .resources files are a binary format that's actually embedded into your dll. You can compile resx (XML) or text resources into the binary format using resgen. Text files are more readable but can only be used for string resources. XML is more verbose but can represent everything that binary resources can.

The usual thing is to store your resources in .resx form in the project, and MonoDevelop will automatically compile them into .resources files when building your project (you'd have to compile .txt files manually). Unfortunately MD doesn't have special editing tools for resx files, so you'd have to edit the XML directly.

MD does have nice localization tools for gettext, but these aren't currently supported on Windows.

4
  • So, it sounds like if I didn't want to use gettext (which honestly sounds like the simplest and most straightforward solution to this problem), I could utilize .resx files similar to how Visual Studio utilizes them, and MonoDevelop will take care of the compiling of these into .resources files.
    – Sean Quinn
    Commented Jul 5, 2011 at 15:29
  • Can you speak at all to what the relationship is between .resources files that MonoDevelop allows you to create via the New File > Misc > Empty Resource File option and either .txt, .resx, or .resources (binary) are with Visual Studio's similarly named file type? I assume that MonoDevelop's empty resource file is closer to a .txt file than it is to .resx (still, just a text file ultimately, I know) or a binary .resources file. Thanks for any insight you can give to this, its really caused a lot of confusion for me.
    – Sean Quinn
    Commented Jul 5, 2011 at 15:30
  • The blank .resources file looks like it was inherited from SharpDevelop, which did have an editor for binary resources. If it opens in the text editor that's probably a bug. Commented Jul 5, 2011 at 21:29
  • It sounds like it may be a bug then, its opening the .resources file in the text editor of MonoDevelop. That's good to know that SharpDevelop had support for binary .resources files and this is likely a throwback to the SharpDevelop code which MonoDevelop inherits from. At least it clears up some of the confusion, thanks!
    – Sean Quinn
    Commented Jul 5, 2011 at 22:35
0

is there a reason of not using Gettext?

(E. g. you want to be compatible to VS? If not, this worked for me: http://monodevelop.com/Documentation/Localizing_Applications)

8
  • As I understood it, Gettext had some limitations on the Windows environment according to MonoDevelop's own admission. Or, at least, the tools for editing translations and updating them were only accessible from Linux. Are these limits still there, and how real are they? Gettext seems like it should be sufficient for what I need after reading that, but I need to dig a bit deeper.
    – Sean Quinn
    Commented Jul 4, 2011 at 20:38
  • Yes, the msgmerge and msgformat tools aren't normally found on Windows, so MD doesn't include the Gettext addin on Windows. However, Windows versions of these tools do exists, so if you put them in your PATH and copy the addin over, it should work. Commented Jul 5, 2011 at 11:16
  • @mhutch I'm running MonoDevelop 2.6 beta 3, and it appears that the Translation project is available to me in my Windows environment. It looks like as of 2.2 it wasn't supported, as of 2.6 is it now supported?
    – Sean Quinn
    Commented Jul 5, 2011 at 16:06
  • @mhutch ... also, am I right to assume that the "fallback" text in a Gettext implementation for localization also acts as the identifier in .po files, living in the source code? Doesn't this approach tightly couple the actual text to the source code? On Java project's I've worked on, we have very simple key-value pair text files that are only coupled to the application by way of their key identifiers, all text and translations are in these text files (never in the actual source); allowing translators to stay out of the source. It doesn't look like Gettext typically works this way.
    – Sean Quinn
    Commented Jul 5, 2011 at 16:40
  • I don't think it's officially supported, but it may have been included by accident. You might hav to get hold of msgfmt and msgmerge binaries from somewhere. Commented Jul 5, 2011 at 21:32

Not the answer you're looking for? Browse other questions tagged or ask your own question.