문제

우리는 예외를 파일에 작성하여 시스템에서 발생하는 예외를 기록하고 있습니다. 그러나 그들은 고객의 문화에 기록되어 있습니다. 그리고 터키 오류는 나에게 큰 의미가 없습니다.

그렇다면 사용자 문화를 변경하지 않고 영어로 오류 메시지를 어떻게 기록 할 수 있습니까?

도움이 되었습니까?

해결책

이 문제는 부분적으로 해결 될 수 있습니다. 프레임 워크 예외 코드는 현재 스레드 로케일을 기반으로 리소스에서 오류 메시지를로드합니다. 일부 예외의 경우 메시지 속성에 액세스 할 때 발생합니다.

이러한 예외는 스레드 로케일을 EN-US로 간단히 전환하여 전체 미국 영어 버전의 메시지를 얻을 수 있습니다 (원래 사용자 로케일을 미리 저장하고 즉시 복원).

별도의 스레드 에서이 작업을 수행하는 것이 더 좋습니다. 이것은 부작용이 없도록합니다. 예를 들어:

try
{
  System.IO.StreamReader sr=new System.IO.StreamReader(@"c:\does-not-exist");
}
catch(Exception ex)
{
  Console.WriteLine(ex.ToString()); //Will display localized message
  ExceptionLogger el = new ExceptionLogger(ex);
  System.Threading.Thread t = new System.Threading.Thread(el.DoLog);
  t.CurrentUICulture = new System.Globalization.CultureInfo("en-US");
  t.Start();
}

ExceptionLogger 클래스가 다음과 같습니다.

class ExceptionLogger
{
  Exception _ex;

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

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

그러나 AS 이 응답의 이전 개정에 대한 의견을 올바르게 지적하면 일부 메시지는 이미 예외가 발생할 때 언어 리소스에서 (부분적으로)로드되어 있습니다.

이것은 예를 들어 ArgumentNullexection ( "foo") 예외가 발생할 때 생성 된 메시지의 '매개 변수가 null이 될 수 없다'에 적용됩니다. 이 경우 위의 코드를 사용할 때에도 메시지가 여전히 (부분적으로) 로컬로 나타납니다.

EN-US 로케일이있는 스레드에서 모든 비 UI 코드를 실행하는 것과 같은 실용적으로 해킹을 사용하는 것 외에는 .NET Framework Exception Code가 없습니다. 오류 메시지 로케일을 재정의하기위한 시설.

다른 팁

원래 예외 메시지를 검색 할 수 있습니다 Unlocaite.com

아마도 논쟁의 여지가 있지만 문화를 설정하는 대신 en-US, 당신은 그것을 설정할 수 있습니다 Invariant. 에서 Invariant 문화, 오류 메시지는 영어로되어 있습니다.

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

특히 미국 이외의 영어를 사용하는 지역 지역의 편견이없는 이점이 있습니다. (일명 동료의 Snide 발언을 피합니다)

Windows에는 사용하려는 UI 언어가 있어야합니다. 그것은 번역 된 메시지가 무엇인지 마술처럼 아는 방법이 없습니다.

en

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;

PT-PT, EN-US 및 EN-US에서 메시지를 생성합니다. 프랑스 문화 파일이 설치되어 있지 않기 때문에 기본값은 Windows 기본값 (설치?) 언어로 표시됩니다.

다음은 코딩이 필요하지 않으며 코드 (예 : mscorlib의 코드)에 의해 변경 될 수 있도록 너무 일찍로드 된 예외의 텍스트조차도 작동하는 솔루션입니다.

모든 경우에 항상 적용 할 수있는 것은 아니지만 (기본 .EXE 파일을 제외하고 .config 파일을 만들 수 있어야하므로 설정에 따라 다름). 그러니 만 만들어주세요 app.config Dev에서 (또는 a [myapp].exe.config 또는 web.config 예를 들어 다음 줄이 포함되어 있습니다.

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

이것이하는 일은 어셈블리 바인딩을 리디렉션하는 프레임 워크를 알려주는 것입니다. mscorlib의 자원과 System.Xml프랑스어로 1에서 999 사이의 버전에 대한 자원 (문화가 설정됩니다.fr")는 ... 존재하지 않는 어셈블리에 (임의 버전 999) 존재하지 않는다.

따라서 CLR 이이 두 어셈블리 (Mscorlib 및 System.xml)에 대한 프랑스 자원을 찾을 때, 그것들을 찾지 못하고 영어로 우아하게 떨어집니다. 상황과 테스트에 따라이 리디렉션 (현지 자원이 포함 된 어셈블리)에 다른 어셈블리를 추가 할 수 있습니다.

물론 나는 이것이 Microsoft가 지원한다고 생각하지 않으므로 자신의 위험에 따라 사용하십시오. 글쎄, 문제를 감지하는 경우이 구성을 제거하고 관련이 없는지 확인할 수 있습니다.

나는 이것이 오래된 주제라는 것을 알고 있지만, 내 솔루션은 웹 검색에서 우연히 발견하는 사람과 관련이있을 수 있다고 생각합니다.

예외 로거에서는 예외 클래스의 이름을 저장하는 ex.getType.toString을 기록 할 수 있습니다. 나는 클래스의 이름이 언어와 무관해야하므로 항상 영어 (예 : "System.filenotFoundException")로 표현 될 것으로 기대하지만, 현재는 외국어 시스템에 액세스 할 수 없지만 아이디어.

오류 메시지 텍스트를 실제로 원한다면 가능한 모든 예외 클래스 이름의 사전과 선호하는 언어로 동등한 메시지를 만들 수 있지만 영어의 경우 클래스 이름이 완벽하다고 생각합니다.

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;

해결 방법없이.

tks :)

.NET 프레임 워크는 두 부분으로 제공됩니다.

  1. .NET 프레임 워크 자체
  2. .NET 프레임 워크 언어 팩

모든 텍스트 (예외 메시지, MessageBox의 버튼 레이블 등)는 .NET 프레임 워크 자체의 영어로되어 있습니다. 언어 팩에는 현지화 된 텍스트가 있습니다.

정확한 상황에 따라 솔루션은 언어 팩을 제거하는 것입니다 (즉, 고객에게 그렇게하도록 지시하십시오). 이 경우 예외 텍스트는 영어로됩니다. 그러나 다른 모든 프레임 워크가 제공 한 텍스트는 영어가 될 것입니다 (예 : MessageBox의 버튼 레이블, 응용 프로그램위원회의 키보드 바로 가기).

환경 Thread.CurrentThread.CurrentUICulture 예외를 현지화하는 데 사용됩니다. 두 가지 종류의 예외가 필요한 경우 (사용자를위한 하나, 하나) 다음 함수를 사용하여 예외 메시지를 변환 할 수 있습니다. Orignal 텍스트를 위해 .NET-Libraries 리소스를 검색하여 Resource-Key를 얻은 다음 번역 된 값을 반환합니다. 그러나 아직 좋은 해결책을 찾지 못한 약점이 있습니다. 자원에 {0}이 포함 된 메시지는 찾을 수 없습니다. 누구든지 좋은 해결책이 있다면 감사 할 것입니다.

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
}

나는 이러한 접근법 중 하나를 상상할 것입니다.

1) 예외는 당신에 의해서만 읽히고, 즉 클라이언트 기능이 아니므로 터키 모드에서 실행할 때 변경되지 않는 하드 유선이 아닌 현지 문자열을 사용할 수 있습니다.

2) 오류 코드 포함 예를 들어. 각 오류마다 0x00000001을 사용하여 영어 테이블에서 쉽게 볼 수 있습니다.

나는 같은 상황을 겪었고, 여기와 다른 곳에서 찾은 모든 대답은 도움이되지 않았거나 만족하지 않았다.
영어로 언어를 강제로 예외
C #- 응용 프로그램이 다른 언어로있을 때 영어로 예외 메시지를 받으시겠습니까?
디버깅 중에 비주얼 스튜디오 예외 메시지 언어를 영어로 변경하는 방법
예외 메시지 번역을 처리하는 방법은 무엇입니까?
현지화 된 .NET 예외 메시지를 완전히 피하는 방법

그만큼 Thread.CurrentUICulture .NET 예외의 언어를 변경하지만 Win32Exception, Windows UI 자체의 언어로 Windows 리소스를 사용합니다. 그래서 나는 메시지를 인쇄하지 않았습니다 Win32Exception 독일 대신 영어로 FormatMessage() 설명대로
영어로 Win32Exception을 얻는 방법?

따라서 외부 파일에 다른 언어에 대한 대부분의 기존 예외 메시지를 저장하는 내 자신의 솔루션을 만들었습니다. 원하는 언어로 정확한 메시지를받지는 못하지만 현재 얻는 것보다 훨씬 더 많은 언어로 메시지를 받게됩니다 (이해할 수없는 언어로 메시지입니다).

이 클래스의 정적 기능은 다른 언어로 Windows 설치에서 실행될 수 있습니다.CreateMessages() 문화 별 텍스트를 만듭니다
SaveMessagesToXML() 언어가 생성되거나로드되는만큼 많은 XML 파일에 저장합니다.
LoadMessagesFromXML() 모든 XML 파일을 언어 별 메시지로로드합니다

다른 언어로 다른 Windows 설치에 XML 파일을 작성할 때 곧 필요한 모든 언어를 갖게됩니다.
여러 MUI 언어 팩이 설치된 경우 1 개의 창에서 다른 언어에 대한 텍스트를 만들 수 있지만 아직 테스트하지 않았습니다.

VS2008로 테스트, 사용할 준비가되었습니다. 의견과 제안을 환영합니다!

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

Undercover1989 답변을 기반으로하지만 매개 변수를 고려하고 메시지가 여러 리소스 문자열 (인수 예외)으로 구성된 시점을 고려합니다.

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

오류 메시지 대신 통화 스택을 기록해야합니다 (IIRC, Simple Exception.ToString ()은 귀하를 위해이를 수행해야합니다). 거기에서 예외가 어디에서 발생했는지 정확히 결정하고 일반적으로 어떤 예외를 추론 할 수 있습니다.

Catch Block의 예외 메시지를 확장 방법을 사용하여 예외 메시지를 재정의하고 아래에 언급 된 것과 같이 THROWN 메시지가 코드에서 확인하십시오.

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

로깅 목적으로 특정 응용 프로그램은 영어 예외 메시지를 가져와야 할 수도 있습니다 (일반적인 클라이언트의 UICULTURE에 표시하는 것 외에도).

그 목적을 위해 다음 코드입니다

  1. 현재 유사체를 변경합니다
  2. "gettype ()"& "activator.createinstance (t)"를 사용하여 던진 예외 객체를 재현합니다.
  3. 새로운 uicuture에 새로운 예외 객체의 메시지를 표시합니다.
  4. 그리고 마지막으로 현재의 uiculture를 초기 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();
    
         }
    
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top