Why does my localization only work on my Development-Machine? - c#

I've localized my App in two languages (English and German) with the MulitlingualAppToolkit 4.0. English is the base language, while german is a translation based on the english one.
The translations are stored as resw-file inside folder "strings.en" and "strings.de".
In App.xaml.cs App() I set the culture like this:
Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = GetCurrentCulture();
CultureInfo.CurrentUICulture = GetCurrentCulture();
private CultureInfo GetCurrentCulture()
{
var cultureName = new DateTimeFormatter("longdate", new[] {"US"}).ResolvedLanguage;
return new CultureInfo(cultureName);
}
(I got this quiet weird way to the regional-culture in Windows 10 from this article https://www.pedrolamas.com/2015/11/02/cultureinfo-changes-in-uwp/ since I recognized that CultureInfo.CurrentCulture and CultureInfo.CurrentUICulture are always "en-EN" no matter what i configurate in my machines regional- and language-settings)
To check if PrimaryLanguageOverride works as expected, I added a TextBox by the name of tbTest on my first Page and a button linkt to this event:
private void Button_Click(object sender, RoutedEventArgs e)
{
Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = tbTest.Text;
Frame.Navigate(this.GetType(), 0);
System.IO.File.AppendAllText(System.IO.Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "PrimaryLanguageOverride.txt"),
DateTime.Now + " - Actual PrimaryLanguageOverride:\n " + WIndows.Globalization.ApplicationLanguages.PrimaryLanguageOverride);
}
catch(Exception ex) { Helper.Log.LogUnhandledError(ex); }
}
Now comes the weird stuff:
When Debugging, or executing the App from my Development-Machine, everything works as expected, but when I make an appx-bundle and install it on another (Windows10-Desktop) device, the App does not recognize the its Language.
In my situation, the device is set to german, regional as well as its language. Also when using the test-procedure, it defenetively gets the string I set , as long as it's a valid culture-name, e.g.: "en-EN", "en-US", "de-DE", "de", "en" (all of these are working fine on my development machine) if it's an invalid string, I get an exception, with a log-entry in my unhandled-error-log. It refresh the Page, and even writes the new-set language in my PrimaryLanguageOverride-Log, but it doesn't change any text I did translate.
So my question is, is this a common Issue (since I recognized in UWP/Win10 the culture-system is a little messed up) or do I use the wrong procedure to override the App-Culture?

This is an issue with AppXBundling. When Installing bundles, it checks with the current OS for the installed Language packs and copies the relevant language resources from the bundle and omits the other language files. The objective of a single bundle is to copy necessary resources and build the application and therefore the languages which are not in the system are considered irrelevant. As a fix you could stop generating single bundles and create package for each CPU architecture. Check this for more info

Related

Windows Forms Localize resx without changing Culture

I know it's easy to localize Windows Forms App: set Localizable=True, change Language and set text in Controls for every Language. This information saves in resx-files and application will automatically select the required file. Great!
I know about disadvantages of this solution (you need to rebuild the app if there a typo, it's impossible to change language in runtime, etc), but it's not a problem for me and "resources" is the simpliest, built-in solution.
But this mechanism uses the property Culture of app's thread.
My app is the part ("plugin") of the bigger application and works in the same Thread.
The main application is multilingual too, but it doesn't use Culture to change interface's language. I can change the thread's culture globally, but it crushes the main app's interface.
So my question:
is it possible to manually set the resx-localizable resurce file that will be used? Not based on Culture, but, for example, on some variable in my app:
if (this.Language == "fr")
this.Resources.Add("Form1.fr.resx");
else
this.Resources.Add("Form1.en.resx");
Or something else.
Thank you!
My sandbox:
https://github.com/Tereami/WindowsFormsTestLanguage
The built resources file has a property ResourceManager that's used to return the desired content. This has an overload with a CultureInfo parameter. You can use it to request resources in individual languages:
var desiredCulture = new CultureInfo("en-us");
var text = MyStrings.ResourceManager.GetString(nameof(Resources.ExitMessage), desiredCulture);
If you want to set the culture globally for your resource file, you could also set it through the corresponding property:
var desiredCulture = new CultureInfo("en-us");
MyStrings.Culture = desiredCulture;
var text = MyStrings.ExitMessage;

ASP.NET localization stopps after around 60 minutes

We have an application based on ASP.NET MVC 5.2 and we're using localization with Resource files (resx), Localization.resx, Localization.de-DE.resx, Localization.de-AT.resx, Localization.en-US.resx, Localization.en-GB.resx... etc etc which produces satellite assemblies.
We determine the language first by cookie and then as fallback by browser header information. Works very well.
protected internal void Application_BeginRequest(object sender, EventArgs e)
{
HttpCookie cultureCookie = httpRequest.Cookies[CookieName.Culture];
string cultureName;
if (cultureCookie != null)
cultureName = cultureCookie.Value;
else
{
if (httpRequest.UserLanguages != null && httpRequest.UserLanguages.Length > 0)
cultureName = httpRequest.UserLanguages[0];
else
cultureName = null;
}
cultureName = CultureHelper.GetImplementedCulture(cultureName); // returns default on null
Thread.CurrentThread.CurrentCulture = new CultureInfo(cultureName);
Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;
}
We use the Localization.PropertyName directly in views like
<div class="text-right">#Localization.Header_TopMenu_Service</div>
This works fine so far but after around 60-80 minutes we have a problem on just one environment (productive): the localization does not work anymore.
It effects just these textes! The thread still has the correct culture!
Internally we still work with the Thread.CurrentThread.CurrentCulture values like for static texts, calculations of taxes... and this still works.
So some parts of the application are now in english (static stuff and logic stuff like calulcation of taxes) and all elements from the Localization resources are in german (default).
Why can this happen?
We thought there is something with race conditions but we've embedded some information to the output and everything is fine:
<!--
CurrentCulture == 'en-GB'
CurrentUICulture == 'en-GB'
ManagedThreadId == '25'
IsThreadPoolThread == 'True'
-->
Even if the language in this output is en-GB the localization outputs our default ,which is german.
When we restart or recycle the application, the localization works for again 60 minutes.
We also tried to set the language via Filter or in the Controller: same issue.
What can be the reason for this weird issue?
Wrong implementation? Something with satellite assemblies? IIS issue? system configuration?
Because everything works fine on the test stage and this effects just occur on the prod (no new build, just a copy) I think it is something with the system.
Problem is solved.
It was a race condition which set Localization.Culture (or in other implementations Resources.Culture) globally to a specific language.
The problem was, that this should be null in web applications. If this is null, ResourceManager.GetString() uses Thread.CurrentThread.CurrentUICulture for localization.
If Localization.Culture is not null the ResourceManager does not care about Thread.CurrentThread.CurrentUICulture.

Currency Symbol Display Is Incorrect

The currency symbol and currency format for this language code is displaying incorrectly when called through C# on a server.
ms-MY (Malay - Malaysian)
The language display on the control panel on the server has the currency symbol set to RM. While debugging the C# code, it has the currency code set to R.
I wrote up a mini console program locally to display the currency symbol for ms-MY and it shows up as RM.
If I change the formatting on the server. The code doesn't pick up the changes. Anyone knows if there are weird server caches or another place that language settings are stored?
I've checked the language registry key between the server and my local machine and they are the same. I tried recycling the application pool and it still doesn't work.
Pseudo Code on the server
foreach (CultureInfo c in CultureInfo.GetCultures(CultureTypes.InstalledWin32Cultures))
{
if (c.ThreeLetterISOLanguageName != "IVL")
{
r = new RegionInfo(c.LCID);
if (r.ISOCurrencySymbol == isoCurrencyCode)
{
ci = c;
FoundCode = true;
break;
}
}
}
Mini Console Code for testing locally.
decimal amount = 179835.00M ;
Console.WriteLine(amount.ToString("C", CultureInfo.CreateSpecificCulture("ms-my")));
Note when I add this to the watcher on the server code: CultureInfo.CreateSpecificCulture("ms-my"). The currency format display as R. But if I look at the watcher on my local console code nothing related to the server, it's set to RM

Internationalize Windows Phone 7 App

I am currently working on a windows phone application that takes some information from the user and returns some other information based on the user input.
The application works great if the specific device has its region settings set to US. If the region settings of the device are set to Greek or German, some problems occur. For example, the US decimal point character "." is considered as "," and vice versa. As a result, all the calculations are false.
What I want to do is internationalize the application so that it works exactly the same no matter what the regional settings are. Is this possible?
If you want your app allways to show number and dates in one specify format you can force the app to allways run in one specify culture like this.
You just have to set the current thread of your app to one specify culture (add to the App.cs file)!
public App()
{
// Standard Silverlight initialization
InitializeComponent();
// Phone-specific initialization
InitializePhoneApplication();
// Set the current thread to US!
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");

Mysterious Resources /CultureInfo behaviour in WPF App

i have two Resources files in the Properties folder of a WPF-project (VS 2008):
Resources.resx
Resources.de-DE.resx
Selecting the culture "de-DE" does not work (no error, but always the strings from "Resources.resx" are used):
public App()
{
UntitledProject2.Properties.Resources.Culture = new CultureInfo("de-DE");
}
BUT: if I rename "Resources.de-DE.resx" to "Resources.fr-CA.resx" or "Resources.en-US.resx"
and then set it via
UntitledProject2.Properties.Resources.Culture = new CultureInfo("fr-CA");
it works!! But why!? Mysterious...
By default, WPF will always use "en-US"; at least it did the last time I checked (which was .net 3.5). If you want WPF to instead use the culture currently set by the system, you would execute this code block:
FrameworkElement.LanguageProperty.OverrideMetadata(
typeof(FrameworkElement),
new FrameworkPropertyMetadata(
XmlLanguage.GetLanguage(
CultureInfo.CurrentCulture.IetfLanguageTag)));
This will override the default value used for the FrameworkElement's Language dependency property, which, again, is "en-US" by default.
Execute this code once and early on in the lifetime of your application. AFter that, you shouldn't have to worry about it again, unless you expect your user to be switching the culture in the middle of program execution...

Categories

Resources