¿Los mensajes de excepción en inglés?

Estamos registrando cualquier excepción que ocurra en nuestro sistema al escribir Exception.Message en un archivo. Sin embargo, están escritos en la cultura del cliente. Y los errores turcos no significan mucho para mí.

Entonces, ¿cómo podemos registrar los mensajes de error en inglés sin cambiar la cultura de los usuarios?

Este problema se puede solucionar parcialmente. El código de excepción de Framework carga los mensajes de error de sus recursos, en función de la configuración regional del hilo actual. En el caso de algunas excepciones, esto sucede en el momento en que se accede a la propiedad del mensaje.

Para esas excepciones, puede obtener la versión completa en inglés de EE. UU. Del mensaje al cambiar brevemente la configuración regional del subproceso a en-US al iniciar sesión (guardando de antemano la configuración regional del usuario original y restaurándola inmediatamente después).

Hacer esto en un hilo separado es aún mejor: esto asegura que no habrá ningún efecto secundario. Por ejemplo:

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

Donde la clase ExceptionLogger se ve algo así como:

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

Sin embargo, como señala correctamente Joe en un comentario sobre una revisión anterior de esta respuesta, algunos mensajes ya están (parcialmente) cargados desde los recursos del idioma en el momento en que se lanza la excepción.

Esto se aplica a la parte ‘parámetro no puede ser nulo’ del mensaje generado cuando se lanza una excepción ArgumentNullException (“foo”), por ejemplo. En esos casos, el mensaje aún aparecerá (parcialmente) localizado, incluso cuando se usa el código anterior.

Para empezar, aparte de usar hacks poco prácticos, como ejecutar todos los códigos que no sean UI en un hilo con configuración regional en-US, parece que no hay mucho que hacer al respecto: el código de excepción de .NET Framework no tiene instalaciones para anular la configuración regional del mensaje de error.

Puede buscar el mensaje de excepción original en unlocalize.com

Quizás sea un punto polémico, pero en lugar de establecer la cultura en en-US , puede establecerlo en Invariant . En la cultura Invariant , los mensajes de error están en inglés.

 Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; 

Tiene la ventaja de no tener prejuicios, especialmente en lugares que no hablan inglés de habla estadounidense. (alias evita comentarios sarcásticos de colegas)

Windows necesita tener instalado el idioma de la interfaz de usuario que desea usar. No es así, no tiene forma de saber mágicamente cuál es el mensaje traducido.

En un en-US windows 7 ultimate, con pt-PT instalado, el siguiente código:

 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; 

Produce mensajes en pt-PT, en-US y en-US. Como no hay archivos de cultura francesa instalados, el valor predeterminado es el idioma de Windows (¿está instalado?).

Aquí hay una solución que no requiere ninguna encoding y funciona incluso para textos de excepciones que se cargan demasiado pronto para que podamos cambiar por código (por ejemplo, los de mscorlib).

Puede no ser siempre aplicable en todos los casos (depende de su configuración, ya que necesita para poder crear un archivo .config aparte del archivo .exe principal), pero eso funciona para mí. Por lo tanto, solo cree un app.config en dev, (o un [myapp].exe.config o web.config en producción) que contenga las siguientes líneas, por ejemplo:

  ...             ...  

Lo que hace es decirle al marco que redirija los enlaces de ensamblaje para los recursos de mscorlib y los recursos de System.Xml, para las versiones entre 1 y 999, en francés (culture se establece en “fr”) en un ensamblado que … no existe (un versión arbitraria 999).

Por lo tanto, cuando el CLR busque recursos en francés para estos dos ensamblajes (mscorlib y System.xml), no los encontrará y recurrirá al inglés correctamente. Según su contexto y las pruebas, es posible que desee agregar otros ensamblados a estos redireccionamientos (ensamblados que contienen recursos localizados).

Por supuesto, no creo que esto sea compatible con Microsoft, así que utilícelo bajo su propio riesgo. Bueno, en caso de que detecte un problema, puede simplemente eliminar esta configuración y verificar que no esté relacionada.

Sé que este es un tema antiguo, pero creo que mi solución puede ser bastante relevante para cualquiera que tropiece con ella en una búsqueda web:

En el registrador de excepciones, puede registrar ex.GetType.ToString, que guardará el nombre de la clase de excepción. Esperaría que el nombre de una clase debería ser independiente del lenguaje y, por lo tanto, siempre estaría representado en inglés (por ejemplo, “System.FileNotFoundException”), aunque en este momento no tengo acceso a un sistema de idioma extranjero para probar el idea.

Si realmente desea el texto del mensaje de error también podría crear un diccionario de todos los posibles nombres de clase de excepción y sus mensajes equivalentes en el idioma que prefiera, pero para el inglés creo que el nombre de clase es perfectamente adecuado.

Configurar Thread.CurrentThread.CurrentUICulture se usará para localizar las excepciones. Si necesita dos tipos de excepciones (una para el usuario, una para usted) puede usar la siguiente función para traducir el mensaje de excepción. Está buscando en los recursos .NET-Libraries para que el texto original obtenga la clave-recurso y luego devuelve el valor traducido. Pero hay una debilidad: no encontré una buena solución aún: no se encontrarán los mensajes que contengan {0} recursos. Si alguien tiene una buena solución, estaría agradecido.

 public static string TranslateExceptionMessage(Exception E, CultureInfo targetCulture) { try { Assembly a = E.GetType().Assembly; ResourceManager rm = new ResourceManager(a.GetName().Name, a); ResourceSet rsOriginal = rm.GetResourceSet(Thread.CurrentThread.CurrentUICulture, true, true); ResourceSet rsTranslated = rm.GetResourceSet(targetCulture, true, true); foreach (DictionaryEntry item in rsOriginal) if (item.Value.ToString() == E.Message.ToString()) return rsTranslated.GetString(item.Key.ToString(), false); // success } catch { } return E.Message; // failed (error or cause it's not intelligent enough to locale '{0}'-patterns } 

Me imagino uno de estos enfoques:

1) Las excepciones solo las lee usted, es decir, no son una función del cliente, por lo que puede usar cadenas cableadas no localizadas que no cambiarán cuando se ejecute en modo turco.

2) Incluye un código de error, por ej. 0X00000001 con cada error para que pueda mirarlo fácilmente en una tabla inglesa.

 CultureInfo oldCI = Thread.CurrentThread.CurrentCulture; Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture ("en-US"); Thread.CurrentThread.CurrentUICulture=new CultureInfo("en-US"); try { System.IO.StreamReader sr=new System.IO.StreamReader(@"c:\does-not-exist"); } catch(Exception ex) { Console.WriteLine(ex.ToString()) } Thread.CurrentThread.CurrentCulture = oldCI; Thread.CurrentThread.CurrentUICulture = oldCI; 

Sin WORKAROUNDS.

Tks 🙂

El framework .NET viene en dos partes:

  1. El propio framework .NET
  2. Los paquetes de idioma de .NET Framework

Todos los textos (por ejemplo, mensajes de excepción, tags de botones en un MessageBox, etc.) están en inglés en el propio framework .NET. Los paquetes de idioma tienen los textos localizados.

Dependiendo de su situación exacta, una solución sería desinstalar los paquetes de idioma (es decir, decirle al cliente que lo haga). En ese caso, los textos de excepción estarán en inglés. Sin embargo, tenga en cuenta que todos los demás textos proporcionados por el marco también serán en inglés (por ejemplo, las tags de los botones en un MessageBox, los atajos de teclado para ApplicationCommands).

He tenido la misma situación, y todas las respuestas que encontré aquí y en otros lugares no me ayudaron o no me satisficieron:
Forzar excepciones de idioma en inglés
C # – ¿Recibe mensajes de excepción en inglés cuando la aplicación está en otro idioma?
Cómo cambiar el idioma de los mensajes de excepción de Visual Studio a inglés mientras se depura
¿Cómo manejar la traducción del mensaje de excepción?
Cómo evitar por completo los mensajes de excepción .NET localizados

Thread.CurrentUICulture cambia el idioma de las excepciones .net, pero no para Win32Exception , que usa los recursos de Windows en el idioma de la misma UI de Windows. Así que nunca logré imprimir los mensajes de Win32Exception en inglés en lugar de en alemán, ni siquiera usando FormatMessage() como se describe en
¿Cómo obtener Win32Exception en inglés?

Por lo tanto, creé mi propia solución, que almacena la mayoría de los mensajes de excepción existentes para diferentes idiomas en archivos externos. No recibirá el mensaje exacto en su idioma deseado, pero recibirá un mensaje en ese idioma, que es mucho más de lo que obtiene actualmente (que es un mensaje en un idioma que probablemente no comprenda).

Las funciones estáticas de esta clase se pueden ejecutar en instalaciones de Windows con diferentes idiomas: CreateMessages() crea los textos específicos de la cultura
SaveMessagesToXML() guarda en tantos archivos XML como idiomas se crean o cargan
LoadMessagesFromXML() carga todos los archivos XML con mensajes específicos del idioma

Al crear los archivos XML en diferentes instalaciones de Windows con diferentes idiomas, pronto tendrá todos los idiomas que necesita.
Tal vez pueda crear los textos para diferentes idiomas en 1 Windows cuando tiene instalados varios paquetes de idioma MUI, pero aún no lo he probado.

Probado con VS2008, listo para usar. ¡Comentarios y sugerencias son bienvenidas!

 using System; using System.Collections.Generic; using System.ComponentModel; using System.Globalization; using System.Reflection; using System.Threading; using System.Xml; public struct CException { //---------------------------------------------------------------------------- public CException(Exception i_oException) { m_oException = i_oException; m_oCultureInfo = null; m_sMessage = null; } //---------------------------------------------------------------------------- public CException(Exception i_oException, string i_sCulture) { m_oException = i_oException; try { m_oCultureInfo = new CultureInfo(i_sCulture); } catch { m_oCultureInfo = CultureInfo.InvariantCulture; } m_sMessage = null; } //---------------------------------------------------------------------------- public CException(Exception i_oException, CultureInfo i_oCultureInfo) { m_oException = i_oException; m_oCultureInfo = i_oCultureInfo == null ? CultureInfo.InvariantCulture : i_oCultureInfo; m_sMessage = null; } //---------------------------------------------------------------------------- // GetMessage //---------------------------------------------------------------------------- public string GetMessage() { return GetMessage(m_oException, m_oCultureInfo); } public string GetMessage(String i_sCulture) { return GetMessage(m_oException, i_sCulture); } public string GetMessage(CultureInfo i_oCultureInfo) { return GetMessage(m_oException, i_oCultureInfo); } public static string GetMessage(Exception i_oException) { return GetMessage(i_oException, CultureInfo.InvariantCulture); } public static string GetMessage(Exception i_oException, string i_sCulture) { CultureInfo oCultureInfo = null; try { oCultureInfo = new CultureInfo(i_sCulture); } catch { oCultureInfo = CultureInfo.InvariantCulture; } return GetMessage(i_oException, oCultureInfo); } public static string GetMessage(Exception i_oException, CultureInfo i_oCultureInfo) { if (i_oException == null) return null; if (i_oCultureInfo == null) i_oCultureInfo = CultureInfo.InvariantCulture; if (ms_dictCultureExceptionMessages == null) return null; if (!ms_dictCultureExceptionMessages.ContainsKey(i_oCultureInfo)) return CreateMessage(i_oException, i_oCultureInfo); Dictionary dictExceptionMessage = ms_dictCultureExceptionMessages[i_oCultureInfo]; string sExceptionName = i_oException.GetType().FullName; sExceptionName = MakeXMLCompliant(sExceptionName); Win32Exception oWin32Exception = (Win32Exception)i_oException; if (oWin32Exception != null) sExceptionName += "_" + oWin32Exception.NativeErrorCode; if (dictExceptionMessage.ContainsKey(sExceptionName)) return dictExceptionMessage[sExceptionName]; else return CreateMessage(i_oException, i_oCultureInfo); } //---------------------------------------------------------------------------- // CreateMessages //---------------------------------------------------------------------------- public static void CreateMessages(CultureInfo i_oCultureInfo) { Thread oTH = new Thread(new ThreadStart(CreateMessagesInThread)); if (i_oCultureInfo != null) { oTH.CurrentCulture = i_oCultureInfo; oTH.CurrentUICulture = i_oCultureInfo; } oTH.Start(); while (oTH.IsAlive) { Thread.Sleep(10); } } //---------------------------------------------------------------------------- // LoadMessagesFromXML //---------------------------------------------------------------------------- public static void LoadMessagesFromXML(string i_sPath, string i_sBaseFilename) { if (i_sBaseFilename == null) i_sBaseFilename = msc_sBaseFilename; string[] asFiles = null; try { asFiles = System.IO.Directory.GetFiles(i_sPath, i_sBaseFilename + "_*.xml"); } catch { return; } ms_dictCultureExceptionMessages.Clear(); for (int ixFile = 0; ixFile < asFiles.Length; ixFile++) { string sXmlPathFilename = asFiles[ixFile]; XmlDocument xmldoc = new XmlDocument(); try { xmldoc.Load(sXmlPathFilename); XmlNode xmlnodeRoot = xmldoc.SelectSingleNode("/" + msc_sXmlGroup_Root); string sCulture = xmlnodeRoot.SelectSingleNode(msc_sXmlGroup_Info + "/" + msc_sXmlData_Culture).Value; CultureInfo oCultureInfo = new CultureInfo(sCulture); XmlNode xmlnodeMessages = xmlnodeRoot.SelectSingleNode(msc_sXmlGroup_Messages); XmlNodeList xmlnodelistMessage = xmlnodeMessages.ChildNodes; Dictionary dictExceptionMessage = new Dictionary(xmlnodelistMessage.Count + 10); for (int ixNode = 0; ixNode < xmlnodelistMessage.Count; ixNode++) dictExceptionMessage.Add(xmlnodelistMessage[ixNode].Name, xmlnodelistMessage[ixNode].InnerText); ms_dictCultureExceptionMessages.Add(oCultureInfo, dictExceptionMessage); } catch { return; } } } //---------------------------------------------------------------------------- // SaveMessagesToXML //---------------------------------------------------------------------------- public static void SaveMessagesToXML(string i_sPath, string i_sBaseFilename) { if (i_sBaseFilename == null) i_sBaseFilename = msc_sBaseFilename; foreach (KeyValuePair> kvpCultureExceptionMessages in ms_dictCultureExceptionMessages) { string sXmlPathFilename = i_sPath + i_sBaseFilename + "_" + kvpCultureExceptionMessages.Key.TwoLetterISOLanguageName + ".xml"; Dictionary dictExceptionMessage = kvpCultureExceptionMessages.Value; XmlDocument xmldoc = new XmlDocument(); XmlWriter xmlwriter = null; XmlWriterSettings writerSettings = new XmlWriterSettings(); writerSettings.Indent = true; try { XmlNode xmlnodeRoot = xmldoc.CreateElement(msc_sXmlGroup_Root); xmldoc.AppendChild(xmlnodeRoot); XmlNode xmlnodeInfo = xmldoc.CreateElement(msc_sXmlGroup_Info); XmlNode xmlnodeMessages = xmldoc.CreateElement(msc_sXmlGroup_Messages); xmlnodeRoot.AppendChild(xmlnodeInfo); xmlnodeRoot.AppendChild(xmlnodeMessages); XmlNode xmlnodeCulture = xmldoc.CreateElement(msc_sXmlData_Culture); xmlnodeCulture.InnerText = kvpCultureExceptionMessages.Key.Name; xmlnodeInfo.AppendChild(xmlnodeCulture); foreach (KeyValuePair kvpExceptionMessage in dictExceptionMessage) { XmlNode xmlnodeMsg = xmldoc.CreateElement(kvpExceptionMessage.Key); xmlnodeMsg.InnerText = kvpExceptionMessage.Value; xmlnodeMessages.AppendChild(xmlnodeMsg); } xmlwriter = XmlWriter.Create(sXmlPathFilename, writerSettings); xmldoc.WriteTo(xmlwriter); } catch (Exception e) { return; } finally { if (xmlwriter != null) xmlwriter.Close(); } } } //---------------------------------------------------------------------------- // CreateMessagesInThread //---------------------------------------------------------------------------- private static void CreateMessagesInThread() { Thread.CurrentThread.Name = "CException.CreateMessagesInThread"; Dictionary dictExceptionMessage = new Dictionary(0x1000); GetExceptionMessages(dictExceptionMessage); GetExceptionMessagesWin32(dictExceptionMessage); ms_dictCultureExceptionMessages.Add(Thread.CurrentThread.CurrentUICulture, dictExceptionMessage); } //---------------------------------------------------------------------------- // GetExceptionTypes //---------------------------------------------------------------------------- private static List GetExceptionTypes() { Assembly[] aoAssembly = AppDomain.CurrentDomain.GetAssemblies(); List listoExceptionType = new List(); Type oExceptionType = typeof(Exception); for (int ixAssm = 0; ixAssm < aoAssembly.Length; ixAssm++) { if (!aoAssembly[ixAssm].GlobalAssemblyCache) continue; Type[] aoType = aoAssembly[ixAssm].GetTypes(); for (int ixType = 0; ixType < aoType.Length; ixType++) { if (aoType[ixType].IsSubclassOf(oExceptionType)) listoExceptionType.Add(aoType[ixType]); } } return listoExceptionType; } //---------------------------------------------------------------------------- // GetExceptionMessages //---------------------------------------------------------------------------- private static void GetExceptionMessages(Dictionary i_dictExceptionMessage) { List listoExceptionType = GetExceptionTypes(); for (int ixException = 0; ixException < listoExceptionType.Count; ixException++) { Type oExceptionType = listoExceptionType[ixException]; string sExceptionName = MakeXMLCompliant(oExceptionType.FullName); try { if (i_dictExceptionMessage.ContainsKey(sExceptionName)) continue; Exception e = (Exception)(Activator.CreateInstance(oExceptionType)); i_dictExceptionMessage.Add(sExceptionName, e.Message); } catch (Exception) { i_dictExceptionMessage.Add(sExceptionName, null); } } } //---------------------------------------------------------------------------- // GetExceptionMessagesWin32 //---------------------------------------------------------------------------- private static void GetExceptionMessagesWin32(Dictionary i_dictExceptionMessage) { string sTypeName = MakeXMLCompliant(typeof(Win32Exception).FullName) + "_"; for (int iError = 0; iError < 0x4000; iError++) // Win32 errors may range from 0 to 0xFFFF { Exception e = new Win32Exception(iError); if (!e.Message.StartsWith("Unknown error (", StringComparison.OrdinalIgnoreCase)) i_dictExceptionMessage.Add(sTypeName + iError, e.Message); } } //---------------------------------------------------------------------------- // CreateMessage //---------------------------------------------------------------------------- private static string CreateMessage(Exception i_oException, CultureInfo i_oCultureInfo) { CException oEx = new CException(i_oException, i_oCultureInfo); Thread oTH = new Thread(new ParameterizedThreadStart(CreateMessageInThread)); oTH.Start(oEx); while (oTH.IsAlive) { Thread.Sleep(10); } return oEx.m_sMessage; } //---------------------------------------------------------------------------- // CreateMessageInThread //---------------------------------------------------------------------------- private static void CreateMessageInThread(Object i_oData) { if (i_oData == null) return; CException oEx = (CException)i_oData; if (oEx.m_oException == null) return; Thread.CurrentThread.CurrentUICulture = oEx.m_oCultureInfo == null ? CultureInfo.InvariantCulture : oEx.m_oCultureInfo; // create new exception in desired culture Exception e = null; Win32Exception oWin32Exception = (Win32Exception)(oEx.m_oException); if (oWin32Exception != null) e = new Win32Exception(oWin32Exception.NativeErrorCode); else { try { e = (Exception)(Activator.CreateInstance(oEx.m_oException.GetType())); } catch { } } if (e != null) oEx.m_sMessage = e.Message; } //---------------------------------------------------------------------------- // MakeXMLCompliant // from https://www.w3.org/TR/xml/ //---------------------------------------------------------------------------- private static string MakeXMLCompliant(string i_sName) { if (string.IsNullOrEmpty(i_sName)) return "_"; System.Text.StringBuilder oSB = new System.Text.StringBuilder(); for (int ixChar = 0; ixChar < (i_sName == null ? 0 : i_sName.Length); ixChar++) { char character = i_sName[ixChar]; if (IsXmlNodeNameCharacterValid(ixChar, character)) oSB.Append(character); } if (oSB.Length <= 0) oSB.Append("_"); return oSB.ToString(); } //---------------------------------------------------------------------------- private static bool IsXmlNodeNameCharacterValid(int i_ixPos, char i_character) { if (i_character == ':') return true; if (i_character == '_') return true; if (i_character >= 'A' && i_character <= 'Z') return true; if (i_character >= 'a' && i_character <= 'z') return true; if (i_character >= 0x00C0 && i_character <= 0x00D6) return true; if (i_character >= 0x00D8 && i_character <= 0x00F6) return true; if (i_character >= 0x00F8 && i_character <= 0x02FF) return true; if (i_character >= 0x0370 && i_character <= 0x037D) return true; if (i_character >= 0x037F && i_character <= 0x1FFF) return true; if (i_character >= 0x200C && i_character <= 0x200D) return true; if (i_character >= 0x2070 && i_character <= 0x218F) return true; if (i_character >= 0x2C00 && i_character <= 0x2FEF) return true; if (i_character >= 0x3001 && i_character <= 0xD7FF) return true; if (i_character >= 0xF900 && i_character <= 0xFDCF) return true; if (i_character >= 0xFDF0 && i_character <= 0xFFFD) return true; // if (i_character >= 0x10000 && i_character <= 0xEFFFF) return true; if (i_ixPos > 0) { if (i_character == '-') return true; if (i_character == '.') return true; if (i_character >= '0' && i_character <= '9') return true; if (i_character == 0xB7) return true; if (i_character >= 0x0300 && i_character <= 0x036F) return true; if (i_character >= 0x203F && i_character <= 0x2040) return true; } return false; } private static string msc_sBaseFilename = "exception_messages"; private static string msc_sXmlGroup_Root = "exception_messages"; private static string msc_sXmlGroup_Info = "info"; private static string msc_sXmlGroup_Messages = "messages"; private static string msc_sXmlData_Culture = "culture"; private Exception m_oException; private CultureInfo m_oCultureInfo; private string m_sMessage; static Dictionary> ms_dictCultureExceptionMessages = new Dictionary>(); } internal class Program { public static void Main() { CException.CreateMessages(null); CException.SaveMessagesToXML(@"d:\temp\", "emsg"); CException.LoadMessagesFromXML(@"d:\temp\", "emsg"); } } 

Debería registrar la stack de llamadas en lugar de un mensaje de error (IIRC, simple exception.ToString () debería hacer eso por usted). Desde allí, puede determinar exactamente de dónde se originó la excepción, y generalmente deducir qué excepción es.

Anula el mensaje de excepción en el bloque de catch usando el método de extensión, Check throwwn message es del código o no, como se menciona a continuación.

  public static string GetEnglishMessageAndStackTrace(this Exception ex) { CultureInfo currentCulture = Thread.CurrentThread.CurrentUICulture; try { dynamic exceptionInstanceLocal = System.Activator.CreateInstance(ex.GetType()); string str; Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US"); if (ex.Message == exceptionInstanceLocal.Message) { dynamic exceptionInstanceENG = System.Activator.CreateInstance(ex.GetType()); str = exceptionInstanceENG.ToString() + ex.StackTrace; } else { str = ex.ToString(); } Thread.CurrentThread.CurrentUICulture = currentCulture; return str; } catch (Exception) { Thread.CurrentThread.CurrentUICulture = currentCulture; return ex.ToString(); } 

Para fines de registro, ciertas aplicaciones pueden necesitar obtener el mensaje de excepción en inglés (además de mostrarlo en la UICulture del cliente habitual).

Para ese propósito, el siguiente código

  1. cambia la UICulture actual
  2. recrea el objeto Exception arrojado usando “GetType ()” y “Activator.CreateInstance (t)”
  3. muestra el nuevo mensaje del objeto de excepción en el nuevo UICuture
  4. y finalmente cambia la UICulture actual a UICulture anterior.

      try { int[] a = { 3, 6 }; Console.WriteLine(a[3]); //Throws index out of bounds exception System.IO.StreamReader sr = new System.IO.StreamReader(@"c:\does-not-exist"); // throws file not found exception throw new System.IO.IOException(); } catch (Exception ex) { Console.WriteLine(ex.Message); Type t = ex.GetType(); CultureInfo CurrentUICulture = System.Threading.Thread.CurrentThread.CurrentUICulture; System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en-US"); object o = Activator.CreateInstance(t); System.Threading.Thread.CurrentThread.CurrentUICulture = CurrentUICulture; // Changing the UICulture back to earlier culture Console.WriteLine(((Exception)o).Message.ToString()); Console.ReadLine(); }