Messaggi di eccezione in inglese?

Stiamo registrando tutte le eccezioni che si verificano nel nostro sistema scrivendo il messaggio Exception.Message su un file. Tuttavia, sono scritti nella cultura del cliente. E gli errori turchi non significano molto per me.

Quindi, come possiamo registrare eventuali messaggi di errore in inglese senza modificare la cultura degli utenti?

Questo problema può essere parzialmente risolto. Il codice di eccezione Framework carica i messaggi di errore dalle sue risorse, in base alla locale corrente del thread. Nel caso di alcune eccezioni, ciò accade nel momento in cui si accede alla proprietà Message.

Per tali eccezioni, è ansible ottenere la versione completa in inglese degli Stati Uniti del messaggio passando brevemente le impostazioni internazionali del thread a en-US durante la registrazione (salvando preventivamente le impostazioni locali dell’utente originale e ripristinandole subito dopo).

Fare questo su un thread separato è ancora meglio: questo assicura che non ci saranno effetti collaterali. Per esempio:

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

Dove la class ExceptionLogger appare come:

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

Tuttavia, come sottolinea giustamente Joe in un commento su una precedente revisione di questa risposta, alcuni messaggi sono già (parzialmente) caricati dalle risorse del linguaggio nel momento in cui viene lanciata l’eccezione.

Ciò si applica alla parte ‘parameter can not be null’ del messaggio generato quando viene generata un’eccezione ArgumentNullException (“foo”), ad esempio. In questi casi, il messaggio apparirà ancora (parzialmente) localizzato, anche quando si utilizza il codice precedente.

A parte l’utilizzo di hack non pratici, come l’esecuzione di tutti i codici non UI su un thread con impostazioni locali en-US, non sembra esserci molto da fare al riguardo: il codice di eccezione di .NET Framework non ha strutture per sovrascrivere le impostazioni locali dei messaggi di errore.

Puoi cercare il messaggio di eccezione originale su unlocalize.com

Un punto controverso forse, ma invece di impostare la cultura in en-US , puoi impostarla su Invariant . Nella cultura Invariant , i messaggi di errore sono in inglese.

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

Ha il vantaggio di non sembrare prevenuto, specialmente per i locali di lingua inglese non americana. (alias, evita commenti spiacevoli da parte dei colleghi)

Windows ha bisogno di avere la lingua dell’interfaccia utente che si desidera utilizzare installata. Non è così, non ha modo di sapere magicamente quale sia il messaggio tradotto.

In un en-US windows 7 definitivo, con PT-PT installato, il seguente codice:

 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 messaggi in pt-PT, en-US e en-US. Poiché non sono installati file di cultura francese, per impostazione predefinita viene utilizzata la lingua predefinita di Windows (installata?).

Ecco una soluzione che non richiede alcuna codifica e funziona anche per i testi di eccezioni che vengono caricati troppo presto per consentirci di modificare il codice (ad esempio, quelli in mscorlib).

Potrebbe non essere sempre applicabile in ogni caso (dipende dal tuo setup in quanto devi essere in grado di creare un file .config a parte il file .exe principale) ma questo funziona per me. Quindi, crea un app.config in dev, (o un [myapp].exe.config o web.config in produzione) che contiene le seguenti linee, ad esempio:

  ...             ...  

Ciò che fa è dire al framework di redirect i bind di assembly per le risorse di mscorlib e le risorse di System.Xml, per le versioni comprese tra 1 e 999, in francese (culture è impostato su “fr”) per un assembly che … non esiste (un versione arbitraria 999).

Quindi, quando il CLR cercherà risorse francesi per questi due assembly (mscorlib e System.xml), non li troverà e ricadrà in inglese con garbo. A seconda del contesto e dei test, è ansible aggiungere altri assembly a questi reindirizzamenti (assembly che contengono risorse localizzate).

Ovviamente non penso che questo sia supportato da Microsoft, quindi usalo a tuo rischio. Bene, nel caso in cui si rilevi un problema, è sufficiente rimuovere questa configurazione e verificare che non sia correlata.

So che questo è un argomento vecchio, ma penso che la mia soluzione potrebbe essere abbastanza pertinente per chiunque vi si imbattesse in una ricerca sul web:

Nel logger delle eccezioni è ansible registrare ex.GetType.ToString, che salverà il nome della class di eccezioni. Mi aspetterei che il nome di una class dovrebbe essere indipendente dalla lingua e sarebbe quindi sempre rappresentato in inglese (ad esempio “System.FileNotFoundException”), anche se al momento non ho accesso a un sistema di lingua straniera per testare il idea.

Se si desidera veramente anche il testo del messaggio di errore, è ansible creare un dizionario di tutti i nomi di classi di eccezioni possibili e i relativi messaggi equivalenti in qualunque lingua si preferisca, ma per l’inglese penso che il nome della class sia perfettamente adeguato.

L’impostazione di Thread.CurrentThread.CurrentUICulture verrà utilizzata per localizzare le eccezioni. Se hai bisogno di due tipi di eccezioni (una per l’utente, una per te) puoi usare la seguente funzione per tradurre il messaggio di eccezione. Cerca nelle risorse di .NET-Libraries il testo originale per ottenere la chiave di risorsa e quindi restituisce il valore tradotto. Ma c’è una debolezza che non ho ancora trovato una buona soluzione: i messaggi, che contengono {0} in risorse, non saranno trovati. Se qualcuno ha una buona soluzione, sarei grato.

 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 } 

Immagino uno di questi approcci:

1) Le eccezioni vengono sempre e solo lette da te, cioè non sono una funzionalità client, quindi puoi usare stringhe non localizzate hardwired che non cambieranno quando corri in modalità turca.

2) Includere un codice di errore es. 0X00000001 con ogni errore in modo da poterlo facilmente visualizzare in un tavolo inglese.

 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; 

Senza WORKAROUNDS.

Tks 🙂

Il framework .NET è diviso in due parti:

  1. Lo stesso framework .NET
  2. I pacchetti di linguaggio framework .NET

Tutti i testi (ad esempio i messaggi di eccezione, le etichette dei pulsanti su un MessageBox, ecc.) Sono in inglese nello stesso framework .NET. I language pack hanno i testi localizzati.

A seconda della tua situazione esatta, una soluzione potrebbe essere quella di disinstallare i pacchetti di lingua (ad esempio dire al client di farlo). In tal caso, i testi delle eccezioni saranno in inglese. Si noti tuttavia che tutti gli altri testi forniti dal framework saranno anche in inglese (ad esempio le etichette dei pulsanti su un MessageBox, le scorciatoie da tastiera per ApplicationCommands).

Ho avuto la stessa situazione e tutte le risposte che ho trovato qui e altrove non hanno aiutato o non sono state soddisfacenti:
Imponi la lingua delle eccezioni in inglese
C # – Ottenere messaggi di eccezione in inglese quando l’applicazione è in un’altra lingua?
Come cambiare la lingua dei messaggi delle eccezioni di Visual Studio in inglese durante il debug
Come gestire la traduzione del messaggio di eccezione?
Come evitare completamente i messaggi di eccezione .NET localizzati

Thread.CurrentUICulture modifica la lingua delle eccezioni .net, ma non per Win32Exception , che utilizza le risorse di Windows nella lingua dell’interfaccia utente di Windows. Quindi non sono mai riuscito a stampare i messaggi di Win32Exception in inglese anziché in tedesco, nemmeno usando FormatMessage() come descritto in
Come ottenere Win32Exception in inglese?

Pertanto ho creato la mia soluzione, che memorizza la maggior parte dei messaggi di eccezione esistenti per lingue diverse in file esterni. Non riceverai il messaggio esatto nella lingua desiderata, ma riceverai un messaggio in quella lingua, che è molto più di quello che ricevi attualmente (che è un messaggio in una lingua che probabilmente non capisci).

Le funzioni statiche di questa class possono essere eseguite su installazioni Windows con lingue diverse: CreateMessages() crea i testi specifici della cultura
SaveMessagesToXML() li salva in tutti i file XML man mano che le lingue vengono create o caricate
LoadMessagesFromXML() carica tutti i file XML con messaggi specifici della lingua

Quando crei i file XML su diverse installazioni di Windows con lingue diverse, presto avrai tutte le lingue che ti servono.
Forse puoi creare i testi per lingue diverse su 1 Windows quando hai installato più language pack MUI, ma non l’ho ancora testato.

Testato con VS2008, pronto all’uso. Commenti e suggerimenti sono ben accetti!

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

È necessario registrare lo stack di chiamate anziché solo il messaggio di errore (IIRC, semplice eccezione.ToString () dovrebbe farlo per te). Da lì, è ansible determinare esattamente da dove ha origine l’eccezione e in genere dedurre quale eccezione sia.

Sovrascrivi il messaggio di eccezione nel blocco catch utilizzando il metodo di estensione, Verifica il messaggio generato dal codice o meno come indicato di seguito.

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

Per scopi di registrazione, alcune applicazioni potrebbero dover recuperare il messaggio di eccezione in inglese (oltre a visualizzarlo nell’usuale UICulture del client).

A tale scopo, il seguente codice

  1. cambia l’UICulture corrente
  2. ricrea l’object Exception lanciato usando “GetType ()” e “Activator.CreateInstance (t)”
  3. visualizza il nuovo messaggio dell’object Exception nel nuovo UICuture
  4. e infine modifica l’attuale UICulture in UICulture precedente.

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