C# 应用程序在 InitializeComponent() 启动时崩溃,抛出 CultureNotFoundException

C# Application crashes on startup at InitializeComponent(), throws CultureNotFoundException

我的 Windows Forms 应用程序在 Windows 10(最新版本)上安装和运行没有问题。但是,当安装在 Windows 2012R2 x64 终端服务器上时,程序会在启动时崩溃。

事件日志(请参阅下文)似乎指向在 MainForm 的构造函数中调用的 InitializeComponent() 方法中的 System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); 行。在那里,它抛出一个 CultureNotFoundException.

服务器完全是最新的,并且安装了正确版本的 .NET (v4.7.2)。 (重要的一点是我自己没有任何访问服务器的权限,所以我无法直接在服务器上调试软件。)

我已经尝试安装不同版本的应用程序,该应用程序会在调用 InitializeComponent() 之前尝试检索 CultureInfo.CurrentCulture.NumberFormat。该程序的那个版本能够毫无问题地从 CurrentCulture 获取 NumberFormat,但随后该程序仍然在 InitializeComponent() 上崩溃。由此我了解到问题似乎不是由本地文化设置引起的。

深入研究 Microsoft 的 reference code 使我找到了 ManifestBasedResourceGroveler class 中的 GetNeutralResourcesLanguage(),其中包含一个 try 语句,该语句在尝试 ArgumentException 时专门捕获 CultureInfo c = CultureInfo.GetCultureInfo(cultureName);。我可能是错的,但我相信这是引发异常的地方。在 catch 语句中指出:

// we should catch ArgumentException only.
// Note we could go into infinite loops if mscorlib's 
// NeutralResourcesLanguageAttribute is mangled.  If this assert
// fires, please fix the build process for the BCL directory.

关于如何解决这个问题的任何想法?非常感谢。

事件日志:

- <System>
  <Provider Name=".NET Runtime" /> 
  <EventID Qualifiers="0">1026</EventID> 
  <Level>2</Level> 
  <Task>0</Task> 
  <Keywords>0x80000000000000</Keywords> 
  <TimeCreated SystemTime="2020-07-10T08:45:15.000000000Z" /> 
  <EventRecordID>1402928</EventRecordID> 
  <Channel>Application</Channel> 
  <Computer>XXXXXXXXX</Computer> 
  <Security /> 
  </System>
- <EventData>
  <Data>Application: MyApplication.exe Framework Version: v4.0.30319 
Description: The process was terminated due to an unhandled exception.
Exception Info:
  System.Globalization.CultureNotFoundException
  at System.Globalization.CultureInfo.GetCultureInfo(System.String)
  at System.Resources.ManifestBasedResourceGroveler.GetNeutralResourcesLanguage(System.Reflection.Assembly, System.Resources.UltimateResourceFallbackLocation ByRef)
Exception Info:
  System.ArgumentException
  at System.Resources.ManifestBasedResourceGroveler.GetNeutralResourcesLanguage(System.Reflection.Assembly, System.Resources.UltimateResourceFallbackLocation ByRef)
  at System.Resources.ResourceManager.CommonAssemblyInit() at System.Resources.ResourceManager..ctor(System.Type)
  at System.ComponentModel.ComponentResourceManager..ctor(System.Type)
  at MyNameSpace.MainForm.InitializeComponent() at MyNameSpace.MainForm..ctor(System.String[]) 
  at MyNameSpace.Program.Main(System.String[])</Data> 
  </EventData>
  </Event>```

我找到了问题的根源,并找到了解决办法。 在 MainForm 的构造函数中调用的 InitializeComponent() 方法中的行 System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); 抛出了以下 ArgumentException:

The NeutralResourcesLanguageAttribute on the assembly "MyApplication, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" specifies an invalid culture name: "en-BW".
Inner exception: System.Globalization.CultureNotFoundException: Culture is not supported.
Parameter name: name
en-BW is an invalid culture identifier.
   at System.Globalization.CultureInfo.GetCultureInfo(String name)
   at System.Resources.ManifestBasedResourceGroveler.GetNeutralResourcesLanguage(Assembly a, UltimateResourceFallbackLocation& fallbackLocation)

原来 NeutralResourceLanguageAttribute 被设置为 "en-BW",原因不明。此区域性仅在 Windows 10 和 Windows Server 2016(及更高版本)中可用,请参阅 MSDN。 打开应用程序的项目属性后,通过单击“程序集信息”按钮可以更改此语言。将字段“中性语言”更改为“none”为我解决了这个问题。