Different resx for different deployments c# - c#

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.

Related

Proper procedure to import existing RESX files into a C#/WPF project

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

How can I swap resources for different versions of an application?

I developing an application which will have at least 2 if not 3-4 different versions (don't ask). The applications will basically be identical except have different product names, window titles, application icon and some other minor differences in string or image resources.
My main goal is to avoid having to create multiple projects for each executable. I want to be able to have one main application project and have it just load those resources (name, icon, etc.) and be agnostic of which version it is. This way, I can simply configure my setup project to deploy the proper resources with the version of that application. Ideally it would not be that visible to the end-user after it was installed.
What I've tried: I've experimented with creating different .resx files and swapping them based off build configuration, or I've also experimented with adding environment variables and #if on the variable. But, I really do not want multiple build configurations. I want it to only depend on deployment.
Is it possible to create resx files, either in a different project or in the same project and exclude them from the build, and have them generated into satellite .DLL assemblies similar to localization, and then load whichever one is deployed with the application?
I'm confused if I should be looking at running my own RESGEN and AL tasks, or if I should just create a DLL project (but maybe then I'd have to have multiple DLL projects for only 1 resource file). Also, any article I can find about using .RESX files is for localization. It relies on setting the CurrentCulture to resolve the specific resources to use. My scenario has nothing to do with culture... I just want to load different resources for different deployments of the application.
Without knowing how deeply you need to go, you can package the resources into separate .dll files and differentiate that way. For instance, building the various different versions into a seperate DLLs and having your installer adjust the name to match what your application expects or use an XML configuration file to specify which to load and load it that way.
Assembly.Load() will allow you to load the alternative assembly.
Assembly _assembly;
_assembly = Assembly.GetExecutingAssembly();
Stream _imageStream;
_imageStream =
_assembly.GetManifestResourceStream(
"ThumbnailPictureViewer.resources.Image1.bmp");
Bitmap theDefaultImage = new Bitmap(_imageStream);
See: http://www.attilan.com/2006/08/accessing-embedded-resources-using.html

C#, Localization, Resources, and MonoDevelop

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)

Localization in Class Library

I would like to localize my c# class library
The library will output a .dll file, which I will distribute to .net application bin folders.
I want localization in the class library but I do not want to have to recompile the DLL each time a localization change is required.
So ideally....
have c# class with resx files outside the assembly, so that when the contents of the resx changes, all that should be required is that the asp.net host application might require a restart.
Best case scenario, is that the asp.net host application doesn't require a restart.
Thanks in advance for your advice - the resx file will just hold string values.
If possible I would like to do this using a best practice method, or at least without writing a whole custom localization solution.
Check this stackoverflow question.
Is there any performance difference in using .resx file and satellite assembly?
Looks like you can have a seperate resource dll.

Localization using msi file

In my application I want to support 2 languages (English and Arabic). For now I throw the English version of the help file in a certain path. What if I want the user choose the language he wants to install his application with and according to choose I'll throw the related chm file in that path.
Also another part of the Q, can I do something like when you install an application it asks you the language then it throws only the related exe file?
You didn't tell how you achieve localization in your application. Since you are developing in .NET I assume that you have a .resx file for every language containing all localized data. So why not install both help files and make the path to the help file a localized string in the resource file?
By the way, using localized resource files you will only have one executable to install. You can choose during the loading of your forms which language will be using by specifying the CultureInfo.CurrentUICulture accordingly, e.g. based on a config setting or registry key.
Concerning the second part of your question: You can have your user select the target language. This would set the config setting or registry key described above. However, changing the language during installation would not change the UI language of the MSI installer (I don't think this is supported *).
I would therefore recommend you to have a separate installer for each language or use a different install system (NSIS seems to be a good choice).
*) MSI can select the UI language automatically based on the Regional Settings defined for the user. However, this behaviour is not officially supported and teh way to achieve it is also a little complicated.

Categories

Resources