英文异常消息?

Car*_*rra 287 .net c# localization exception

我们通过将Exception.Message写入文件来记录系统中发生的任何异常.但是,它们是在客户的文化中写成的.而土耳其的错误对我来说意义不大.

那么如何在不改变用户文化的情况下用英语记录任何错误消息呢?

mdb*_*mdb 66

这个问题可以部分解决.Framework异常代码根据当前线程区域设置从其资源加载错误消息.在某些例外情况下,这会在访问Message属性时发生.

对于这些例外情况,您可以通过在记录时将线程区域设置简单地切换到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();
}
Run Code Online (Sandbox Code Playgroud)

ExceptionLogger类看起来像:

class ExceptionLogger
{
  Exception _ex;

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

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

但是,正如Joe在对此回复的早期修订版的评论中正确指出的那样,在抛出异常时已经(部分)从语言资源加载了一些消息.

例如,这适用于抛出ArgumentNullException("foo")异常时生成的消息的'parameter not not null'部分.在这些情况下,即使使用上述代码,消息仍将显示(部分)本地化.

除了使用不切实际的黑客之外,例如在开始使用en-US语言环境的线程上运行所有非UI代码,似乎没有太多可以做的事情:.NET Framework异常代码没有用于覆盖错误消息区域设置的工具.

  • 您的示例适用于FileNotFoundException,因为在访问Message属性时会检索消息资源,而不是在抛出异常时检索.但是对于所有异常都不是这样(例如,尝试抛出新的ArgumentNullException("paramName")) (9认同)
  • @VitalyB本地化的异常文本是.NET框架语言包的一部分.因此,如果您没有安装法语语言包,则无法获得翻译文本. (7认同)
  • 至少在.NET 4.5中,所有异常都使用`Environment.GetResourceString("...")实例化,因此您的解决方案不再起作用.最好的方法是使用您自己的(英语)消息文本抛出自定义异常,并使用InnerException属性保留旧的异常. (7认同)
  • 我很迷惑.我已经尝试过你的答案并测试它我希望我的法语异常,所以我做了't.CurrentUICulture = new System.Globalization.CultureInfo("fr-FR");`和`t.CurrentCulture = new System. Globalization.CultureInfo("fr-FR");`然而,由此产生的异常是英文的...... (3认同)

小智 65

您可以在unlocalize.com上搜索原始异常消息

  • 这不是解决这个问题的实用方法 (15认同)
  • 尝试搜索一些中文异常消息,总是告诉我"没有找到记录". (4认同)

MPe*_*ier 40

也许是一个有争议的观点,但en-US您可以将其设置为,而不是将文化设置为Invariant.在Invariant文化中,错误消息是英文的.

Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture;
Run Code Online (Sandbox Code Playgroud)

它具有不偏见的优点,特别是对于非美国英语区域.(又避免同事的讽刺言论)

  • 这不会使标准的消息框按钮是英文的吗?这可能不是理想的行为. (4认同)
  • 如果您的应用程序完全未本地化,那当然可以。否则,除了在愤世嫉俗的同事的雷达下飞行时削弱所有定位之外,我看不到这种方法的用途。 (3认同)
  • 我将建议在顶部的Application_Start中。这将使整个项目以英语运行。如果仅是您想要的错误消息,则可以制作一个Cover函数并在每个`catch`中调用它。 (2认同)

小智 10

Windows需要安装要使用的UI语言.它没有,它无法神奇地知道翻译的消息是什么.

在en-US windows 7 ultimate中,安装了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;
Run Code Online (Sandbox Code Playgroud)

在pt-PT,en-US和en-US中生成消息.由于没有安装法语文化文件,因此默认使用Windows默认(已安装?)语言.


Sim*_*ier 10

这里的解决方案不需要任何编码,甚至可以用于过早加载的异常文本,以便我们能够通过代码进行更改(例如,mscorlib中的那些).

它可能并不总是适用于所有情况(这取决于您的设置,因为您需要能够在主.exe文件旁边创建.config文件)但这对我有用.因此,只需创建一个包含以下行的app.configdev,(或一个[myapp].exe.configweb.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>
Run Code Online (Sandbox Code Playgroud)

这样做是告诉框架重定向程序集绑定mscorlib的资源和System.Xml资源,对于1到999之间的版本,法语(culture设置为" fr")到一个不存在的程序集(任意一个)版本999).

因此,当CLR为这两个程序集(mscorlib和System.xml)查找法语资源时,它将无法找到它们并优雅地回退到英语.根据您的上下文和测试,您可能希望将其他程序集添加到这些重定向(包含本地化资源的程序集).

当然我不认为这是微软支持的,所以使用风险自负.好吧,如果您发现问题,您可以删除此配置并检查它是否无关.

  • 要创建完整列表,请查看该文件夹。它大约有 120 个资源文件。将它们中的每一个添加到配置中。这似乎是目前适用于 Windows 10 及更高版本的唯一解决方案,因为无法再在较新的 Windows 中卸载 .Net 语言包(它是操作系统的一部分)。它现在甚至放在 GAC 中,因此删除这些语言文件夹似乎不起作用。 (2认同)

小智 5

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;
Run Code Online (Sandbox Code Playgroud)

没有解决方法。

谢谢:)


小智 5

我知道这是一个古老的话题,但我认为我的解决方案可能与在网络搜索中偶然发现它的任何人都非常相关:

在异常记录器中,您可以记录 ex.GetType.ToString,这将保存异常类的名称。我希望类的名称应该独立于语言,因此总是用英语表示(例如“System.FileNotFoundException”),尽管目前我无法访问外语系统来测试主意。

如果你真的想要错误消息文本,你可以用你喜欢的任何语言创建一个所有可能的异常类名称及其等效消息的字典,但对于英语,我认为类名称是完全足够的。

  • 不起作用。我收到了一个由 System.Xml.XmlWellFormedWriter 抛出的 InvalidOperationException 异常。您尝试在不阅读消息的情况下猜测发生了什么特定错误。可能是一千种不同的东西。 (7认同)

归档时间:

查看次数:

80998 次

最近记录:

6 年 前