Problem
By writing the Exception.Message to a file, we log any exceptions that occur in our system. They are, however, written in the client’s culture. And I don’t care about Turkish mistakes.
So, how can any error messages be logged in English without affecting the users’ culture?
Asked by Carra
Solution #1
This problem can be partially resolved. Based on the current thread locale, the Framework exception code loads error messages from its resources. This occurs when the Message property is accessed in the event of some exceptions.
For those exceptions, you can obtain the full US English version of the message by briefly switching the thread locale to en-US while logging it (saving the original user locale beforehand and restoring it immediately afterwards).
It’s much better if you do it on a different thread so there are no negative effects. Consider the following scenario:
try
{
System.IO.StreamReader sr=new System.IO.StreamReader(@"c:\does-not-exist");
}
catch(Exception ex)
{
Console.WriteLine(ex.ToString()); //Will display localized message
ExceptionLogger el = new ExceptionLogger(ex);
System.Threading.Thread t = new System.Threading.Thread(el.DoLog);
t.CurrentUICulture = new System.Globalization.CultureInfo("en-US");
t.Start();
}
Where the ExceptionLogger class appears to be:
class ExceptionLogger
{
Exception _ex;
public ExceptionLogger(Exception ex)
{
_ex = ex;
}
public void DoLog()
{
Console.WriteLine(_ex.ToString()); //Will display en-US message
}
}
Some messages are already (partially) loaded from the language resources at the time the exception is thrown, as Joe properly points out in a comment on an earlier iteration of this reply.
This is true, for example, when an ArgumentNullException(“foo”) exception is issued when the message contains the phrase “parameter cannot be null.” Even when employing the aforementioned code, the message will appear (partially) localized in some circumstances.
There doesn’t appear to be much you can do about it unless you use impractical hacks like executing all your non-UI code on a thread with the en-US locale to begin with: the.NET Framework exception code has no tools for altering the error message locale.
Answered by mdb
Solution #2
At unlocalize.com, you can look for the original exception message.
Answered by user461128
Solution #3
Perhaps a controversial issue, however you can set the culture to Invariant instead of en-US. The error messages in the Invariant culture are written in English.
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture;
It has the advantage of not appearing biased, which is especially useful in non-English speaking areas. (a.k.a. avoids coworkers’ nasty remarks)
Answered by MPelletier
Solution #4
Here’s a way that doesn’t involve any coding and works even for exception texts that are loaded too soon for us to edit via code (for example, those in mscorlib).
It may not be appropriate in all cases (it depends on your configuration, as you must be able to generate a.config file in addition to the main.exe file), but it worked for me. So, for example, in dev, create an app.config (or in production, a [myapp].exe.config or web.config) that contains the following lines:
<configuration>
...
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="mscorlib.resources" publicKeyToken="b77a5c561934e089"
culture="fr" /> <!-- change this to your language -->
<bindingRedirect oldVersion="1.0.0.0-999.0.0.0" newVersion="999.0.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Xml.resources" publicKeyToken="b77a5c561934e089"
culture="fr" /> <!-- change this to your language -->
<bindingRedirect oldVersion="1.0.0.0-999.0.0.0" newVersion="999.0.0.0"/>
</dependentAssembly>
<!-- add other assemblies and other languages here -->
</assemblyBinding>
</runtime>
...
</configuration>
What this does is tell the framework to redirect assembly bindings for mscorlib’s resources and System. Xml’s resources, for versions between 1 and 999, in french (culture is set to “fr”) to an assembly that … does not exists (an arbitrary version 999).
So when the CLR will look for french resources for these two assemblies (mscorlib and System.xml), it will not find them and fallback to English gracefully. You might wish to add other assemblies to these redirects depending on your context and testing (assemblies that contains localized resources).
Of course, I don’t believe Microsoft supports this, so use at your own peril. In the event that an issue arises, just remove this configuration and verify that it is unrelated.
Answered by Simon Mourier
Solution #5
The UI language you intend to use must be installed on Windows. It has no means of magically knowing what the translated message is if it doesn’t.
In an en-US windows 7 ultimate, with pt-PT installed, the following code:
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("pt-PT");
string msg1 = new DirectoryNotFoundException().Message;
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("en-US");
string msg2 = new FileNotFoundException().Message;
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("fr-FR");
string msg3 = new FileNotFoundException().Message;
Produces messages in the following languages: pt-PT, en-US, and en-US. It defaults to the Windows default (installed?) language because there are no French culture files installed.
Answered by danobrega
Post is based on https://stackoverflow.com/questions/209133/exception-messages-in-english