Search code examples
c#.netcultureargumentexceptioninitializecomponent

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


My Windows Forms Application installs and works without problems on Windows 10 (latest version). However, when installed on Windows 2012R2 x64 Terminal server, the program crashes on startup.

The event log (please see below) seems to direct to the line System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); within the InitializeComponent() method that is called in the MainForm's constructor. There, it throws a CultureNotFoundException.

The Server is fully up-to-date, and the correct version of .NET (v4.7.2) is installed. (An important note is that I do not have any access to the Server myself, so I am unable to debug the software directly on the Server.)

I have tried installing a different version of the application that attempts to retreive CultureInfo.CurrentCulture.NumberFormat before calling InitializeComponent(). That version of the program is able to get the NumberFormat from the CurrentCulture without problems, but subsequently the program still crashes on InitializeComponent(). From this I understand that the problem seems not to be caused by the local Culture settings.

Digging into Microsoft's reference code led me to GetNeutralResourcesLanguage() within the ManifestBasedResourceGroveler class which contains a try-statement that specifically catches ArgumentException when trying CultureInfo c = CultureInfo.GetCultureInfo(cultureName);. I could be wrong but I believe this is where the exception is raised. At the catch-statement it is noted:

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

Any ideas on how this could be solved? Many thanks in advance.

Event log:

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

Solution

  • I have found the source of the problem, and a solution. The line System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); within the InitializeComponent() method that is called in the MainForm's constructor threw the following 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)
    

    It turns out the NeutralResourceLanguageAttribute was - for unknown reasons - set to "en-BW". This culture is only available in Windows 10 and Windows Server 2016 (and later versions), see MSDN. This language be changed by clicking the "Assembly Information" button after opening the application's Project Properties. Changing the field "Neutral Language" to "none" fixed the issue for me.