project-system icon indicating copy to clipboard operation
project-system copied to clipboard

Retrieving file from new resource file format throws System.MissingMethodException: 'Constructor on type 'System.Byte[]' not found.'

Open TimSirmovics opened this issue 1 year ago • 15 comments

Description

When adding a resource file after upgrading Visual Studio to 17.11.0 and adding a file resource, the new Resource Explorer is used. Then when trying to retrieve the resource using the ResourceFileName.ObjectName syntax, a MissingMethodException is thrown Constructor on type 'System.Byte[]' not found.

Reproduction Steps

  1. Create a .net8 console project
  2. Add a Resources (.resx) file
  3. Double click on the .resx file to open the new Resource Explorer
  4. Click the + button to create a resource
  5. Change the type to "File"
  6. Click "Add existing file..." and select a file
  7. Close the Resource Explorer.
  8. The project will now fail to build with an error MSB3822 Non-string resources require the System.Resources.Extensions assembly at runtime, but it was not found in this project's references. Add the NuGet package "System.Resources.Extensions" Version="8.0.0" to resolve the error.
  9. Reference the resource file in code i.e. var fileBytes = ResourceFileName.ObjectName
  10. Run the program, an exception will be thrown: System.MissingMethodException: 'Constructor on type 'System.Byte[]' not found.'

Expected behavior

When accessing the resource file it should be returned as a byte[].

Actual behavior

An exception is thrown: System.MissingMethodException: 'Constructor on type 'System.Byte[]' not found.'

Regression?

This worked before the latest resource file / explorer changes

Known Workarounds

No response

Configuration

No response

Other information

No response

TimSirmovics avatar Aug 19 '24 23:08 TimSirmovics

Tagging subscribers to this area: @dotnet/area-system-resources See info in area-owners.md if you want to be subscribed.

Callstack:

Unhandled exception. System.MissingMethodException: Constructor on type 'System.Byte[]' not found.
   at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture)
   at System.Activator.CreateInstance(Type type, Object[] args)
   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.LoadObject(Int32 pos, ResourceTypeCode& typeCode)
   at System.Resources.Extensions.RuntimeResourceSet.ReadValue(DeserializingResourceReader reader, Int32 dataPos, Boolean isString, ResourceLocator& locator)
   at System.Resources.Extensions.RuntimeResourceSet.GetObject(String key, Boolean ignoreCase, Boolean isString)
   at System.Resources.Extensions.RuntimeResourceSet.GetObject(String key, Boolean ignoreCase)
   at System.Resources.ResourceManager.GetObject(String name, CultureInfo culture, Boolean wrapUnmanagedMemStream)
   at conRes.Resources.get_ProgramSource() in C:\scratch\conRes\Resources.Designer.cs:line 68
   at Program.<Main>$(String[] args) in C:\scratch\conRes\Program.cs:line 4

So it's being treated as a Activator type resource.

Here's the relevant code in MSBuild: https://github.com/dotnet/msbuild/blob/1a51dd82a24e26b6aac68e29414182fa56fbb573/src/Tasks/ResourceHandling/MSBuildResXReader.cs#L222-L280

MSbuild is registering as activator resource: https://github.com/dotnet/msbuild/blob/1a51dd82a24e26b6aac68e29414182fa56fbb573/src/Tasks/ResourceHandling/MSBuildResXReader.cs#L279C31-L279C49 https://github.com/dotnet/msbuild/blob/1a51dd82a24e26b6aac68e29414182fa56fbb573/src/Tasks/ResourceHandling/FileStreamResource.cs#L47

That's wrong, it should be treating as byte[], but MSBuild is only treating this as a byte array if it has both System.Byte[] and mscorlib https://github.com/dotnet/msbuild/blob/1a51dd82a24e26b6aac68e29414182fa56fbb573/src/Tasks/ResourceHandling/MSBuildResXReader.cs#L293

Here's what I see in the latest resx:

  <data name="ProgramSource" type="System.Resources.ResXFileRef, System.Windows.Forms">
    <value>Program.cs;System.Byte[]</value>
  </data>

Repro: conRes.zip

So I can workaround this by adding ,mscorlib to the resx.

  <data name="ProgramSource" type="System.Resources.ResXFileRef, System.Windows.Forms">
-    <value>Program.cs;System.Byte[]</value>
+    <value>Program.cs;System.Byte[],mscorlib</value>
  </data>

Maybe MSBuild could broaden that check to consider this specific case of no core assembly name. @rainersigwald

Did the designer change here? @drewnoakes Here are some previous values written -- all seem to include the assembly name: https://github.com/search?q=org%3Adotnet+ResxFileRef+%2F%3BSystem.Byte%5C%5B%5C%5D%2F+path%3A*.resx&type=code

ericstj avatar Aug 20 '24 00:08 ericstj

Hi, thank you for using the new Resource Explorer and for reporting this issue.

The problem is related to creating a resource of type File, where the assembly information isn't being saved in the resource file.

The good news is that the latest Visual Studio version includes a fix for this issue! You can download it from https://visualstudio.microsoft.com/vs/preview/. Let us know if you encounter other issues or have feedback on the new experience.

melytc avatar Aug 20 '24 05:08 melytc

When can we expect this fix to be in a release?

cmierowsky avatar Aug 21 '24 05:08 cmierowsky

When can we expect this fix to be in a release?

Would like to know this as well. Having the same issue.

maot01 avatar Aug 22 '24 10:08 maot01

@cmierowsky, @maot01, the fix is available in Visual Studio 17.11.1.

melytc avatar Aug 22 '24 17:08 melytc

@cmierowsky, @maot01, the fix is available in Visual Studio 17.11.1.

Im still getting : Constructor on type 'System.Byte[]' not found. when trying to access a File saved in Resource

Like such :

var test = Resource.MyFile;

image

maot01 avatar Aug 24 '24 15:08 maot01

I wonder if I am missing something in here.

I followed the repro steps and I was able to run the program with no exception: image

I notice that for me, the file is being saved as a System.String. If I open the Managed Resource Editor, the legacy experience (Open With > Managed Resource Editor(legacy)), it is also saved as a System.String.

If you try to change the resource type in the XML editor (Open With > XML (Text) Editor) from Byte[] to System.String, does exception still occur?

melytc avatar Aug 26 '24 18:08 melytc

I wonder if I am missing something in here.

I followed the repro steps and I was able to run the program with no exception: image

I notice that for me, the file is being saved as a System.String. If I open the Managed Resource Editor, the legacy experience (Open With > Managed Resource Editor(legacy)), it is also saved as a System.String.

If you try to change the resource type in the XML editor (Open With > XML (Text) Editor) from Byte[] to System.String, does exception still occur?

This does not work. I have attached an .exe file and that gets stored as byte[]. When trying to force this type to a string it results in "Resource was of type 'System.String' instead of String - call GetObject instead."

I guess in your case its saved as string since its a .cs file you have attached. In my case I need to be able to embed a .exe and be able to retrieve it at a later point.

Tried this change: image Original value: image

maot01 avatar Aug 27 '24 10:08 maot01

Thanks for the clarification, @maot01. I can see the error now; I'll investigate this further and keep this thread updated.

melytc avatar Aug 27 '24 17:08 melytc

A fix for this issue has been internally implemented and is being prepared for release, where we treat text files as System.String and other files, like .cs and .exe, as System.Byte[]. Thanks again for bringing this up! We’ll update you once it becomes available for download.

melytc avatar Aug 28 '24 22:08 melytc

Has the fix to this issue been released yet? Now it seems with the current version of VS community (17.11.5) I cannot even attach .exe files in the new resource manager. Funny thing, it works perfectly to import them using the legacy solution (and then I can actually read the file). This seems a bit embarrassing at this point... 😅

maot01 avatar Oct 14 '24 18:10 maot01

I also have the same problem with adding fonts. There are also other problems especially with adding images. I have to correct the content of the resource files .resx and .Designer.vb to have a correct operation.

Will we soon have a new version of visual studio (17.11.6) with the essential fixes of the resource explorer?

Perpete avatar Nov 02 '24 16:11 Perpete

Still having this problem in 17.12.1 with adding image files to a new resx file. Adding ,mscorlib fixes this as @ericstj suggested

colinb2048 avatar Nov 22 '24 08:11 colinb2048

Any updates on this?

TimSirmovics avatar May 26 '25 22:05 TimSirmovics