C# load external dll with embedded images - c#

I've a tiny application with several icons. I decided to put them in a separated DLL, so within my solution, I created a project and I've embedded those icons as resources.
Then I compiled this library (myImages.dll)
After, I added that dll as reference in the main program and I used the ResourceManager to get the reference of my custom library. Then I pointed to use GetObject method to retrieve the name of each file.
The following code works, but an error occurs when I try to retrieve an icon:
ResourceManager rm = new ResourceManager("myAssembly.MyNamespace", Assembly.LoadFile("Images.dll"));
Image myImage = ((System.Drawing.Image)(rm.GetObject("myIcon")));
Seems that the reference to my Images.dll doesn't work properly.
Any hints?

Usually when you get resources by name, you need to provide a fully qualified name. If you call GetManifestResourceNames, you can get a list of the names in your loaded resource manager to easily find out exactly what the names area that you must use.

Related

What is the proper way to include resources on multiple Forms in an app?

I have an application with an existing Form that has images on each ToolStripButton at the top. These images are in the resx file and look as though they are only available to this Form. I want to make another Form with the same images.
What is the proper way to import these images so that all my Forms can use them. For example, the Save and Open buttons will be on most of the Forms.
In a big project at work we have a solution that has many projects with user controls and forms. That is why we have one extra project called Resources that holds different kind of resources (separate resource files) for the whole solution:
strings (translations)
images
property names
and so on
We reference the project to every other project in the solution where a resource is needed. This way the resources are kept separately, the dll can be easily replaced and nothing will be broken, as long the same resource names are used.
We also use the dll assembly in complete different projects(solutions) where we need for example the same images. When named correctly (for example Company.Resources.dll -> Company.Resources.Images.Toolbar.Add/Remove/Settings) it fits very well into every new project.
In your case it is of cource possible to reference ProjectA in ProjectB in order to use the same resources (as long the projects are in the same solution), but it could be that this will be not always possible (for example in order to avoid circular references).
Create new WinForm solution (in my example one solution with two projects). Add new project of type Class Library:
Add new resources to the resources project (in my example for strings and images):
Adding a resource file for images:
Add some images:
Now reference the resources project from the other projects:
Important => In order to use the resources from outside the assembly, you need to set the visibility to public:
Compile the solution once and use the references resources project from everywhere:

C# Load Resource from DLL (ResourceManager)

I need to load some .Xnb files from a DLL in a Xna Game. For this, there is a "ResourceContentManager" which takes a "ResourceManager" in the Constructor. So how to add the files as Embedded Resources to the DLL and initialize a ResourceManager? The Following Code didnt worked (namespace is "Mox")
ResourceManager resourceManager = new ResourceManager("Mox", Assembly.GetExecutingAssembly());
Stream s = resourceManager.GetStream("Shader");
if(s == 0)
throw new Exception();
I added the Resource "Shader.fx" with "Add->Existing" and then set the Build to Embedded Resource and "copy always" ... this throws an Exception so I know it didnt loaded correctly... any suggestions?
I asked a similar question over at gamedev.stackexchange.com. The answer may help you as well, see below:
I have another solution in addition to Russell's which allows you to use the content manager and allows you to embed all of the types of content XNA supports.
XNA supports the ContentManager though a resource instead of a content project. To use it do the below. Of course you will need to pass a reference of your game's services at some point.
ResourceContentManager Content = new ResourceContentManager(game.Services, Resource1.ResourceManager);
Use this to compile the shader or anything to a xnb.
Add any and all of the XNB to your resources. Them simply load your content as usual.
Content.Load<Texture2D>(".\\assetName")

How do I replace embedded resources in a .NET assembly programmatically?

I am trying to replace a Resource of an exe (.NET, C#) file using C# code.
I have found this article and made this code (using Mono.Cecil 0.6):
AssemblyDefinition asdDefinition = AssemblyFactory.GetAssembly("C:\\File.exe");
EmbeddedResource erTemp = new EmbeddedResource("encFile", ManifestResourceAttributes.Public);
erTemp.Data = myNewFileBytes;
asdDefinition.MainModule.Resources.RemoveAt(0);
asdDefinition.MainModule.Resources.Add(erTemp);
AssemblyFactory.SaveAssembly(asdDefinition, "C:\\newFile.exe");
The code is actually removing the resource and then adding a new one with the same name.
The resource name is encFile and stored as encFile.exe (tried both).
I tested the code and the remove is working (i can tell by the size of the file) and the adding too, but the new file crash just like the file i created with the remove only (for the testing) - it acts like he can't see the replaced resource.
What can i do to fix it? Maybe some changes in the edited EXE file?
The EXE file reads its resource this way:
byte[] buffer = ProjectName.Properties.Resources.encFile;
Trying to do this seems overly complex. If you need dynamic update of resources, ship your resources as a folder for your application (set items in the folder as content and copy if newer in project properties).
If you need dynamic update at runtime, then it's as simple as either:
1] Allow user to replace items in place or
2] Even better, treat it like word-press themes and allow an override folder for each resource.
If you need to tag each resource with metadata you could use a sqlite database or even easier, allow a matching .meta file for each resource to describe it in more detail.
Finally, if you are allowing digital download of your software, then you might consider code-signing your executable - in which case modifying the executable in any way will not be an option.

How to find the name of the default resources file in C# and VB.Net?

I've created an attribute, similar to the ToolboxBitmapAttribute, that allows you to associate an Icon or Image to a class.
To associate an image, the resource file base name, a type (to find the assembly), and the name of the resource are passed to the attribute constructor. I then use the ResourceManager to get access to the resource:
Dim rm = New ResourceManager(ResourceFileBaseName, passedType.Assembly)
Dim obj = rm.GetObject(resourceName)
This is fine except that I want the option to pass just the resource name in the constructor, and omit the resource file base name. Then I would pick up the resource from the default resource file. When I say default resource file, I mean the one when you start Visual Studio, open the property pages and click the Resources tab.
The problem is, when developing in VB.Net, the base name is 'RootNamespace.Resources', and when developing in C#, the base name is 'Rootnamespace.Properties.Resources'.
Where can I programatically find the name of the default resource file?
Update
What I can do is get a list of all resource names:
t.Module.Assembly.GetManifestResourceNames
I can then look for a name that ends with Resources.resources and use that to build the resource file base name.
This, however, is inefficient, but I suspect it's the only way to do it.
You could try all resource files in the assembly and test whether the icon is available.
It is going to very difficult to detect the default resource file. For example, I always move the resource files for my C# project to the root namespace. Also, the user may have purposefully put the image in a different resource file.

How can I reuse .NET resources in multiple executables?

I have an existing application that I'm supposed to take and create a "mini" version of. Both are localized apps and we would like to reuse the resources in the main application as is. So, here's the basic structure of my apps:
MainApplication.csproj
/Properties/Resources.resx
/MainUserControl.xaml (uses strings in Properties/Resources.resx)
/MainUserControl.xaml.cs
MiniApplication.csproj
link to MainApplication/Properties/Resources.resx
link to MainApplication/MainUserControl.xaml
link to MainApplication/MainUserControl.xaml.cs
MiniApplication.xaml (tries to use MainUserControl from MainApplication link)
So, in summary, I've added the needed resources and user control from the main application as links in the mini application. However, when I run the mini application, I get the following exception. I'm guessing it's having trouble with the different namespaces, but how do I fix?
Could not find any resources
appropriate for the specified culture
or the neutral culture. Make sure
\"MainApplication.Properties.Resources.resources\"
was correctly embedded or linked into
assembly \"MiniApplication\" at
compile time, or that all the
satellite assemblies required are
loadable and fully signed.
FYI, I know I could put the user control in a user control library but the problem is that the mini application needs to have a small footprint. So, we only want to include what we need.
You are correct that the different namespaces are the problem. A resource file cannot be given a namespace, it will take the namespace of the folder that contains it. If the namespaces across your two apps are different, the namespace will be different.
I can see three options available to you
Use the same default namespace for both applications
Have an assembly purely for your resource file and reference that in both apps
In the code loading the resource, generate the namespace based on the namespace of the class that's loading it
The Resources generated by visual studio are not public, they are only visible to classes within a library. in order to generate resources as public properties you will need to use a custom generator like this: http://www.codeproject.com/kb/dotnet/ResXFileCodeGeneratorEx.aspx

Categories

Resources