Can't load a manifest resource with GetManifestResourceStream()
Asked Answered
H

8

57

I've created a custom configuration section using XSD. In order to parse the config file that follows this new schema, I load the resource (my .xsd file) with this:

public partial class MonitoringConfiguration
    {
        public const string ConfigXsd = "MonitoringAPI.Configuration.MonitoringConfiguration.xsd";
        public const string ConfigSchema = "urn:MonitoringConfiguration-1.0";

        private static XmlSchemaSet xmlSchemaSet;

        static MonitoringConfiguration()
        {
            xmlSchemaSet = new XmlSchemaSet();
            Stream xsdStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(ConfigXsd);
            XmlReader schemaReader = XmlReader.Create(xsdStream);
            xmlSchemaSet.Add(ConfigSchema, schemaReader);
        }

    }

By the way my resource is: MonitoringConfiguration.xsd. And the namespace of the other partial class (that represents the code behind of the .xsd file) is MonitoringAPI.Configuration.

The problem is situated here:

 Stream xsdStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(ConfigXsd);

The xsdStream is null, so I guess the resource can't be found! But why?

Thank you

Hypodermic answered 18/6, 2010 at 10:11 Comment(0)
C
113

The name of the resource is always:

<Base namespace>.<RelativePathInProject>.<FileName>

So if your resource is located in "Resources/Xsd/", and your default project namespace is "MonitoringAPI.Configuration", the resource name is:

"MonitoringAPI.Configuration.Resources.Xsd.MonitoringConfiguration.xsd"

Also make sure the build action for your resource is set to "Embedded Resource"

Chippy answered 18/6, 2010 at 10:14 Comment(7)
My resource is situated in the same directory than this class.Hypodermic
Right-click the file and choose "Properties".Chippy
Thanks that was the problem! I spent half a day figuring out the problem and you solved it in a minute ;)Hypodermic
Note the resource name string is case sensitiveHuxley
You say this, but for me it's just <Base namespace>.<FileName>. Do you know why?Pori
@LightnessRacesinOrbit Are the resources in the root of the project?Skyla
@LightnessRacesinOrbit for me it is also like this because the class I am using to reference the file lives exactly where the resource lives.Victorvictoria
T
66

Easy and correct way to get the actual name of your embedded resource:

string[] resourceNames =
    Assembly.GetExecutingAssembly().GetManifestResourceNames();

Then simply check resourceNames array, and you will know for sure what to pass to GetManifestResourceStream method.

Toreador answered 8/1, 2013 at 15:58 Comment(4)
To user1958681 ... YES!!! In my case, resource paths were "non standard", in the sense they didn't have the resources sub-dir in their names. The array trick was perfect to know the right naming. Many thanks!!Longterm
Mine didn't have the subdir in their names either. Does anyone know why?Pori
I found just running Assembly.GetExecutingAssembly().GetManifestResourceNames(); in the Intermediate Window while debugging was enough. Gives a nice formatted output that's easy to read.Skyla
@LightnessRacesinOrbit - "didn't have the subdir in their names either" - depends on your target environment (WPF, UWP, Xamarin, Standard, Net6). IIRC, some have a "standard place" to put resources (e.g. "Resources/"), and omit that from the name.Cannot
M
17

In my case,

When you try to access the file via GetManifestResourceStream(). You will get an error due to invalid path of the file, and stream will be null.

Solution:

Right click on the file which you have added in to solution and Click on Properties.

Select the Build Action as Embedded Resource. (Instead of Content - by default)

Build action property set to embedded resource

Mauer answered 19/8, 2015 at 13:3 Comment(0)
P
9

By default, visual studio does not embed xsd file therefore you must ensure "Build Action" property of xsd file is set to "Embedded Resource" to make it works

Phonology answered 20/10, 2010 at 7:26 Comment(0)
W
5

just add your resources under form1.resx -->add existing items

double click on the resources you added under Resources folder.go to properties and select "Embedded Resources" instead of none.

Then try debugging the line:

string[] resourceNames=Assembly.GetExecutingAssembly().GetManifestResourceNames();

check the resources you added are in the array. then copy the resource name exactly from this array and try putting the name on your code..it works fine!!

Willena answered 4/11, 2015 at 7:21 Comment(0)
C
2

You can get the Resource Stream by passing the Resource Names which is as follows below...

  1. Get the resource name e.g..

    Assembly objAssembly = Assembly.GetExecutingAssembly();

    string[] strResourceNames = objAssembly.GetManifestResourceNames();

  2. Pass the Resource Names to ...

    Stream strm = objAssembly.GetManifestResourceStream(strResourceNames);

Now you have Stream you can do whatever you want...

Calpe answered 19/10, 2016 at 12:47 Comment(0)
E
1

In my case, it was something completely different:

My UWP App compiled correctly in Debug and Release configuration but GetManifestResourceStream returned Null only Release configuration.

The issue was, that in the UWP Build Configuration file (and only there) the setting "Compile with .NET Native tool chain" was enabled. After disabling, GetManifestResourceStream worked as expected.

Epa answered 12/6, 2017 at 10:8 Comment(1)
Strange that somebody down voted my answer as it turns out that there is indeed a difference for GetManifestResourceStream whether it's from .NET native or not. When somebody is looking for "Can't load a manifest resource with GetManifestResourceStream()" this could have been indeed one of the reasons.Epa
F
1

I had an issue where I was embedding a whole heap of .xsd files in many different assemblies; everything was working (GetManifestResourceNames was returning the files I'd expect to see) except for one. The one which wasn't was called:

Something.LA.xsd

I wasn't dealing with specific cultures and the .LA bit at the end of the filename was being picked up by the compiler as this file being for the LA culture - the filename in the manifest was going in as Something.xsd (under culture LA) - hence me not being able to find it (it ended up in a satellite assembly). I dodged the issue by renaming the file - presumably it is possible to explicitly state the culture of a given embedded resource.

Actually, a quick google reveals: How can I prevent embedded resource file culture being set based on its filename

According to this answer, you've got to do hacky things - so perhaps renaming the file wasn't so bad after all :)

Feces answered 1/2, 2018 at 12:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.