Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assembly.GetManifestResourceStream not working with Xamarin on iOS

The following code works fine in Windows, however, when using Xamarin and targeting iOS, GetManifestResourceStream() returns null.

Assembly assembly = Assembly.GetExecutingAssembly();
Stream stream = assembly.GetManifestResourceStream("CommunicationModel.XmlSchemas.DeviceCommon.xsd");

I have set the file 'DeviceCommon.xsd' as an Embedded Resource. Not sure why it is not returning a valid stream.

Does anybody know why this is not working in iOS using Xamarin?

UPDATE:

Ok, so I followed the advice in the comments and set the file to Content.

I can now detect the file, but cannot open it:

if (File.Exists("DeviceCommon.xsd"))
{
  try
  {
    myStream = new FileStream("DeviceCommon.xsd", FileMode.Open);
  }
....
}

When I run the above code, the 'File.Exists()' call works, but when I attempt to open it, I get the following exception:

Access to the path "/private/var/mobile/Applications/8BD48D1F-F8E8-4A80-A446-F807C6728805/UpnpUI_iOS.app/DeviceCommon.xsd" is denied.

Anybody have some ideas how I can fix this???

Thanks, Curtis

like image 672
Curtis Avatar asked Feb 15 '23 15:02

Curtis


2 Answers

Ok, I finally got it to work. In my case, I was using the same files for a windows .dll and for a Xamarin.iOS.dll. I had named the .dll projects differently, though the namespaces were the same. Unfortunately, the microsoft documentation says that they use the namespace as part of the filename. That is no true.. They use the .dll name as part of the namespace. Just a slight difference, but makes all the difference.

So, to the point.. I set the file properties to: 'Embedded Resource' and 'Do not copy'. The resources I needed to process were all files with an .xsd extension, so I just looped through all resource names and used those that ended in .xsd. This way, no matter what operating system they were on, the name would be right because I retrieved it programmatically and didn't hard code it:

        Assembly assembly = Assembly.GetExecutingAssembly();
        string[] resources = assembly.GetManifestResourceNames();
        foreach (string resource in resources)
        {
            if(resource.EndsWith(".xsd"))
            {
                Stream stream = assembly.GetManifestResourceStream(resource);
                if (stream != null)
                {
                    XmlSchema schema = XmlSchema.Read(stream, null);
                    _schemas.Add(schema);
                }
            }
        }
like image 172
Curtis Avatar answered Apr 19 '23 22:04

Curtis


As for me what I had to do is prefix it properly. Instead of looking for "fooBar.baz", look for "The.Name.Of.The.Assembly.The.Folder.Inside.fooBar.baz".

like image 28
knocte Avatar answered Apr 19 '23 20:04

knocte