سؤال

ونحن تسجيل أي الاستثناءات التي تحدث في النظام من خلال كتابة استثناء.رسالة إلى ملف.ومع ذلك ، فهي مكتوبة في ثقافة العميل.والتركية الأخطاء لا تعني الكثير بالنسبة لي.

فكيف يمكننا تسجيل أية رسائل خطأ في اللغة الإنجليزية دون تغيير المستخدمين الثقافة ؟

هل كانت مفيدة؟

المحلول

وهذه القضية يمكن أن يعمل جزئيا حولها. رمز الاستثناء إطار يحمل رسائل الخطأ من مواردها، استنادا إلى لغة موضوع الحالية. في حالة وجود بعض الاستثناءات، وهذا يحدث في الوقت الذي يتم الوصول إلى الخاصية رسالة.

لتلك الاستثناءات، يمكنك الحصول على النسخة الإنكليزية الكامل للرسالة عن طريق التحول لفترة وجيزة لغة موضوع أون للولايات المتحدة أثناء تسجيل ذلك (إنقاذ لغة المستخدم الأصلي مسبقا واستعادتها بعد ذلك على الفور).

والقيام بذلك في موضوع مستقل، بل هو أفضل: هذا يضمن أنه لن يكون هناك أي آثار جانبية. على سبيل المثال:

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

ولكن، وكما جو يشير بشكل صحيح في تعليق على مراجعة سابق من هذا الرد، بعض الرسائل بالفعل ( جزئيا) تحميل من موارد اللغة في الوقت الذي يتم طرح الاستثناء.

وهذا ينطبق على "المعلمة لا يمكن أن يكون لاغيا" جزء من الرسالة التي تم إنشاؤها عندما تم طرح ( "فو") استثناء ArgumentNullException، على سبيل المثال. في تلك الحالات، سوف لا تزال تظهر رسالة (جزئيا) المحلية، حتى عند استخدام رمز أعلاه.

وبخلاف باستخدام الخارقة غير عملية، مثل تشغيل كافة التعليمات البرمجية غير UI-على موضوع مع لغة الإنجليزية الأمريكية لتبدأ، لا يبدو أن هناك الكثير يمكنك القيام به حيال ذلك: استثناء برنامج .NET Framework كود لا يوجد لديه مرافق لتجاوز لغة رسالة خطأ.

نصائح أخرى

ويمكنك البحث عن رسالة الاستثناء الأصلية على unlocalize.com

وهناك نقطة خلافية ربما، ولكن بدلا من وضع الثقافة en-US، يمكنك تعيين لInvariant. في الثقافة Invariant، رسائل الخطأ باللغة الإنجليزية.

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

وانها ميزة من لا تبحث منحازة، وخصوصا لغات يتحدث الانجليزية غير أمريكية. (المعروف أيضا باسم يتجنب ملاحظات بذيئة من الزملاء)

ويندوز يحتاج إلى لغة واجهة المستخدم التي تريد استخدامها مثبتة. انها لا، فإنه لا يوجد لديه وسيلة لمعرفة سحرية ما هي الرسالة المترجمة.

في أحد النوافذ اون الولايات المتحدة 7 نهاية المطاف، مع PT-PT تثبيت، التعليمة البرمجية التالية:

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. حيث لا يوجد ملفات الثقافة الفرنسية مثبتة، لأنه تخلف عن التقصير النوافذ (تثبيت؟) لغة.

وهنا هو الحل الذي لا يتطلب أي ترميز ويعمل حتى للنصوص من الاستثناءات التي يتم تحميلها في وقت مبكر جدا بالنسبة لنا لتكون قادرة على تغيير عن طريق كود (على سبيل المثال، في تلك mscorlib).

قد لا تكون قابلة للتطبيق دائما في كل حالة (ان ذلك يعتمد على الإعداد الخاص بك كما تحتاج إلى أن تكون قادرة على إنشاء ملف .config جانبا ملف إكس الرئيسي) ولكن هذا يعمل بالنسبة لي. لذلك، مجرد خلق app.config في ديف، (أو [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;

وبدون الحلول.

وتكس:)

على .صافي الإطار يأتي في قسمين:

  1. على .NET framework نفسها
  2. على .NET framework حزم اللغات

جميع النصوص (ex.رسائل الاستثناء ، زر التسميات على MessageBox, الخ.) باللغة الإنجليزية في .صافي الإطار نفسه.حزم اللغات يكون مترجم النصوص.

اعتمادا على وضعك بالضبط, الحل هو تثبيت حزم اللغات (أيإخبار العميل للقيام بذلك).في هذه الحالة استثناء النصوص باللغة الإنجليزية.نلاحظ أن كل إطار آخر الموردة النص سوف يكون الإنجليزية وكذلك (ex.زر التسميات على MessageBox, اختصارات لوحة المفاتيح ApplicationCommands).

وسوف تستخدم Thread.CurrentThread.CurrentUICulture إعداد لحصر الاستثناءات. إذا كنت بحاجة إلى نوعين من الاستثناءات (واحد للمستخدم، واحدة لك) يمكنك استخدام الدالة التالية لترجمة-رسالة الاستثناء. انها تبحث في الموارد. NET مكتبات للنص أصلي للحصول على مفتاح الموارد ومن ثم إرجاع قيمة المترجمة. ولكن هناك ضعف واحد لم أجد حلا جيدا بعد: الرسائل، التي تحتوي على {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 يغير لغة الاستثناءات الصافية، ولكن لم يحدث ذلك لWin32Exception، والذي يستخدم موارد Windows في لغة ويندوز واجهة المستخدم نفسه. لذلك أنا لم تمكن من طباعة رسائل Win32Exception باللغة الإنجليزية بدلا من اللغة الألمانية، ولا حتى باستخدام FormatMessage() كما هو موضح في
كيفية الحصول على Win32Exception في اللغة الإنجليزية؟

لذلك أنا خلقت حل بلدي، الذي يخزن معظم الرسائل استثناء القائمة لغات مختلفة في الملفات الخارجية. أنك لن تحصل على الرسالة بالضبط جدا في اللغة التي تريدها، ولكن ستحصل على رسالة في تلك اللغة، التي هي أكثر بكثير مما كنت حاليا الحصول على (والذي هو رسالة في اللغة التي من المحتمل لا أفهم).

وظائف ثابتة من هذه الفئة يمكن تنفيذها على المنشآت ويندوز مع لغات مختلفة: CreateMessages() يخلق النصوص ثقافة محددة
SaveMessagesToXML() يوفر لهم العديد من الملفات XML كما يتم إنشاء اللغات أو تحميل
الأحمال LoadMessagesFromXML() جميع ملفات XML مع رسائل بلغة معينة

عند إنشاء ملفات XML على المنشآت ويندوز مختلفة مع لغات مختلفة، سيكون لديك قريبا بجميع اللغات التي تحتاج إليها.
ربما يمكنك إنشاء نصوص لغات مختلفة على 1 يندوز عندما يكون لديك العديد من حزم اللغات MUI مثبتة، ولكن أنا لم تختبر ذلك حتى الآن.

واختبار مع 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، exception.ToString بسيطة () يجب أن نفعل ذلك لك). من هناك، يمكنك تحديد بالضبط أين باستثناء نشأت من، وعادة ما نستنتج التي استثناء من ذلك.

ورسالة الاستثناء تجاوز في كتلة الصيد باستخدام أسلوب الإرشاد، وتحقق رسالة القيت هو من التعليمات البرمجية أو لا كما هو مذكور أدناه.

    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. التغييرات الحالية UICulture
  2. يعيد طرح استثناء كائن باستخدام "GetType()" & "المنشط.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