dotnet / msbuild

The Microsoft Build Engine (MSBuild) is the build platform for .NET and Visual Studio.
https://docs.microsoft.com/visualstudio/msbuild/msbuild
MIT License
5.23k stars 1.35k forks source link

ResXNullRef resource serialization is broken #4634

Closed rainersigwald closed 5 years ago

rainersigwald commented 5 years ago

From @filipnavara on Monday, August 19, 2019 6:06:17 PM

Problem description:

.resx files using System.Resources.ResXNullRef or System.Resources.ResXFileRef cannot be loaded.

Actual behavior:

System.NotSupportedException
  HResult=0x80131515
  Message=TypeConverter cannot convert from System.String.
  Source=System.ComponentModel.TypeConverter
  StackTrace:
   at System.ComponentModel.TypeConverter.GetConvertFromException(Object value)
   at System.ComponentModel.TypeConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
   at System.ComponentModel.TypeConverter.ConvertFromInvariantString(String text)
   at System.Resources.Extensions.DeserializingResourceReader.DeserializeObject(Int32 typeIndex)
   at System.Resources.Extensions.DeserializingResourceReader._LoadObjectV2(Int32 pos, ResourceTypeCode& typeCode)
   at System.Resources.Extensions.DeserializingResourceReader.LoadObjectV2(Int32 pos, ResourceTypeCode& typeCode)
   at System.Resources.Extensions.DeserializingResourceReader.ResourceEnumerator.get_Entry()
   at System.Resources.Extensions.DeserializingResourceReader.ResourceEnumerator.get_Current()
   at System.ComponentModel.ComponentResourceManager.FillResources(CultureInfo culture, ResourceSet& resourceSet)
   at System.ComponentModel.ComponentResourceManager.FillResources(CultureInfo culture, ResourceSet& resourceSet)
   at System.ComponentModel.ComponentResourceManager.FillResources(CultureInfo culture, ResourceSet& resourceSet)
   at System.ComponentModel.ComponentResourceManager.ApplyResources(Object value, String objectName, CultureInfo culture)
   at System.ComponentModel.ComponentResourceManager.ApplyResources(Object value, String objectName)
   at WindowsFormsApp1.Form1.InitializeComponent() in C:\Users\Filip Navara\Source\Repos\WindowsFormsApp1\WindowsFormsApp1\Form1.Designer.cs:line 36
   at WindowsFormsApp1.Form1..ctor() in C:\Users\Filip Navara\Source\Repos\WindowsFormsApp1\WindowsFormsApp1\Form1.cs:line 17
   at WindowsFormsApp1.Program.Main() in C:\Users\Filip Navara\Source\Repos\WindowsFormsApp1\WindowsFormsApp1\Program.cs:line 19

Expected behavior:

No crash.

Minimal repro:

WindowsFormsApp1.zip

Details:

This is new behavior with .NET Core Preview 8 and VS 2019 Preview 16.3.0 Preview 2. With earlier VS previews the resources were compiled using NetFX msbuild. Now a new flow in msbuild is used that avoids the deserialization and serialization of binary resources. The new resource compilation process in msbuild and CoreFX seems to be broken for ResXNullRef and ResXFileRef at least. It is not immediately obvious whether it is bug in WinForms, CoreFX or msbuild but it certainly is broken now. /cc @rainersigwald

Copied from original issue: dotnet/winforms#1662

rainersigwald commented 5 years ago

From @rainersigwald on Monday, August 19, 2019 6:15:29 PM

ResXNullRef probably needs special handling in MSBuild. I'll duplicate this bug over there and look into that.

Can you share a repro for your problems with ResXFileRef? I have a fix almost ready for byte arrays and memory streams, but I'm not sure that's your case: microsoft/msbuild#4607.

filipnavara commented 5 years ago

I'll try to make a repro for ResXFileRef. Meanwhile, this is what we use in the .resx file:

  <data name="icondef" type="System.Resources.ResXFileRef, System.Windows.Forms">
    <value>icondef.xml;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;windows-1250</value>
  </data>

and this is how it is accessed from code:

ResourceManager resources = new ResourceManager(typeof(Resources.IM.Emoticons));
XmlTextReader xmlreader = new XmlTextReader(new StringReader(resources.GetString("icondef")));

or alternatively the pregenerated .Designer.cs code:

        internal static string icondef {
            get {
                return ResourceManager.GetString("icondef", resourceCulture);
            }
        }
rainersigwald commented 5 years ago

can you quickly try changing the String type to Version=4.0.0.0? I have a guess about the problem and its fix (which would be in MSBuild but you could work around with that change).

filipnavara commented 5 years ago

Ha, surprisingly you came up with the same workaround as my colleague. Changing to Version=4.0.0.0 seemed to help.

rainersigwald commented 5 years ago

Great! That's now microsoft/msbuild#4636.