Frage

Wir sind eine Protokollierung von Ausnahmen, die es in unserem system, indem Sie die Ausnahme.Nachricht in einer Datei.Jedoch, Sie sind geschrieben in der Kultur des Kunden.Und türkische Fehler nicht bedeuten mir sehr viel.

Wie können wir also den log-Fehlermeldungen in Englisch ohne änderung der Benutzer-Kultur?

War es hilfreich?

Lösung

Dieses Problem kann teilweise gelöst.Die Framework-Ausnahme-code lädt die Fehlermeldungen von seinen Ressourcen, basierend auf den aktuellen thread locale.Im Fall von einigen Ausnahmen, dies geschieht bei der die Message-Eigenschaft zugegriffen wird.

Für diejenigen Ausnahmen, erhalten Sie die vollständige englische version der Nachricht durch kurzes einschalten des Faden-locale-en-US, während es Protokollierung (Speicherung des ursprünglichen Benutzers Gebietsschema-vorher und wiederherstellen Sie unmittelbar danach).

Tun dies auf einem separaten thread wird noch besser:dies stellt sicher, dass es keine Nebenwirkungen.Zum Beispiel:

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

Wo die ExceptionLogger Klasse sieht ungefähr so aus:

class ExceptionLogger
{
  Exception _ex;

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

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

Jedoch, wie Joe richtig betont in einem Kommentar zu einer früheren Version dieser Antwort, einige Nachrichten sind bereits (teilweise) geladen, aus der Sprache-Ressourcen an der Zeit die Ausnahme ausgelöst wird.

Dies gilt für die "parameter kann nicht null sein' Teil der Nachricht erzeugt, wenn eine ArgumentNullException("foo") - Ausnahme wird ausgelöst, zum Beispiel.In diesen Fällen wird die Nachricht noch immer angezeigt wird (teilweise) lokalisiert, auch wenn Sie mit dem obigen code.

Andere, als bei der Verwendung unpraktisch hacks, wie laufen, alle Ihre nicht-UI-code in einem thread mit en-US-Gebietsschema um zu beginnen mit, es scheint nicht viel können Sie dagegen tun:die .NET Framework-Ausnahme-code hat keine Einrichtungen für das überschreiben der Fehlermeldung locale.

Andere Tipps

Sie können für die ursprüngliche Ausnahmemeldung suchen unter unlocalize.com

Ein strittiger Punkt vielleicht, sondern die Kultur der Einstellung en-US, können Sie es auf Invariant. In der Invariant Kultur sind die Fehlermeldungen in englischer Sprache.

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

Es hat den Vorteil, nicht auf der Suche voreingenommen, vor allem für nicht-amerikanisches Englisch sprechender Gegenden. (Auch bekannt als vermeidet abfällige Bemerkungen von Kollegen)

Windows muss die Sprache der Benutzeroberfläche Sie installierte verwenden möchten haben. Es tut es nicht, es keine Möglichkeit, auf magische Weise zu wissen hat, was die übersetzte Nachricht ist.

In einem en-US windows 7, mit pt-PT installiert ist, der folgende 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;

Erzeugt Nachrichten in pt-PT, en-US und en-US. Da gibt es keine Kultur Französisch-Dateien installiert, wird standardmäßig der Windows-Standard (installiert?) Sprache.

Hier Lösung, die keine Codierung benötigt und funktioniert auch für Texte von Ausnahmen, die zu früh geladen sind für uns in der Lage sein, durch den Code zu ändern (zum Beispiel der in mscorlib).

Es kann nicht in jedem Fall immer anwendbar sein (abhängig von Ihrem Setup, wie Sie beiseite eine CONFIG-Datei erstellen müssen in der Lage sein die Haupt EXE-Datei), aber das funktioniert für mich. Also, nur ein app.config in dev erstellen (oder einem [myapp].exe.config oder web.config in der Produktion), die die folgenden Zeilen enthält zum Beispiel:

<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>

Was das bedeutet ist, den Rahmen sagen Montage-Bindings für mscorlib Ressourcen und System.Xml Ressourcen, für die Versionen zwischen 1 und 999, in französisch zu umleiten (Kultur wird auf „fr“) zu einer Baugruppe, die ... nicht existiert ( eine beliebige Version 999).

Also, wenn die CLR für Französisch Ressourcen für diese beiden Baugruppen aussehen (mscorlib und System.xml), es wird sie nicht ordnungsgemäß auf Englisch finden und Rückfall. Je nach Ihrem Kontext und Prüfungen, Sie könnten auch andere Baugruppen auf diese Umleitungen hinzufügen möchten (Baugruppen, die Ressourcen enthält, lokalisiert).

Natürlich glaube ich das nicht von Microsoft unterstützt wird, erfolgt auf eigene Gefahr. Nun, falls Sie ein Problem erkennen, können Sie einfach diese Konfiguration entfernen und überprüfen, es ist in keinem Zusammenhang.

Ich weiß, dies ist ein altes Thema, aber ich denke, dass meine Lösung durchaus relevant sein kann, für jeden, der in einer Web-Suche über sie stolpert:

In der Ausnahme Logger können Sie ex.GetType.ToString einzuloggen, die den Namen der Ausnahmeklasse retten würde. Ich würde erwarten, dass der Name einer Klasse soll unabhängig von Sprache sein und würde daher immer in englischer Sprache (zB „System.FileNotFoundException“) dargestellt werden, obwohl derzeit Ich habe keinen Zugriff auf ein Fremdsprachensystem zu testen, die Idee.

Wenn Sie wirklich die Fehlermeldung Text als auch wollen Sie ein Wörterbuch aller möglichen Ausnahme Klassennamen erstellen können und ihre äquivalenten Meldungen in welcher Sprache Sie bevorzugen, aber für Englisch Ich denke, der Klassenname vollkommen ausreichend ist.

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;

Ohne UMGEHT.

Tks:)

Die .NET-Framework besteht aus zwei Teilen:

  1. Der .NET-Framework selbst
  2. Die .NET-Framework Sprachpakete

Alle Texte (ex. Ausnahmemeldungen, Tastenbeschriftungen auf einem MessageBox, etc.) sind in englischer Sprache in .NET Framework selbst. Die Sprachpakete haben die lokalisierten Texte.

Je nach Ihrer genauen Situation würde eine Lösung sein, die Sprachpakete zu deinstallieren (das heißt dem Client sagen, dies zu tun). In diesem Fall werden die Ausnahmetexte in englischer Sprache. Beachten Sie jedoch, dass alle anderen Rahmen gelieferten Text Englisch wird auch (ex. Die Tastenbeschriftungen auf einer MessageBox, Tastaturkürzel für Application).

Einstellung Thread.CurrentThread.CurrentUICulture wird verwendet, um die Ausnahmen zu lokalisieren. Wenn Sie zwei Arten von Ausnahmen müssen (eine für den Benutzer, eine für Sie) können Sie folgende Funktion verwenden, um die Ausnahme-Nachricht zu übersetzen. Es ist die Suche in den .NET-Bibliotheken Ressourcen für den Orignal Text den Ressource-Schlüssel und gibt dann den übersetzten Wert. Aber es ist eine Schwäche, die ich nicht eine gute Lösung gefunden habe noch: Nachrichten, die {0} in Ressourcen enthält, wird nicht gefunden werden. Wenn jemand eine gute Lösung haben wäre ich dankbar.

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
}

Ich würde eines dieser Ansätze vorstellen:

1) Die Ausnahmen werden immer nur von Ihnen gelesen, das heißt, sie sind nicht ein Client-Funktion, so dass Sie fest verdrahtete nicht lokalisierten Strings verwenden können, wenn Sie in Türkisch-Modus ausgeführt wird sich nicht ändern.

2) Fügen Sie einen Fehlercode z. 0x00000001 mit jedem Fehler, so dass Sie es leicht nach oben in einer Englisch-Tabelle suchen in.

Ich habe die gleiche Situation hat, und alle Antworten, die ich hier und anderswo nicht helfen oder waren nicht befriedigend:
Force-Ausnahmen Sprache auf Englisch
C # - Erste Ausnahmemeldungen in Englisch, wenn die Anwendung in einer anderen Sprache?
Wie Visual Studio Ausnahmemeldung Sprache ändern auf Englisch beim Debuggen
Wie Übersetzung von Ausnahmemeldung behandeln?
Wie vollständig lokalisierte .NET Ausnahmemeldungen vermeiden

Die Thread.CurrentUICulture ändert sich die Sprache der .net Ausnahmen, aber es funktioniert nicht für Win32Exception, die sich Windows-Ressourcen in der Sprache der Windows-Benutzeroberfläche verwendet. So konnte ich nie die Nachrichten von Win32Exception in Englisch statt Deutsch, nicht einmal unter Verwendung FormatMessage() drucken, wie in
beschrieben Wie Win32Exception auf Englisch bekommen?

Deshalb habe ich meine eigene Lösung, die die Mehrheit der bestehenden Ausnahmemeldungen für verschiedene Sprachen in externen Dateien gespeichert werden. Sie werden die sehr genau die Nachricht in der gewünschten Sprache nicht bekommen, aber Sie werden eine Nachricht in dieser Sprache erhalten, die viel mehr ist als Sie derzeit bekommen (die eine Nachricht in einer Sprache, die Sie wahrscheinlich nicht verstehen).

Die statischen Funktionen dieser Klasse können auf Windows-Installationen mit verschiedenen Sprachen ausgeführt werden: CreateMessages() schafft die kulturspezifische Texte
SaveMessagesToXML() speichert sie, um so viele XML-Dateien als Sprachen erstellt werden, in oder geladen LoadMessagesFromXML() lädt alle XML-Dateien mit sprachspezifischen Nachrichten

Wenn die XML-Dateien auf verschiedenen Windows-Installationen mit unterschiedlichen Sprachen zu schaffen, werden Sie schnell alle Sprachen, die Sie brauchen.
Vielleicht können Sie die Texte für verschiedene Sprachen auf 1 Windows erstellen, wenn Sie mehr MUI-Sprachpakete installiert haben, aber ich habe das noch nicht getestet.

Getestet mit VS2008, gebrauchsfertig. Kommentare und Anregungen sind willkommen!

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<string, string> 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<string, string> dictExceptionMessage = new Dictionary<string, string>(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<CultureInfo, Dictionary<string, string>> kvpCultureExceptionMessages in ms_dictCultureExceptionMessages)
    {
      string sXmlPathFilename = i_sPath + i_sBaseFilename + "_" + kvpCultureExceptionMessages.Key.TwoLetterISOLanguageName + ".xml";
      Dictionary<string, string> 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<string, string> 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<string, string> dictExceptionMessage = new Dictionary<string, string>(0x1000);

    GetExceptionMessages(dictExceptionMessage);
    GetExceptionMessagesWin32(dictExceptionMessage);

    ms_dictCultureExceptionMessages.Add(Thread.CurrentThread.CurrentUICulture, dictExceptionMessage);
  }

  //----------------------------------------------------------------------------
  // GetExceptionTypes
  //----------------------------------------------------------------------------
  private static List<Type> GetExceptionTypes()
  {
    Assembly[] aoAssembly = AppDomain.CurrentDomain.GetAssemblies();

    List<Type> listoExceptionType = new List<Type>();

    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<string, string> i_dictExceptionMessage)
  {
    List<Type> 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<string, string> 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<CultureInfo, Dictionary<string, string>> ms_dictCultureExceptionMessages = new Dictionary<CultureInfo, Dictionary<string, string>>();
}

internal class Program
{
  public static void Main()
  {
    CException.CreateMessages(null);
    CException.SaveMessagesToXML(@"d:\temp\", "emsg");
    CException.LoadMessagesFromXML(@"d:\temp\", "emsg");
  }
}

Auf der Grundlage der Undercover1989 Antwort, sondern berücksichtigen Parameter und wenn Nachrichten von mehreren Ressourcen-Strings zusammengesetzt sind (wie Argument Ausnahmen).

public static string TranslateExceptionMessage(Exception exception, CultureInfo targetCulture)
{
    Assembly a = exception.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);

    var result = exception.Message;

    foreach (DictionaryEntry item in rsOriginal)
    {
        if (!(item.Value is string message))
            continue;

        string translated = rsTranslated.GetString(item.Key.ToString(), false);

        if (!message.Contains("{"))
        {
            result = result.Replace(message, translated);
        }
        else
        {
            var pattern = $"{Regex.Escape(message)}";
            pattern = Regex.Replace(pattern, @"\\{([0-9]+)\}", "(?<group$1>.*)");

            var regex = new Regex(pattern);

            var replacePattern = translated;
            replacePattern = Regex.Replace(replacePattern, @"{([0-9]+)}", @"${group$1}");
            replacePattern = replacePattern.Replace("\\$", "$");

            result = regex.Replace(result, replacePattern);
        }
    }

    return result;
}

Sie sollten den Call-Stack einloggen, anstatt nur Fehlermeldung (IIRC, einfach exception.ToString () sollte das für Sie tun). Von dort können Sie genau bestimmen, wo die Ausnahme von ihrem Ursprung, und in der Regel ableiten, welche Ausnahme es ist.

Aufschalten Ausnahmemeldung in Block fängt mit Erweiterungsmethode, geworfen Nachricht Überprüfen von Code ist oder nicht, wie unten erwähnt.

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

Für Protokollierungszwecke bestimmte Anwendungen müssen möglicherweise die englische Ausnahmemeldung holen (außer es in den gewöhnlichen Kunden UICulture Anzeigen).

Zu diesem Zweck den folgenden Code

  1. ändert die aktuellen UICulture
  2. erstellt das geworfen Exception-Objekt mit "GetType ()" und "Activator.CreateInstance (t)"
  3. zeigt die neue Exception-Objekt der Nachricht in der neuen UICuture
  4. und dann ändert sich schließlich die aktuelle UICulture zu früher zurück UICulture.

        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();
    
         }
    
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top