English 中文(简体)
How does a .NET process get the culture information?
原标题:

I have a Windows service running (C#, .NET 2.0) on Windows Server 2003 R2. In one server the System.Threading.Thread.CurrentThread.CurrentCulture is {en-AU} and in the other {en-US}. This has caused a difference when calling ToString() on a DateTime object. I want the culture to be {en-AU}.

I checked the "Regional and Language Setting". In both servers, the "Regional Options" tab shows "English (Asutralia)". But in the "Advanced" tab it shows "English (United States)" for one and "English (Australia)" for the other. So this must be causing the difference. Although I want to know why exactly the "Advanced" tab says "the language version of the non-unicode programs you want to use", I thought .NET processes were Unicode and should not be affected by this.

How does the .NET runtime determine the culture to use? Any detailed reference would be helpful.

最佳回答

If a culture has not been set on the thread, Thread.CurrentThread.CurrentCulture defaults to the "user default culture" - which it gets from the underlying OS. This is determined by the Formats section in the regional control panel applet.

For a service, it has no control panel settings by default like for a user (the case above) as it runs under the LocalSystem account which will not have a profile, so it uses the system locale from the OS. I m not sure if this can be set for a service by adjusting the settings in Windows.

There are a few things you could do:

  1. you can explicitly set the CurrentCulture of the main thread when the service starts. If you do this, you will need to bear in mind that any new threads that are created in your service will also need to have their CurrentCulture set as well, as threads do not inherit their culture from parent threads.

  2. you can set the service to run as a specific user, and set that user s regional settings (the formats section) to be the culture you want to use. When the service starts as that use,it will use that user s regional settings.

  3. since your problem seems to be related to calling DateTime.ToString(), make sure you pass the AU culture to the ToString() method:

    DateTime.ToString(new CultureInfo("en-AU"))
    

    You could add this as an extension method to save you having to do this everywhere:

    public static string ToAUString(this DateTime dateTime)
    {
        return dateTime.ToString(new CultureInfo("en-AU"));
    }
    

    You can then call DateTime.ToAUString() to get the correct output.

问题回答

In my case it took only one line of code to change the Culture:

System.Globalization.CultureInfo.DefaultThreadCurrentUICulture = System.Globalization.CultureInfo.GetCultureInfo( "en-US" )

It changes default Culture of Main thread and new ones as well.

This MSDN page on CultureInfo has some information that might be relevant:

The user might choose to override some of the values associated with the current culture of Windows through the regional and language options portion of Control Panel. For example, the user might choose to display the date in a different format or to use a currency other than the default for the culture. In general, your applications should honor these user overrides.

If UseUserOverride is true and the specified culture matches the current culture of Windows, the CultureInfo uses those overrides, including user settings for the properties of the DateTimeFormatInfo instance returned by the DateTimeFormat property, and the properties of the NumberFormatInfo instance returned by the NumberFormat property. If the user settings are incompatible with the culture associated with the CultureInfo, for example, if the selected calendar is not one of the OptionalCalendars, the results of the methods and the values of the properties are undefined.

I think this might be a good starting point for your investigations.





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签