My app has been designed to be able to run on two different languages, english and czech. In order to accomplish this, I've created 2 resource files:
If an end-user would like to add another language, for example GlobalStrings.fr-FR.resx, is it possible to allow for this functionality without rebuilding the application?
If we look at the properties of these resource files:
I'm not understanding what embedded resource means. Does this mean that in order for the app to consume this file, the application must be rebuilt?
How do we create a resource file, that is open to be extended/changed by the end user, without having to rebuild the entire application
?
Regular .Net resources are compiled into assembly with particular name and loaded by matching that name. So if "end-user" is ok to translate strings in resx file and compile resources into assembly with particular name (like "MyResources.cs-cz.dll") you can do that with default .Net behavior without recompiling main code. See MSDN:Packing and Deploying resources and related links for more information.
Note that you don't need Visual Studio for it and can use csc command line compiler to embed resources on user's machine - so if your really want you can provide simple script that compiles corresponding resx locally. Note that editing XML (resx) as text is generally not possible by regular person due to required encoding of some characters - consider technical level of your "end-users" before going that route. Plain text version of source for resource may work in more cases.
Usually this is not the case - if end-user localization is requirement you would create some sort of custom resource string management by loading strings from plain text files or database that users can update locally.
I have an application with an existing Form that has images on each ToolStripButton at the top. These images are in the resx file and look as though they are only available to this Form. I want to make another Form with the same images.
What is the proper way to import these images so that all my Forms can use them. For example, the Save and Open buttons will be on most of the Forms.
In a big project at work we have a solution that has many projects with user controls and forms. That is why we have one extra project called Resources that holds different kind of resources (separate resource files) for the whole solution:
strings (translations)
images
property names
and so on
We reference the project to every other project in the solution where a resource is needed. This way the resources are kept separately, the dll can be easily replaced and nothing will be broken, as long the same resource names are used.
We also use the dll assembly in complete different projects(solutions) where we need for example the same images. When named correctly (for example Company.Resources.dll -> Company.Resources.Images.Toolbar.Add/Remove/Settings) it fits very well into every new project.
In your case it is of cource possible to reference ProjectA in ProjectB in order to use the same resources (as long the projects are in the same solution), but it could be that this will be not always possible (for example in order to avoid circular references).
Create new WinForm solution (in my example one solution with two projects). Add new project of type Class Library:
Add new resources to the resources project (in my example for strings and images):
Adding a resource file for images:
Add some images:
Now reference the resources project from the other projects:
Important => In order to use the resources from outside the assembly, you need to set the visibility to public:
Compile the solution once and use the references resources project from everywhere:
I have this problem:
I made a C# WPF (.NET Framework 4.0) application and everything is ok. Now I want to obfuscate it. I tried with Confuser.
The question is:
If the app is published I can see the main exe file and dll-s. So I tried to obfuscate the exe. Where should I put the obfuscated .exe generated file (I obfuscate only the main exe file). I mean Confuser creates a folder called "Confuser" with the obfuscated exe in it.
If I doubleclick the obfuscated exe to start the app as usually it doesn't work and I get the normal application crush window.
I also tried to replace the original exe file (in the app folder) with the obfuscated one (from Confuser folder).
If the app is deployed I have the setup.msi pack or setup.exe. How should I obfuscate in this case ?
Thankx,
Adrian
All XAML-based platforms (WPF, Silverlight, Windows Phone) are quite problematic area for most obfuscators. The main problem is that XAML references types and members by name. No wonder the applications often doesn't work after obfuscation: the integrity breaks.
There are two ways that are used by obfuscators to keep the output assembly work afterwards:
Search XAML content for everything that could be a type or property name and then roughly exclude all members that anyhow match these names. This doesn't give 100% guarantee that the application is not broken while makes the obfuscation coverage poor because of the inaccurate analysis. Still this approach can potentially save your application from breaking.
Do something similar to what XamlReader does: load XAML tree and find all matching CLR types and members. After renaming all the changes are synchronized with XAML. This approach gives the best reliability and coverage (types and members are renamed both in the code and XAML). There are obfuscators on the market that claim that they support XAML renaming. You may want to try some of them.
There is also a workaround. Most obfuscators support conditional obfuscation allowing to manually exclude specific types and members. You should manually exclude all the types and members that are somehow referenced by XAML. This will take some time but usually works.
First, you obfuscate your main .exe file and replace the old one. Then you pack everything into installer.
Also make sure all the properties and types involved in xaml are declared as public. Or tell the obfuscator to ignore them somehow.
I'd experiment with a simple console app first. Make sure you can get it working with that.
Then I might progress to a simple WPF app.
The problem with WPF and obfuscation is it relies on reflection. The View Models are bound by name. It could be this obfuscator isn't sensitive to this, or you need to configure it to ignore the names of properties on your view models.
If you've any other reflection using name, that could break it too. Even a Enum.Parse call can be tripped up. Maybe you seralize to/from XML, that is also a point it could break at.
You may want to display the exception that the app is crashing with to help you debug, but I would get comfortible with the tool myself with simple apps to work out how it gets around the above issues.
I have a project that contains a number of DLL files that contain Form resources which all go through translation/localisation (l10n).
For example, a DLL includes SomeForm.cs, which includes plenty of code functionality. The DLL also contains tranlsated versions of SormForm: SomeForm.resx, SomeForm.fr.resx and SomeForm.ja.resx (Default Language, French and Japanese translations).
The localisation group has asked for all of the resources to be placed into one library to reduce their overhead.
How can I move the form resources to a single DLL whilst keeping the code that implements the form in it's current DLL?
I don't want to move the functionality/code to a single DLL, which I think is what's being suggested here: Moving form resource files to a resource dll
Satellite Assemblies
Satellite assemblies are dll's which only contain resource files.
MSDN Article is very confusing. This article should give you a good understanding about the concept.
http://www.codeproject.com/Articles/59193/Localizing-a-Windows-Application-with-Satellite-As
Edit: Dynamic Layout for windows forms.
How to: Support Localization on Windows Forms Using AutoSize and the TableLayoutPanel Control
Walkthrough: Creating a Layout That Adjusts Proportion for Localization
Code Listing
How to: Design a Windows Forms Layout that Responds Well to Localization
I have a WinForms application which I want to translate into multiple languages. However, I do not have any experience with localizing a WinForms app, and I find very contradictory information about this subject.
Basically, what I want is:
In the source code, I want only one file per language
This file gets compiled into the main application on compilation - no satellite assemblies or external data files after building the application
The user can select the language, I do not need/want auto-detection based on the operating system
This should mainly contain strings and ints, but also a CultureInfo
Most solutions I've seen either have one .resx file per Form and/or external satellite assemblies.
Do I have to roll my own?
Or is there something in the framework already?
.net Framework 3.5 SP1 if that matters.
Edit:
For the most part, Visual Studio already offers support for what I want, but there are two issues. When I set Form.Localizable to true I have this nice Designer support, but this generates one resx per Form. The idea of manually overriding it in InitializeComponent fails because it's designer-written code that will regularly be overwritten.
Theoretically, I only want to :
a) override the creation of the ComponentResourceManager to point it to my global resx and
b) change the call to ApplyResources to the overload that takes a CultureInfo as third parameter.
It seems as if I have to add a function call to my constructor that gets called after InitializeComponent() and overrides its behaviour. That seems terribly inefficient, but Visual Studio is right when it warns about touching InitializeComponent().
At the moment, I am indeed rolling my own WinForms localization Framework...
I've just completed a C# .Net 3.5 project with a similar problem. We were writing WinForms plugin for an existing multi-lingual application with 8 languages (including English).
This is how we did it:
Create all our forms and UI in the default language, English.
Put all our internal strings in a resource file (stuff not tied directly to a form like custom error messages and dialog box titles etc)
Once we had completed most of the work and testing we localised it.
Each form already had a .resx file but this was empty. We set the property 'Localizable' to true, the .resx file was filled with things like button sizes & strings.
For each of the other languages, we changed the 'Language' property on the form. We chose the basic version of each language eg: 'Spanish' instead of 'Spanish (Chile)' etc. so that it would work for every 'Spanish' dialect, I think.
Then we went through each control, translated its text and resized, if needed. This created a .resx per language and form combination.
We were then left with, for 8 languages, 8 .resx for each form and 8 .resx for the general strings. When compiled the output folder had the .dll we were creating and then a sub folder for each language with a .resources.dll in it.
We were able to test the versions of the UI in the designer by just changing the language property to check that we had the correct strings & layout.
All in all once we got our heads around it, it was quite easy and painless.
We didn't need to write any custom tweaks to the form loading
I was asking a similar question about ASP.NET and got a first answer - this tool and its workflow might also be something for you - have a look: Lingobit Localizer
It seems to be able to load your Winforms app and allows you to start translating your labels etc. and see the forms while you do it. Lots of other features, too, like incremental translation and translation memory (if you use the same terms over and over again).
Looks quite promising (for Winforms) - haven't used it myself, though.
Here's an extensive list of potential .NET localization tools - not sure, how well they work and what they cover - have a look, maybe you'll find what you're looking for.
Marc
I dont have a solution for your first and second requirement but keep in mind that localizing a form is not as simple as translating each word. You need to check that each translated text fits in their respective control. Also, maybe you have an icon or an image which need to be change in another culture.
For your point three, you can change the language manually with the following lines:
CultureInfo ci = new CultureInfo("fr");
Thread.CurrentThread.CurrentUICulture = ci;
This is a huge subject and there are many ways to accomplish what you want. The framework does provide the basis but a complete solution requires that you implement certain elements yourself.
For example the default framework implementation is to create a .resx file for every resource. In ASP.Net this means each user/server control or page. This doesn't lend itself to easy maintenance and if you want to move resources to a database you need to implement your own provider.
My familiarity with Winforms is limited but if you are using Silverlight or WPF then have a read of Guy Smith-Ferrier's work on the subject at: http://www.guysmithferrier.com/category/Internationalization.aspx. He also has some toolsets that can make your life easier at: http://www.dotneti18n.com/Downloads.aspx.
I've worked with him before and have never come across anyone else with a better depth of understanding of the subject.
What you are asking for:
no satellite resource files
only one size and control placement per form.
lots of languages embedded in the executable.
Is not do-able in vanilla Visual Studio's IDE.
What it would require is some custom work, basically fulfilling all these steps:
Acquire a custom resource manager that handles TMX resource files.
Put all your localizable strings in a TMX file.
Make this TMX file an embedded resource in your project.
In your Form constructor, create your TMX ResourceManager, loading the TMX file from your embedded resources.
In your code, use your tmx ResourceManager instead of the default ResourceManager for getting localized strings.
Let the Form use the default ResourceManager for getting all the designer things except the strings.
Get your TMX file fleshed out with the new language translations.
More can be added in the next release of your project, just by adding them to this TMX file before you compile.
RESOURCES: (not an exhaustive list, by any means)
http://en.wikipedia.org/wiki/Translation_Memory_eXchange
http://sourceforge.net/projects/tmx-editor/
The right way to do this is, suppose you want to add Arabic support witch is RightToLeft language:
Double click the form
Set localizable prop. to true
Change Language prop. to Arabic //This will automatically open a new version of the form so you can customize.
Set RightToLeft prop. to Yes
Set RightToLeftLayout prop. to True
Start renaming controls, and save the form.
Handle Messages/Errors in code // Sorry I don't have a quick solution for now, try duplicate them and If/Else the current local.