Windows Service Unable to get correct System Culture - c#

From Control Panel, I set my Region and Language setting to French (France)
When I am running my application as console application,
Thread.CurrentThread.CurrentCulture returns French
But when I'm running it as windows service, it returns invariant culture or English (US)
Is there a way to fix that?

The service is probably running as a user that has it's own culture.
Why not set the culture when you start your service
Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-FR");
Thread.CurrentThread.CurrentUICulture = new CultureInfo("fr-FR");
Also from Default Culture in a Windows Service
If your Windows Service is running under the SYSTEM account or other account without a
profile it will use the settings defined under the
"HKEY_USERS/.DEFAULT/Control Panel/International" registry key.
You can change these values from "Control Panel / Regional and Language Options / Advanced"
by checking the checkbox "Apply all settings to the current user account and to the default
user profile".
I normally use the former technique as I only need to change it for a specific service rather than for the whole OS.

.NET 4.5 added CultureInfo.DefaultThreadCurrentCulture and CultureInfo.DefaultThreadCurrentUICulture i suggest setting it as early as possible and it should solve your issue.
This will change the current threads culture and all threads that are created.

Related

CultureInfo not found locally, but found on dotNetFiddle

I have following code to detect whether culture name represents valid culture (I check it to proceed for report rendering in given culture).
try
{
this.Culture = new CultureInfo(cultureName);
}
catch (CultureNotFoundException)
{
// on exception default culture will be used
}
When culture is found, it is set to Culture and later used in report rendering. It works fine in most cases, but if I provide "en-NL" as culture name, the code throws exception on localhost (culture is not found) which is fine (report is rendered with invariant culture).
But if I deploy it remotely on Azure, culture is found and rendering of report fails (because it cannot find such culture).
I tried this code on dotnetfiddle. And there it also returns culture name. But LCID is 4096.
I googled what 4096 stands for and realized it is LOCALE_CUSTOM_UNSPECIFIED - so some culture created by user.
The question is why it behaves differently. I have .NET 4.5 installed on local and Azure too.
Another question is whether I can handle it in a way that if LCID is 4096 I rather use invariant culture to avoid the risk culture does not really exist.
NOTE:
I do not think it is duplicate of this question. I think it has nothing with case-sensitivity, it is about not recognizing particular culture locally and recognizing it on another server.

CultureInfo differences between IIS and IIS Express

I'm having some problems with CultureInfo values for a specific culture, "pt-PT". To narrow it down I created an MVC project in VS 2017 using .net framework and added the following line to the view About.cshtml:
<p>#(new System.Globalization.CultureInfo("pt-PT").DateTimeFormat.FirstDayOfWeek)</p>
This was the only change I made to the project created by visual studio.
When I run this project in VS using the IIS Express, the value returned by FirstDayOfWeek is 'Monday'.
However if I run this project in IIS (on the same machine), the value returned by FirstDayOfWeek is 'Sunday'.
I was expecting the value to be the same and to be 'Monday'.
I'm puzzled about the diference in values and would like some help in understanding it.
Note: After further tests I concluded that if I change the first day of the week in my computer settings, that change is reflected when running the project in IIS Express. I'm more confused... I guess this property is useless...
By default, IIS uses DateTimeInfo.InvariantInfo which returns Sunday as its FirstDayOfWeek value (also using United States date format too). If you're unsure why IIS (not Express) uses different culture than you're using, set the culture information in Application_BeginRequest handler inside Global.asax code:
protected void Application_BeginRequest(object sender, EventArgs e)
{
string culture = "pt";
if (HttpContext.Current.Request.Path.Contains("pt"))
{
culture = "pt"; // Portuguese, use 'pt-PT' if not sure
}
else
{
// set to other cultures, including invariant (default) one
}
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(culture);
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(culture);
}
Or use globalization element in web.config file to set Thread.Culture & Thread.UICulture:
<globalization culture="pt-PT" uiCulture="pt" />
If all of the above settings doesn't work, use these steps below:
Open IIS Manager, select your site and open ".NET Globalization".
Open "Culture" tab, set both Culture & UI Culture section to Portuguese.
Restart the application pool or use iisreset command to apply all changes.
NB: As a general convention, the site shouldn't rely on server's application pool setup to work as expected with specified locale/culture. See Set the Culture and UI Culture for ASP.NET Web Page Globalization for further details about culture settings.
Also check if the regional settings of your application pool set to follow NetworkService's user account, change it to LocalSystem if necessary.
Similar issues:
ASP.NET Application is displaying american date formats
How do you set the IIS Application Pool Identity User Locale when it's set to ApplicationPoolIdentity

Using custom combination of language and region for CultureInfo

I have a web application in which I set the CultureInfo on Thread.CurrentThread to ar-IL (Arabic-Israel):
Thread.CurrentThread.CurrentCulture = new CultureInfo("ar-IL")
The problem is that on my local machine (Windows 10 with IIS 10) it works just fine and no exception is being thrown. However, on Azure (Windows Server 2012 R2 with IIS 8.5) it throws CultureNotFoundException:
Culture is not supported. Parameter name: name 'ar-IL' is an invalid
culture identifier
I checked the source of CultureInfo and realized that the native call to nativeInitCultureData() is the culprit. On my Windows 10 machine it returns true but on Windows Server 2012 it returns false.
Also, checking the SSCLI for nlsinfo.cpp file reveals this comment:
// Call GetLocaleInfoEx and see if the OS knows about it.
// Note that GetLocaleInfoEx has variations:
// * Pre-Vista it fails and has to go downlevel
// * Vista succeeds, but not for neutrals
// * Win7 succeeds for all locales.
// * Mac does ???
So, how can I handle custom combinations of languages and regions (ar-IL, he-US etc) that are not recognized by Windows?
P.S I'm aware of the possibility to create and register a custom locale (using CultureAndRegionInfoBuilder) but it will take too much effort to cater for all the combinations I'm planning to support.
Yes, Windows 10 is able to provide somewhat sensible information for any culture name.
Constructing culture info yourself is an option - as long as calendar information is compatible you can merge strings from neutral ("HE") culture with data for any specific one (like "en-US"). CultureAndRegionInfoBuilder can be used to safely combine information as shown in the MSDN sample:
// Create a custom culture for ru-US.
CultureAndRegionInfoBuilder car1 = new CultureAndRegionInfoBuilder("ru-US",
CultureAndRegionModifiers.None);
car1.LoadDataFromCultureInfo(CultureInfo.CreateSpecificCulture("ru-RU"));
car1.LoadDataFromRegionInfo(new RegionInfo("en-US"));
Aleternatively you can build XML files defining cultures you need to support and either load them at run-time or even install on the servers using CultureAndRegionInfoBuilder.Register - Create custom culture in ASP.NET.

System Culture in a SIlverlight Application

I can't figure out how to get the CultureInfo of the Installed System on the Client Machine.
There is the CultureInfo.InstalledUICulture Property, but it seems to be unavailable in Silverlight.
Regards
Jonny
I believe that Culture.CurrentCulture will in fact provide you with the user's culture. It can however change or be programmatically set via current thread's Thread.CurrentCulture property. I'm not sure if Silverlight can access the user's machine/operating system culture/language settings beyond this mechanism.
As you mention in a comment, you cannot trust it as it will definitely change through the lifetime of the application. Perhaps then you should record the current culture when the application first starts up before it's programmatically changed, and store it indefinitely (statically or otherwise) to be referenced by your code.
EDIT: Another possibility is to leverage the hosting browser and its JavaScript. Googling around I see that you can access window.navigator.language which will report the language of the browser. Internet Explorer likes to do its own thing and reports the browserLanguage, userLanguage, and systemLanguage.
You can write up a small JavaScript method on the page (you will want to do more cross-browser tests, version tests, and operating system tests):
function GetUserLanguage()
{
if (window.navigator.language)
return window.navigator.language;
else //yay IE
return clientInformation.browserLanguage;
}
Then in Silverlight you might have something like:
string userLanguage = (string)HtmlPage.Window.Invoke("GetUserLanguage");
CultureInfo userCulture = new CultureInfo(userLanguage);
I'm not sure if all cultures reported by the browser (across all browsers/versions/operating systems) will match the culture listing in Silverlight.

Problem with loading culture from XML using CultureAndRegionInfoBuilder on Windows XP

I have a web application that will use a few different cultures, one of which is es-US (Spanish United States). However, Windows XP do not have any support for the culture es-US. To work around the problem, I've found out that one is supposed to be able to use the CultureAndRegionInfoBuilder. So I looked into CultureAndRegionInfoBuilder and did the following:
On a Windows 7 machine I saved the culture es-US to an XML-file, as follows:
private static void SaveCultureToFile() {
try {
CultureAndRegionInfoBuilder cultureAndRegionInfoBuilder = null;
Console.WriteLine("Saving es-US to xml disc...\n");
cultureAndRegionInfoBuilder = new CultureAndRegionInfoBuilder("es-US", CultureAndRegionModifiers.Replacement);
// Populate the new CultureAndRegionInfoBuilder object with culture information.
CultureInfo ci = new CultureInfo("es-US");
cultureAndRegionInfoBuilder.LoadDataFromCultureInfo(ci);
cultureAndRegionInfoBuilder.Save("es-US.xml");
}
Then I have a function that reads the xml, and registeres the culture into the system, as follows:
private static void RegisterCultureFromDisk() {
try {
CultureAndRegionInfoBuilder cultureAndRegionInfoBuilder = null;
Console.WriteLine("Loading es-US from xml...\n");
cultureAndRegionInfoBuilder = CultureAndRegionInfoBuilder.CreateFromLdml("es-US.xml");
Console.WriteLine("Culture is registred to the system...\n");
cultureAndRegionInfoBuilder.Register();
Console.WriteLine("The following culture has been registred to the system: \n");
}
So I run the program using the SaveCultureToFile method on a Windows 7 machine, thus saving the culture to an xml file. Then I copy the files to the Windows XP machine, and runs the same program but the RegisterCultureFromDisk() method. But the program fails in the CultureAndRegionInfoBuilder.CreateFromLdml("es-US.xml") method saying that:
"Culture name 'es-us' is not
supported"
Well, thats exactly why I'm trying to load the culture from the xml and registering it into the system.
Do any one know what I'm doing wrong, or how I can create the es-us culture at the Windows XP machine?
Thanx!
I know this is an ancient question, but I've recently run into this issue and managed to actually solve it.
Turns out the CreateFromLdml method can be tricked into loading a non-existing culture if you just create a temporary culture using the name of the one you want to import. Then you can unregister the temporary culture and register the one you just loaded instead.
I've made a simple command-line tool for exporting/importing cultures, which we've successfully used to add in some obscure missing cultures we needed when deploying new servers on Azure.
If you need it - the source code and a more in depth description of the solution is available here.
From MSDN:
Note that a custom culture can be registered on a computer only by a user who has administrative rights on that computer. Consequently, typical applications cannot create a custom culture.
I suspect it might be the cause of your problem... do you have admin rights on this machine ?

Categories

Resources