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?
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.
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)
Related
I'm using an embedded resource generated by 'PublicResXFileGenerator' which generates my ResourceManager class.
I'm trying to find a way to support multiple resx files for the same language or in some way being able to modify it from a deployed application but this doesnt seem possbible.
For example client 'x' is using the en-US translation:
Flat
and the other client 'y' are using the en-US translation:
Appartment
Maybe the above example is stupid but I hope you get my point.
Different users are using different namings for the same thing and I'd like to support this.
Is it possible?
Note:
My code is written in C#.
The strings in your default resource file (probably Resources.resx) are embedded in your executable file.
If you define a language specific resource file (e.g. Resources.en-US.resx) then Visual Studio will automatically generate a satellite DLL containing the localized resources.
The same applies if you add localized resources to a WinForms form, as shown here for Form1.
The satellite DLL is generated in a sub-directory of the bin directory.
The DLL must be deployed on the target machine in a sub-directory with exactly the same name.
This works for localized strings in any language, but it works exactly the same for strings in the current default language.
If the current default is en-US, and there is a satellite DLL for en-US, and it contains the required resources, then the .NET Framework will automatically use resources from the satellite DLL.
If you don't want the resources from the satellite DLL, no problem. Don't deploy it to the target machine. Then the .NET framework will use the default resources which are embedded in the executable.
If you only have two variations, then it is easy to manage in Visual Studio using the default resource file and an en-US resource file. If you have more than two variations, you are going to need a strategy to generate the resources. The simplest way would probably be to misuse another language.
Alternatively, you could use some other tool. Winres might do the job, but I'm not 100% sure.
Technically, you can define custom cultures, e.g. en-US-medical, or en-US-legal, but in my experience that is more bother than it is worth. I don't think (just my opinion) that Microsoft is strongly committed the concept.
I have an app on Windows Embedded which uses .resx files to translate the app to different languages.
Also I create an installation .cab file but I can't include the resx file to this cab.
How can I achieve this?
Thanks for any tip
A few things:
You'd not told us how you're trying to add the file. Are you using a custom INF file and just calling CABWIZ or are you using a Visual Studio Installer Project?
What have you done to try to include the file?
Most importantly, a RESX file does not contain the run-time resources and you rarely would deploy it. The RESX resources get compiled into a *.resource.dll assembly, that is typically in a subfolder with a name for the locale (e.g. en-us or fr-ca). You need to deploy those files/folders which is challenging because CABWIZ doesn't allow duplicate file names (and all resources have the same file name, just different folders). That scenario is handled by this SO question.
I have my auto generated Resource.resx file set up with keys and strings. I also have three other resx files for German, French and Spanish given to me from translators. I'm not able to get the localization functioning and I suspect that the resx files aren't being called correctly. I added them to the project by dragging them into the solution explorer under "Properties". I have a nagging suspicion that just dragging them in isn't creating the proper connections behind the scene.
Now It's totally possible my issue lies somewhere else. If anyone can tell me whether it's ok to add resource files this way or if not, what the correct way is, it would save me tons of time spent chasing my tail. Thanks!
Resx files in Visual Studio include a special tool which is run at build time and translates them into embedded resources. Right-click your original VS-created resx file and click Properties. You should see Build Tool or something similar. Also note the resource type (Embedded, etc.). Make sure that you match these settings for your manually added files.
Once this is set up, you will need to use the CurrentUICulture property to tell .NET to pick up the appropriate resources. You can choose to change the culture/language at install-time or run-time. Here is a comprehensive tutorial which describes the various options available to you:
WPF Localization Using RESX Files
That said, as a best practice, translated Resx files are generally deployed as satellite assemblies. The main application DLL/EXE contains only the language neutral resources file. Other resource files are compiled into separate assemblies and deployed side-by-side with specific naming conventions. This allows you to dynamically add translations, localizations, etc. even after the application is deployed. Here's an introduction: Packaging and Deploying Resources in Desktop Apps
When you create a new C# Windows Forms Application in Visual Studio 2012, It has a Properties folder containing a Resources.resx file.
How do I access this file?
I have tried:
ResourceManager rm=new ResourceManager("Resources.resx",typeof(MyClass).Assembly);
string s=rm.GetString("MyString");
But I get System.Resources.MissingManifestResourceException because for some reason it appends .resources to the filename so it's looking for Resources.resx.resources.
I then appended .resources to the filename to see if it might actually work. It didn't, same exception, why?
I also tried using the ResxResourceReader class but it looks for a resx file in a directory, and this specific resx file I'm trying to access is not stored in a directory, it's compiled in to my assemblies so that doesn't seem to be helping either.
I thought it'd be really simple, maybe it is and I'm just overlooking something?
If it's not simple, I might as well create a C# class and hard-code my strings (only type of resource I need right now).
And another question: If the resx file is compiled in to your exe, does that mean you can't change it's values during runtime?
It is plain simple (usually).
Use the Properties class!
Properties.Resources.MyString
The Properties folder you see in your Solution Explorer is not just a fancy folder ;p Visual Studio generates a class to access all your resources with ease.
I've added a bunch of files from my older project into my new project. They're still not playing an active role in my current code and there are missing classes that won't make them fully functional anyway, I just want them there so I can gradually rework each file to be compatible with my newest code. Is there a way tell the compiler not to pay attention to these C# files and report errors?
P.S: I'm using SharpDevelop
Have a look on the File Properties for
BuildAction Property
The BuildAction property indicates what Visual Studio does with a file when a build is executed. BuildAction can have one of several values:
•
None - The file is not included in the project output group and is not compiled in the build process. An example is a text file that contains documentation, such as a Readme file.
•
Compile - The file is compiled into the build output. This setting is used for code files.
•
Content - The file is not compiled, but is included in the Content output group. For example, this setting is the default value for an .htm or other kind of Web file.
•
Embedded Resource - This file is embedded in the main project build output as a DLL or executable. It is typically used for resource files.
use c# preprocessor directive #if then put that conditional variable inside Compiling/General/Conditional Compiling Symbols
http://msdn.microsoft.com/en-us/library/aa691099(v=vs.71).aspx
Although it is possible to give specific compiler instruction, I'd remove the files from the solution and put them somewhere safe in version control.
Having these files in the solution can easily be confusing when browsing the sources; I would not expect to have to check the BuildAction property of C# files to find out whether or not I am looking at something that is part of the build.
I read a lot of code in a source control viewer (looking a delta's and history), compiler options are not very obvious in environments like these.
Put them safe in source control and remove them from the build.