2015-12-22 8 views
5

मैं अंग्रेजी में सभी Exception संदेश प्राप्त करने का प्रयास कर रहा हूं, इससे कोई फर्क नहीं पड़ता कि मेरा प्रोग्राम किस मशीन पर चल रहा है।अंग्रेजी में Win32Exception कैसे प्राप्त करें?

मैं निम्न पदों से जवाब का उपयोग कर अंग्रेजी में लगभग सभी अपवाद संदेश प्राप्त करने के लिए प्रबंधन किया है: Exception messages in English? और कुछ अन्य समाधान मैं (प्रतिबिंब का उपयोग डिफ़ॉल्ट CultureInfo बदलने के लिए की तरह) मिल गया है। मुझे SocketException के साथ विशिष्ट समस्या है, कोई फर्क नहीं पड़ता कि मैं क्या कर रहा हूं मैं इसे डिफ़ॉल्ट मशीन की भाषा में प्राप्त कर रहा हूं।

मैं एक परीक्षण कार्यक्रम बना लिया है समस्या को दिखाने के लिए:

using System; 
using System.Text; 
using System.Threading; 
using System.IO; 
using System.Net.Sockets; 
using System.Reflection; 
using System.Globalization; 

namespace TestApp 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      try 
      { 
       //I'm not listening on the following port: 
       TcpClient s = new TcpClient("localhost", 2121); 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine("Socket exception: " + ex.Message); 
      } 
      try 
      { 
       //the following file doesn't exists: 
       File.ReadAllText("filenotexist.txt"); 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine("File exception: " + ex.Message); 
      } 
     } 
    } 
} 

मेरी मशीन पर यह परिणाम निम्न पाठ:

H:\Shared>Test-def.exe 
Socket exception: No connection could be made because the target machine actively refused it 127.0.0.1:2121 
File exception: Could not find file 'H:\Shared\filenotexist.txt'. 

इस परीक्षा कार्यक्रम डिफ़ॉल्ट भाषा में अपवाद प्रिंट होगा

Z:\>Test-def.exe 
Socket exception: 対象のコンピューターによって拒否されたため、接続できませんでした。 127.0.0.1:2121 
File exception: ファイル 'Z:\filenotexist.txt' が見つかりませんでした。 
: जापानी मशीन पर यह जापानी में सभी अपवादों को (जो मुझे समझ नहीं आता) लिखने

(जापानी '\' जापानी मशीन में अलग दिखता है, लेकिन जब मेरी मशीन में कॉपी किया यह '\' के रूप में दिखाया गया है)

तो जवाब मैंने पाया की संयोजन से, मैं निम्नलिखित समाधान को क्रियान्वित किया है, तो अब यह इस तरह दिखता है:

Z:\>Test-en.exe 
Socket exception: 対象のコンピューターによって拒否されたため、接続できませんでした。 127.0.0.1:2121 
File exception: Could not find file 'Z:\filenotexist.txt'. 

मैं भी कुछ अन्य परीक्षण किया है:

namespace TestApp 
{ 
    class Program 
    { 
     //will change CultureInfo to English, this should change all threads CultureInfo to English. 
     public static void SetEnglishCulture() 
     { 
      CultureInfo ci = new CultureInfo("en-US"); 
      //change CultureInfo for current thread: 
      Thread.CurrentThread.CurrentUICulture = ci; 
      Thread.CurrentThread.CurrentCulture = ci; 

      //change CultureInfo for new threads: 
      Type t = typeof(CultureInfo); 
      try 
      { 
       t.InvokeMember("s_userDefaultCulture", BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Static, null, ci, new object[] { ci }); 
       t.InvokeMember("s_userDefaultUICulture", BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Static, null, ci, new object[] { ci }); 
      } 
      catch { } 
      try 
      { 
       t.InvokeMember("m_userDefaultCulture", BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Static, null, ci, new object[] { ci }); 
       t.InvokeMember("m_userDefaultUICulture", BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Static, null, ci, new object[] { ci }); 
      } 
      catch { } 
     } 
     static void Main(string[] args) 
     { 
      //first thing: set CultureInfo to English: 
      SetEnglishCulture(); 
      try 
      { 
       //I'm not listening on the following port: 
       TcpClient s = new TcpClient("localhost", 2121); 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine("Socket exception: " + ex.Message); 
      } 
      try 
      { 
       //the following file doesn't exists: 
       File.ReadAllText("filenotexist.txt"); 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine("File exception: " + ex.Message); 
      } 
     } 
    } 
} 

अब जापानी मशीन पर यह अंग्रेजी में फ़ाइल अपवाद लेकिन Net.socket अपवाद जापानी में अभी भी लिखना अपवाद, कुछ अपवाद अब अंग्रेजी में दिखाए जाते हैं, bu उनमें से सभी नहीं, सॉकेट अपवाद लगातार हैं। जैसा कि आप देख सकते हैं, फ़ाइल अपवाद का अनुवाद अंग्रेजी में किया गया था, लेकिन सॉकेट अपवाद अभी भी जापानी में है।

मैंने इसे किसी भी .NET ढांचे (2.1 से 4.5 तक) में अभी भी परीक्षण किया है।

  • क्या सभी अपवादों के लिए कोई संपूर्ण समाधान है?
  • क्या मुझे कुछ याद आया?
  • क्या मुझे कुछ और करना चाहिए?
  • शायद अंग्रेजी आउटपुट प्राप्त करने के लिए विदेशी मशीन पर प्रोग्राम चलाने का कोई और तरीका है, और कुछ पर्यावरण चर सेट करें?

उत्तर

3

मैं एक समाधान तो मैं इसे यहाँ मामले में किसी को अपलोड करेंगे इसकी आवश्यकता होगी है: यहाँ क्या मैं कोड का एक सा में बात कर रहा हूँ है। यदि किसी के पास कोई बेहतर समाधान है तो मुझे यह जानकर खुशी होगी कि कृपया टिप्पणी करें।

Win32Exception के मामले में, हम FormatMessage का उपयोग कर सकते हैं और त्रुटि कोड को अंग्रेजी और डिफ़ॉल्ट भाषाओं दोनों में अनुवाद कर सकते हैं, और डिफ़ॉल्ट रूप से अंग्रेजी द्वारा प्रतिस्थापित कर सकते हैं। यदि मैं प्रतिस्थापित किए बिना अंग्रेजी लेता हूं, तो मैं पैरामीटर खो देता हूं। इसलिए अगर प्रतिस्थापित विफल हुआ तो मैं अंग्रेजी में अतिरिक्त विवरण के साथ अपवाद वापस कर दूंगा।

यहाँ मेरी पूर्ण समाधान है:

using System; 
using System.IO; 
using System.Text; 
using System.Threading; 
using System.Net.Sockets; 
using System.Globalization; 
using System.Reflection; 
using System.ComponentModel; 
using System.Runtime.InteropServices; 

namespace TestCulture 
{ 
    class Program 
    { 
     static void SetEnglishCulture() 
     { 
      CultureInfo ci = new CultureInfo("en-US"); 
      Thread.CurrentThread.CurrentCulture = ci; 
      Thread.CurrentThread.CurrentUICulture = ci; 
      Type type = typeof(CultureInfo); 
      try 
      { 
       type.InvokeMember("s_userDefaultCulture", BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Static, null, ci, new object[] { ci }); 
       type.InvokeMember("s_userDefaultUICulture", BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Static, null, ci, new object[] { ci }); 
      } catch { } 
      try 
      { 
       type.InvokeMember("m_userDefaultCulture", BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Static, null, ci, new object[] { ci }); 
       type.InvokeMember("m_userDefaultUICulture", BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Static, null, ci, new object[] { ci }); 
      } catch { } 
     } 
     [DllImport("kernel32.dll")] 
     static extern uint FormatMessage(uint dwFlags, IntPtr lpSource, uint dwMessageId, uint dwLanguageId, StringBuilder lpBuffer, uint nSize, IntPtr Arguments); 
     public static string Win32ExceptionInEnglish(Win32Exception ex) 
     { 
      const int nCapacity = 820; // max error length 
      const uint FORMAT_MSG_FROM_SYS = 0x01000; 
      const uint engLangID = (0x01<<10) | 0x09; 
      const uint defLangID = 0x0; 
      StringBuilder engSb = new StringBuilder(nCapacity); 
      StringBuilder defSb = new StringBuilder(nCapacity); 
      FormatMessage(FORMAT_MSG_FROM_SYS,IntPtr.Zero, (uint)ex.ErrorCode, defLangID, defSb, nCapacity, IntPtr.Zero); 
      FormatMessage(FORMAT_MSG_FROM_SYS,IntPtr.Zero, (uint)ex.ErrorCode, engLangID, engSb, nCapacity, IntPtr.Zero); 
      string sDefMsg = defSb.ToString().TrimEnd(' ','.','\r','\n'); 
      string sEngMsg = engSb.ToString().TrimEnd(' ','.','\r','\n'); 
      if(sDefMsg == sEngMsg) //message already in English (or no english on machine?) 
      { 
       //nothing left to do: 
       return ex.Message; 
      } 
      else 
      { 
       string msg = ex.Message.Replace(sDefMsg,sEngMsg); 
       if (msg == ex.Message) 
       { 
        //replace didn't worked, can be message with arguments in the middle. 
        //I such as case print both: original and translated. to not lose the arguments. 
        return ex.Message + " (In English: " + sEngMsg + ")"; 
       } 
       else 
       { 
        //successfuly replaced! 
        return msg; 
       } 
      }  
     } 

     public static void Main(string[] args) 
     {   
      SetEnglishCulture(); 
      try { 
       // generate any exception ... 
       const int notListenningPort = 2121; 
       new TcpClient("localhost", notListenningPort); 
      } 
      catch(Win32Exception ex)//first try to cach win32 Exceptions 
      { 
       Console.WriteLine("W32 Exception: " + Win32ExceptionInEnglish(ex)); 
      } 
      catch(Exception ex)//this fit to the rest .NET exceptions which affected by CultureInfo 
      { 
       Console.WriteLine("Exception: " +ex.Message); 
      } 
     } 
    } 
} 
+0

मुझे कोई भी अंग्रेजी पाठ नहीं मिला है, न तो वीएस -2008 (.NET 3.5) और न ही VS2015 (.net 4.5.2) में। डीएफएसबी में एक जर्मन पाठ है, EngSb में कुछ भी नहीं है। –

+0

defLangID भाषा पहचानकर्ता है, मैंने अपने नमूने में eng-us का उपयोग किया, लेकिन ऐसा लगता है कि आपकी मशीन इसका समर्थन नहीं करती है, लेकिन हो सकता है कि यह अन्य Eng का समर्थन करे। भाषा? शायद Eng-uk? आप अन्य लोकेल का उपयोग करने का प्रयास कर सकते हैं, यहां पूरी सूची देखें: https://msdn.microsoft.com/en-us/library/windows/desktop/dd318693(v=vs.85).aspxhttps://msdn.microsoft। com/en-us/पुस्तकालय/विंडोज़/डेस्कटॉप/dd318693 (v = vs.85) .aspx – SHR

1

एक SocketException एक Win32Exception है। Win32Exception से प्राप्त होने वाले सभी अन्य वर्गों की तरह, इसे Win32Exception.GetErrorMessage(int error) का उपयोग करके विंडोज से इसका संदेश मिलता है, जो कर्नेल 32. डीएलएल में FormatMessage का उपयोग करता है।

ऐसा करने में, संदेश प्रभावी ढंग से विंडोज से आता है, न कि .NET से। विंडोज़ विंडोज डिस्प्ले भाषा, और AFAIK में एक संदेश लौटाएगा, इसके बारे में आप अपने .NET प्रोग्राम के भीतर से कुछ भी नहीं कर सकते हैं।

+1

मैंने पाया (और अपलोड संपादन में) जारी करने के लिए एक समाधान है, आपकी टिप्पणी काफी मददगार था। एक बार फिर धन्यवाद। अगर मैं आपको फिर से वोट दूंगा! (मुझे बस एहसास हुआ कि मैं आपके अन्य उत्तर पर अप-वोट कर सकता हूं ...) – SHR

1

आपको उस लाइन को लपेटना पड़ सकता है जो एक अलग थ्रेड में कंसोल में त्रुटि को मुद्रित करता है जिसमें लोकेल अंग्रेजी पर सेट होता है क्योंकि फ्रेमवर्क अपवाद कोड वर्तमान थ्रेड लोकेल के आधार पर त्रुटि संसाधनों को अपने संसाधनों से लोड करता है।

static void Main(string[] args) { 

    try { 
     TcpClient c = new TcpClient("localhost", 1234); 
    } 
    catch (Exception ex) { 
     // thread that logs exception message to console 
     Thread logger = new Thread(new ParameterizedThreadStart(PrintException)); 
     logger.CurrentCulture = new System.Globalization.CultureInfo("en-US"); 
     logger.Start(ex); 
    } 


} 

private static void PrintException(object ex) { 
    Console.WriteLine("Error: " + ((Exception)ex).Message); 
} 
+0

क्या आपने यह कोशिश की है? संदेश ढांचे द्वारा लोड नहीं किया गया है, लेकिन विंडोज द्वारा। यह .NET संसाधनों से नहीं आया है। और संदेश निर्माण समय पर अपवाद में सेट है। मुझे संदेह है कि एन-यूएस संस्कृति सेट करने वाले थ्रेड पर संदेश प्रॉपर्टी को स्वचालित रूप से जापान में टेक्स्ट में जापानसे टेक्स्ट का अनुवाद किया जाएगा। –

+0

मैंने सभी धागे के लिए अपने कोड में 'CurrentCulture' को बदल दिया, इससे मदद नहीं मिली। अतिरिक्त थ्रेड केवल तभी मदद कर सकता है जब आप दोनों भाषाओं को रखना चाहते हैं। – SHR

संबंधित मुद्दे