Reputation: 12212
Say that you have in your C# application called App a directory called Res
, and inside that directory you have icon.png, that presumably you will mark as EmbeddedResource and access it at runtime in order to provide an icon to your application, with code such as:
var assembly = System.Reflection.Assembly.GetEntryAssembly();
var resourceAppIcon = assembly.
GetManifestResourceStream( "App.Res.icon.png" );
// Prepare icons
if ( resourceAppIcon != null ) {
this.appIconBmp = new Bitmap( resourceAppIcon );
this.Icon = Icon.FromHandle( this.appIconBmp.GetHicon());
}
... and so on.
This code was working previously, but suddenly it stopped working since I changed to JetBrains Rider. Though the resources were still embedded, their names had changed from namespace.directory.resource_name
to namespace.resource_name
. In order to access the icon, I have to write now:
var resourceAppIcon = assembly.
GetManifestResourceStream( "App.icon.png" );
Is this something expected? Is it just something related to Rider? Maybe something related to the new times that come with dotnetcore? I've struggled to find documentation about this, but haven't had any luck.
EDITED: I've tried with dotnetcore using the CLI and then the resources names are as expected. It seems this is an issue with Mono?
Upvotes: 1
Views: 3183
Reputation: 5781
In my opinion, the resource names are far too brittle to use them directly - if someone changes the default namespace, all resource names will change and there is no tool to refactor the resource names automatically. Thus, I always resolve embedded resources by iterating over the available resource names and find the correct one by an EndsWith
-filter.
var assembly = System.Reflection.Assembly.GetEntryAssembly();
var resourceName = assembly.GetResourceNames().Single(n => n.EndsWith("icon.png"));
var resourceAppIcon = assembly.
GetManifestResourceStream(resourceName);
Upvotes: 4
Reputation: 8243
The path to the embedded resource can vary based on the properties used to embed the resource. For example, if you specify the ManifestResourceName
or the LogicalName
property, the path will differ from the default.
Additionally, if the EmbeddededResource
uses a DependentUpon
property and it is pointing to a C# class, then the name of the resource will attempt to match the namespace of the class being referenced, instead of the folder that the resource is located in.
Of course, the rules change if EmbeddedResourceUseDependentUponConvention
is also specified in the project, in which case DependentUpon
does not have the effected noted above.
Upvotes: 0
Reputation: 364
I was just trying to replay your problem but in both with dotnetcore (Visual Sutdio and JetBrains Rider) I can access the same way with your "App.Res.icon.png" code to the embedded image resource but not with "App.icon.png".
Alternatly I think you can try something like:
var assembly = System.Reflection.Assembly.GetExecutingAssembly(); // Instead of GetEntryAssembly()
var resourceAppIcon = assembly.GetManifestResourceStream("App.Res.icon.png");
Hope that help you.
Upvotes: 1
Reputation: 21140
Not sure what is changing this, but if you are using a resx file with strings, files, etc. then you should be able to have the designer generate a code file for you with simple properties that do the right thing, then you don't have to hard-code resource names in your code, you can just access the properties on the generated Resources
class.
If that's not an option, then my suggestion is to add some unit and/or integration tests with the names you expect and make sure they pull out the correct data.
Upvotes: 1