Wir protokollieren alle Ausnahmen, die in unserem System auftreten, indem wir die Exception.Message in eine Datei schreiben. Sie sind jedoch in der Kultur des Kunden geschrieben. Und türkische Fehler bedeuten mir nicht viel.
Wie können wir also Fehlermeldungen auf Englisch protokollieren, ohne die Benutzerkultur zu ändern?
c#
.net
exception
localization
Carra
quelle
quelle
Antworten:
Dieses Problem kann teilweise umgangen werden. Der Framework-Ausnahmecode lädt die Fehlermeldungen aus seinen Ressourcen basierend auf dem aktuellen Thread-Gebietsschema. Bei einigen Ausnahmen geschieht dies zum Zeitpunkt des Zugriffs auf die Message-Eigenschaft.
Für diese Ausnahmen können Sie die vollständige englische Version der Nachricht erhalten, indem Sie das Thread-Gebietsschema während der Protokollierung kurz auf en-US ändern (das ursprüngliche Gebietsschema des Benutzers vorher speichern und unmittelbar danach wiederherstellen).
Dies in einem separaten Thread zu tun ist noch besser: Dadurch wird sichergestellt, dass keine Nebenwirkungen auftreten. Beispielsweise:
Wo die ExceptionLogger-Klasse ungefähr so aussieht:
Wie Joe jedoch in einem Kommentar zu einer früheren Überarbeitung dieser Antwort richtig hervorhebt, werden einige Nachrichten zum Zeitpunkt des Auslösens der Ausnahme bereits (teilweise) aus den Sprachressourcen geladen.
Dies gilt für den Teil 'Parameter darf nicht null sein' der Nachricht, der beispielsweise generiert wird, wenn eine ArgumentNullException-Ausnahme ("foo") ausgelöst wird. In diesen Fällen wird die Nachricht auch bei Verwendung des obigen Codes (teilweise) lokalisiert angezeigt.
Abgesehen von der Verwendung unpraktischer Hacks, z. B. dem Ausführen Ihres gesamten Nicht-UI-Codes in einem Thread mit dem Gebietsschema en-US, scheint es nicht viel zu geben, was Sie dagegen tun können: Der .NET Framework-Ausnahmecode hat keine Möglichkeiten zum Überschreiben des Gebietsschemas für Fehlermeldungen.
quelle
t.CurrentUICulture = new System.Globalization.CultureInfo("fr-FR");
undt.CurrentCulture = new System.Globalization.CultureInfo("fr-FR");
doch war die resultierende Ausnahme auf Englisch ...Environment.GetResourceString("...")
sodass Ihre Lösung nicht mehr funktioniert. Am besten lösen Sie eine benutzerdefinierte Ausnahme mit Ihrem eigenen (englischen) Nachrichtentext aus und verwenden die InnerException-Eigenschaft, um die alte beizubehalten.Sie können unter unlocalize.com nach der ursprünglichen Ausnahmemeldung suchen
quelle
No records found
.Ein umstrittener Punkt vielleicht, aber anstatt die Kultur festzulegen
en-US
, können Sie sie festlegenInvariant
. In derInvariant
Kultur sind die Fehlermeldungen auf Englisch.Es hat den Vorteil, dass es nicht voreingenommen aussieht, insbesondere für nicht amerikanischsprachige englischsprachige Gebiete. (aka vermeidet abfällige Bemerkungen von Kollegen)
quelle
catch
.Hier ist eine Lösung, die keine Codierung erfordert und auch für Texte von Ausnahmen funktioniert, die zu früh geladen wurden, als dass wir sie per Code ändern könnten (z. B. in mscorlib).
Es ist möglicherweise nicht immer in jedem Fall anwendbar (es hängt von Ihrem Setup ab, da Sie in der Lage sein müssen, eine .config-Datei neben der .exe-Hauptdatei zu erstellen), aber das funktioniert für mich. Erstellen Sie einfach ein
app.config
in dev (oder ein[myapp].exe.config
oderweb.config
in der Produktion), das beispielsweise die folgenden Zeilen enthält:Dies weist das Framework an, Assembly-Bindungen für
mscorlib
die Ressourcen undSystem.Xml
die Ressourcen für Versionen zwischen 1 und 999 in Französisch (Kultur ist auf "fr
" gesetzt) an eine Assembly umzuleiten , die ... nicht existiert (eine beliebige) Version 999).Wenn die CLR nach französischen Ressourcen für diese beiden Assemblys (mscorlib und System.xml) sucht, findet sie diese nicht und greift ordnungsgemäß auf Englisch zurück. Abhängig von Ihrem Kontext und Ihren Tests möchten Sie diesen Weiterleitungen möglicherweise andere Assemblys hinzufügen (Assemblys, die lokalisierte Ressourcen enthalten).
Natürlich glaube ich nicht, dass dies von Microsoft unterstützt wird. Verwenden Sie es daher auf eigenes Risiko. Wenn Sie ein Problem feststellen, können Sie diese Konfiguration einfach entfernen und überprüfen, ob sie nicht in Zusammenhang steht.
quelle
In Windows muss die gewünschte UI-Sprache installiert sein. Wenn dies nicht der Fall ist, kann es nicht auf magische Weise wissen, was die übersetzte Nachricht ist.
In einem Windows 7 Ultimate in den USA mit installiertem pt-PT wird der folgende Code angezeigt:
Erzeugt Nachrichten in pt-PT, en-US und en-US. Da keine französischen Kulturdateien installiert sind, wird standardmäßig die Windows-Standardsprache (installiert?) Verwendet.
quelle
Ich weiß, dass dies ein altes Thema ist, aber ich denke, dass meine Lösung für jeden relevant sein kann, der bei einer Websuche darauf stößt:
Im Ausnahmeprotokollierer können Sie ex.GetType.ToString protokollieren, wodurch der Name der Ausnahmeklasse gespeichert wird. Ich würde erwarten, dass der Name einer Klasse unabhängig von der Sprache sein sollte und daher immer in Englisch dargestellt wird (z. B. "System.FileNotFoundException"), obwohl ich derzeit keinen Zugriff auf ein Fremdsprachen-System habe, um das zu testen Idee.
Wenn Sie den Text der Fehlermeldung auch wirklich möchten, können Sie ein Wörterbuch aller möglichen Ausnahmeklassennamen und ihrer entsprechenden Nachrichten in einer beliebigen Sprache erstellen, aber für Englisch halte ich den Klassennamen für vollkommen ausreichend.
quelle
InvalidOperationException
, von geworfenSystem.Xml.XmlWellFormedWriter
. Sie versuchen zu erraten, welcher bestimmte Fehler aufgetreten ist, ohne die Nachricht zu lesen. Könnten tausend verschiedene Dinge sein.Ohne Workarounds.
Tks :)
quelle
Die Einstellung
Thread.CurrentThread.CurrentUICulture
wird verwendet, um die Ausnahmen zu lokalisieren. Wenn Sie zwei Arten von Ausnahmen benötigen (eine für den Benutzer, eine für Sie), können Sie die Ausnahmemeldung mit der folgenden Funktion übersetzen. In den .NET-Libraries-Ressourcen wird nach dem Originaltext gesucht, um den Ressourcenschlüssel zu erhalten und dann den übersetzten Wert zurückzugeben. Aber es gibt eine Schwäche, für die ich noch keine gute Lösung gefunden habe: Nachrichten, die {0} in Ressourcen enthalten, werden nicht gefunden. Wenn jemand eine gute Lösung hat, wäre ich dankbar.quelle
Das .NET Framework besteht aus zwei Teilen:
Alle Texte (z. B. Ausnahmemeldungen, Schaltflächenbeschriftungen in einer MessageBox usw.) sind im .NET Framework selbst in englischer Sprache verfügbar. Die Sprachpakete enthalten die lokalisierten Texte.
Abhängig von Ihrer genauen Situation besteht eine Lösung darin, die Sprachpakete zu deinstallieren (dh den Client dazu aufzufordern). In diesem Fall sind die Ausnahmetexte in englischer Sprache. Beachten Sie jedoch, dass alle anderen vom Framework bereitgestellten Texte ebenfalls englisch sind (z. B. die Schaltflächenbeschriftungen in einer MessageBox, Tastaturkürzel für ApplicationCommands).
quelle
Ich würde mir einen dieser Ansätze vorstellen:
Die Ausnahmen werden immer nur von Ihnen gelesen, dh sie sind keine Clientfunktion. Sie können also festverdrahtete, nicht lokalisierte Zeichenfolgen verwenden, die sich im türkischen Modus nicht ändern.
Fügen Sie z. B.
0x00000001
jedem Fehler einen Fehlercode hinzu, damit Sie ihn problemlos in einer englischen Tabelle nachschlagen können.quelle
Basierend auf der Undercover1989-Antwort, berücksichtigt jedoch Parameter und wenn Nachrichten aus mehreren Ressourcenzeichenfolgen bestehen (wie Argumentausnahmen).
quelle
Ich hatte die gleiche Situation und alle Antworten, die ich hier und anderswo fand, halfen nicht oder waren nicht zufriedenstellend:
Das
Thread.CurrentUICulture
ändert die Sprache der .net-Ausnahmen, jedoch nicht fürWin32Exception
, die Windows-Ressourcen in der Sprache der Windows-Benutzeroberfläche selbst verwendet. Daher habe ich es nie geschafft, die NachrichtenWin32Exception
auf Englisch statt auf Deutsch zu drucken , auch nicht mitFormatMessage()
der Beschreibung unterWie bekomme ich Win32Exception auf Englisch?
Aus diesem Grund habe ich meine eigene Lösung erstellt, in der die meisten vorhandenen Ausnahmemeldungen für verschiedene Sprachen in externen Dateien gespeichert sind. Sie erhalten nicht die sehr genaue Nachricht in Ihrer gewünschten Sprache, aber Sie erhalten eine Nachricht in dieser Sprache, die viel mehr ist als derzeit (eine Nachricht in einer Sprache, die Sie wahrscheinlich nicht verstehen).
Die statischen Funktionen dieser Klasse können in Windows-Installationen mit verschiedenen Sprachen ausgeführt werden: Beim
CreateMessages()
Erstellen der kulturspezifischen Texte werdenSaveMessagesToXML()
diese in so vielen XML-Dateien gespeichert, wie Sprachen erstellt oder geladenLoadMessagesFromXML()
werden. Alle XML-Dateien werden mit sprachspezifischen Nachrichten geladenWenn Sie die XML-Dateien in verschiedenen Windows-Installationen mit verschiedenen Sprachen erstellen, stehen Ihnen bald alle benötigten Sprachen zur Verfügung.
Vielleicht können Sie die Texte für verschiedene Sprachen unter 1 Windows erstellen, wenn Sie mehrere MUI-Sprachpakete installiert haben, aber das habe ich noch nicht getestet.
Getestet mit VS2008, gebrauchsfertig. Kommentare und Vorschläge sind willkommen!
quelle
Thread.CurrentUICulture
auch die Sprache der Benutzeroberfläche geändert, was sie zu einer schrecklichen Option macht. Ein klassisches Beispiel sind die Schaltflächen Ja / Nein / OK / Abbrechen im Meldungsfeld.Ausnahmemeldungen in Englisch
Gehen Sie dann zum Lokalisierungsordner, platzieren Sie ihn in projectName.xml und fügen Sie ihn hinzu
quelle
Sie sollten den Aufrufstapel statt nur einer Fehlermeldung protokollieren (IIRC, einfache Ausnahme. ToString () sollte dies für Sie tun). Von dort aus können Sie genau bestimmen, woher die Ausnahme stammt, und in der Regel ableiten, um welche Ausnahme es sich handelt.
quelle
Überschreiben Sie die Ausnahmemeldung im catch-Block mithilfe der Erweiterungsmethode. Überprüfen Sie, ob die ausgelöste Nachricht aus dem Code stammt oder nicht, wie unten erwähnt.
quelle
InvalidOperationException
. Viel Spaß beim Herausfinden, was das ohne die Nachricht selbst bedeutet. Eine neue Instanz wird es nicht auf magische Weise haben.Für Protokollierungszwecke müssen bestimmte Anwendungen möglicherweise die englische Ausnahmemeldung abrufen (abgesehen davon, dass sie in der UICulture des üblichen Clients angezeigt wird).
Zu diesem Zweck den folgenden Code
und ändert dann schließlich die aktuelle UICulture zurück zu früherer UICulture.
quelle