C# - Getting Exception messages in English when the application is in another language?

时间:2015-07-28 15:42:24

标签: c# .net exception localization resourcedictionary

I am trying to localize my program but I would like error messages that are sent to the developers to appear in English. I haven't been able to find a way to make this happen since it seems that if the UI culture is set to another language when an error is thrown, it is thrown in that language. Since I did not write this program myself, and it is quite large, I think it would be impractical to go create new try catch blocks to try and set the culture back to english whenever an error occurs or might possibly occur. Currently the CurrentCulture and DefaultThreadCurrentCulture are always set to be English throughout the entire application, while the CurrentUICulture is set to the end user's language.

As I workaround, I currently have a function that has been iterating through a list of errors (using System.Resources.ResourceSets (which I assume are Windows errors, but I also need a way to find the .NET errors so I can iterate through those). It string replaces matching errors in other languages and replaces them with their English equivalents to build a large message of errors to be sent to the developers whenever the application crashes. Really, I don't have much to translate as most of the message is a server stack trace and showing where the exception was thrown. The biggest problem is translating the Inner Exception message and sometimes the main exception message since sometimes the errors thrown don't appear in the ResourceSet and sometimes use formatting items like '{0}'.

Here is the code I have so far to translate the remaining errors. I'm still working on adding regex patterns to translate errors that use things like '{0}', so if anyone has suggestions for that or better ways to do this I'd appreciate suggestions.

    public static string TranslateExceptionMessageTest(string exmsg, Exception e, CultureInfo currentui)
    {
        CultureInfo test = Thread.CurrentThread.CurrentUICulture;
        string matchingstr = "";
        string newstr = exmsg;
        string resourcecollection = "";

        Assembly a = e.GetType().Assembly;
        ResourceManager rm = new ResourceManager(a.GetName().Name, a);
        ResourceSet rsOriginal = rm.GetResourceSet(currentui, true, true);
        ResourceSet rsTranslated = rm.GetResourceSet(new CultureInfo("en-US"), true, true);
        foreach (DictionaryEntry item in rsOriginal)
        {
            if (exmsg.Contains(item.Value.ToString()))
            {
                if (item.Key.ToString() == "Word_At") // sometimes with spanish errors this replaces words containing the letters 'en' with 'at'.
                {
                    string newat = "   " + item.Value.ToString() + " "; // this is the formatting the word 'at' appears with, in any culture I've tested.
                    matchingstr = "   " + rsTranslated.GetString(item.Key.ToString(), false) + " ";
                    newstr = newstr.Replace(newat, matchingstr);
                }
                else
                {
                    matchingstr = rsTranslated.GetString(item.Key.ToString(), false);
                    newstr = newstr.Replace(item.Value.ToString(), matchingstr);
                }
            }
            resourcecollection = resourcecollection + Environment.NewLine + "Key: " + item.Key.ToString() + Environment.NewLine + "Value: " + item.Value.ToString();
        }
        return newstr; // success
    }

I have also tried using the method posted here ( Exception messages in English? ) but without much luck. I still ended up with the same localized error messages. Here is the code where I know an error is being thrown but it doesn't seem like the catch block is doing anything to change the language. My ExceptionLogger class is set up the same way as in the Stackoverflow example with the addition of a line to write the error to a file. The error is being thrown at wcf.Client.Ping() (I don't care about the actual error. I'm using it to test).

 private void PreloadWcfDlls(object state)
 {
        if (Global.Inst.ServerMode == ApplicationServerMode.Unknown)
            return;

        try
        {
            using (var wcf = ClientGrabber.GetSchemaClient(Global.Inst.ServerMode))
            {
                wcf.Client.Ping();
            }
        }
        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();
        }
 }

If nothing else, is there a way I can get a list of all possible .NET Framework errors in English as well as in other languages? Is there a class I can access to get these from within my program or a list elsewhere? I've tried looking at sites like unlocalize.com and finderr.net but I really don't want to have to write something to crawl through all the pages to find every possible error.

Sorry if I'm completely missing something. I'm pretty new to C# and programming in general and this problem is driving me kind of crazy!

Edit: I forgot to add that I would prefer to avoid a solutions like these where you have to be constantly changing the CurrentUICulture:

Force exceptions language in English

Prevent exception messages from being translated into the user's language?

Or solutions where you delete language packs or something on the user's computer or just set the errors to be in English when debugging (these error logs will also be sent from an end users computer in the case that the application crashes and if they are using another language we need the errors logged in English).

Also, I know I could just google the error messages or use unlocalize.com or finderr.net to translate the messages but I think the other developers might kill me if they had to do that, hah. I guess if worse comes to worst I could query the unlocalize site? Seems like a real pain though.

3 个答案:

答案 0 :(得分:1)

异常框架根据当前线程的区域性加载错误消息。 因此,您可以做的是,捕获异常,然后在catch块中创建自己的logger对象并根据需要设置其区域性。

    try
{
//.....Code Goes Here
}
Catch (Exception ex)
{
   var eh = new ExceptionHandler("Your-Culture");
   //....code goes here
}

Public class ExceptionHandler
{
//code goes on
    public ExceptionHandler(string culture)
{
//set your culture here
}
}

答案 1 :(得分:0)

Here您可以找到问题的解决方案。长话短说:

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();
}
     

ExceptionLogger类看起来像:

class ExceptionLogger
{
  Exception _ex;

  public ExceptionLogger(Exception ex)
  {
    _ex = ex;
  }

  public void DoLog()
  {
    Console.WriteLine(_ex.ToString()); //Will display en-US message
  }
}

答案 2 :(得分:-2)

试试这个:

Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-us");