Image Resources in WinForms - winforms

I want to store images in a .dll file and use them for my winform application. but Im not able to load .dll content
System.IO.Stream stream;
System.Reflection.Assembly assembly;
Image bitmap;
assembly = System.Reflection.Assembly.LoadFrom(Application.ExecutablePath);
stream = assembly.GetManifestResourceStream("global::template.Properties.Resources.test.png");
bitmap = Image.FromStream(stream);
this.background.titleImage = bitmap; // image box

The most likely problem is that the path you are specifying in GetManifestResourceStream() is not correct.
I find the following helpful to debug these issues:
Open assembly that has the resource embedded into it, in Reflector.
Open the Resources folder.
From the list of resource paths\folders, find the one with your resource in it.
If you cannot find your resource, did you mark it as an embedded resource?
Your resource path will be "Resource folder" + "." + "resource name".
e.g. "PrismDemo.Properties.Resources.resources.app.ico"

You are using the wrong name, "global::" doesn't appear in the manifest resource name. A typical name would be project.test.png if you added the resource to the project and set its Build Action to "Embedded Resource". To avoid guessing at the name, use Ildasm.exe and find the .mresource in the manifest.
However, your name suggests you added the resource in the Project + Properties, Resources tab. Good idea, that auto-generates a property name for the resource. You'd use project.Properties.Resources.test to reference it. You'll get an Image back, no need to use GetManifestResourceStream.
The project name I listed above is the default namespace name you assigned to the project. Project + Properties, Application tab, Default namespace setting.

Related

Visual Studio 2010 Project - can't adjust the relative path

I have a Windows Forms project. I have a Resources folder and I wan to use the files there using relative path. Here is a printscreen of my project tree
As you may see I have folder UserControls where I have FileExplorer.cs it contains aa openFileDialog + pictureBox. I use this control in some of my forms which are in Forms folder. The case is that in Resources folder I have this T380.jpg image that I want to load by default but for now I can do it only by inserting the full path to it. Here is my code where I try to load the image:
private void FileExplorer_Load(object sender, EventArgs e)
{
pictureBox1.ImageLocation = #"ShoesUnlimitedAdmin\Resources\T380.jpg";
pictureBox1.Load();
}
I use the Load event of the user control to load my image but it only works when I set the full path to the image like C:\\... and so. How can I point to the Resources folder of the project using relative path?
If these images are small then favor adding them as resources in the executable file so you can use Properties.Resources in your code and don't have to deploy the files on the user's machine. Use Project + Properties, Resources. Click the arrow on the "Add Resource" button and select Add Existing File.
If they are big (more than a couple of megabytes) then you'll indeed want to deploy them as separate files. You can find them back by using the location of the EXE program, here's a helper method, spelled out for clarity:
public static string GetResourcePath(string filename) {
string exepath = System.Reflection.Assembly.GetEntryAssembly().Location;
string exedir = System.IO.Path.GetDirectoryName(exepath);
string resdir = System.IO.Path.Combine(exedir, "Resources");
return System.IO.Path.Combine(resdir, filename);
}

How do I load a dll's config file inside another appdomain

I have an application that needs to load an add-on in the form of a dll. The dll needs to take its configuration information from a configuration (app.config) file. I want to dynamically find out the app.config file's name, and the way to do this, as I understand , is AppDomain.CurrentDomain.SetupInformation.ConfigurationFile
However, since it is being hosted INSIDE a parent application, the configuration file that is got from the above piece of code is (parentapplication).exe.config. I am not able to load another appdomain inside the parent application but I'd like to change the configuration file details of the appdomain. How should I be going about this to get the dll's configuration file?
OK, in the end, I managed to hack something together which works for me. Perhaps this will help;
Using the Assembly.GetExecutingAssembly, from the DLL which has the config file I want to read, I can use the .CodeBase to find where the DLL was before I launched a new AppDomain for it. The *.dll
.config is in that same folder.
Then have to convert the URI (as .CodeBase looks like "file://path/assembly.dll") to get the LocalPath for the ConfigurationManager (which doesn't like Uri formatted strings).
try
{
string assemblyName = Assembly.GetExecutingAssembly().GetName().Name;
string originalAssemblyPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase);
Uri uri = new Uri(String.Format("{0}\\{1}.dll", originalAssemblyPath, assemblyName));
string dllPath = uri.LocalPath;
configuration = ConfigurationManager.OpenExeConfiguration(dllPath);
}
catch { }

WPF Dispay image from relative location

I would like to display an image on my dialog which could be located in a directory relative to the one the .exe is located in, e.g.
project
- data
-- logo //<-- that's where the image is located
-bin //<-- that's where the .exe is in
A default image should be included in the .exe but on displaying the dialog, the \data\logo directory should be checked first and if an image with the given filename could be found there that one should be used for display instead of the one that is inside the .exe.
Any ideas on how to do this?
Thanks,
tabina
Use the pack URI
pack://application:,,,/ReferencedAssembly;component/data/logo/image.png
As he asks for a folder relative to the exe, i suggest he means the logo should be located inside the filesystem (e.g. c:\program files\MyApp\data\logo). So I would check if the file exists with
File.Exists("/data/logo/logo.png")
If it returns false, you could load your embedded resource.
//Edit
If you use this snippet in your Visual Studio IDE the path is located at
<Project directory>/bin/debug/data/logo
what I am doing now is
// set the logo
string path = Environment.CurrentDirectory + "\\data\\logo\\logo.gif";
var uri = new Uri(path, UriKind.Absolute);
try
{
this.myImg.Source = new BitmapImage(uri);
}
catch (Exception e)
{
this.myImg.Source = new BitmapImage(new Uri(#"pack://application:,,,/myAssemblyName;component/Images/logo.gif"));
}
This works pretty well, but what I don't like about this is that it is all written in the code-behind. I would rather have it more re-usable.
Is there a way to put it all into a template and apply it to viewboxes/images?
Thanks,
tabina

WPF control hosted in Windows Forms: Is it possible to access resource files?

I have a WPF control hosted in Windows Forms and I would like to access it's resources, specifically images. What is the best way to do that?
I was thinking of using a ResourceDictionary, but I'm not sure how I can access it from within a Windows Form.
This is a standalone WPF control, in a DLL? There are two ways that the resources can be embedded... as part of a .resources file (e.g. the Project's "Resoruces" tab), or as files included as "Embedded Resources"...
To get the assembly reference to the DLL this is usually the easiest:
var ass = typeof(ClassInOtherDll).Assembly;
In the Resources
If this is part of the default project resources, and not a different .resources file included inside the DLL, you can use the default base-name.
var ass = typeof(ClassInTargetDLL).Assembly;
var rm = new ResourceManager("...BaseName...", ass);
BaseName for default project resources is :
C# := Namespace.Properties.Resources
VB := Namespace.Resources
After that you can just call GetObject() and do a cast back:
var myImage = rm.GetObject("check_16");
return myImage as Bitmap;
If you want to find out whats in there, get the assembly reference and call
ass.GetManifestResourceNames()
.resources files can be used with a ResourceManager
embedded resources will just show up as a list. Use the other method for these.
And this is all assuming they default culture =)
As Embedded Resources
You can use the regular methods on the assembly to get an embedded resource. You find it by name, and then Basically you will need to convert the stream back into your desired type.
GetManifestResourceNames()
GetManifestResourceStream(name)
help getting the desired file with a helper function to find files by name.
I usually use these like this:
// called GetMp3 in the post, but it returns a stream. is the same thing
var stream = GetResourceStream("navigation.xml");
var reader = New XmlTextReader(stream);
return reader;
To get an image that is an embedded resource, this works for me:
var stream = GetResoureStram("check_32.png");
var bmp = new Bitmap(stream);
this.MyButton.Image = bmp;

Loading BitmapImage in code

From my assembly (A) I want to call a method in another assembly (B) which passes an image. This image is then shown in a WPF Window - the window is part of B's project.
I can't seem to pass an ImageSource with a pack:// uri as this gets evaluated in the context of B, so I guess I need to cache the image using CachedBitmap (?) when still in A.
BitmapImage img = new BitmapImage(new Uri("Images/32px-Nuvola_apps_cache.png", UriKind.Relative));
CachedBitmap cbmp = new CachedBitmap(img, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
I've managed to get this to work if I set the image to Embedded Resource and load it as a stream, but this isn't the WPF way.
It seems from the pack: documentation that I should be able to do this, but I've tried these below and none work;
"Images/32px-Nuvola_apps_cache.png": "Could not find part of the path"
"pack://application:,,,Images/32px-Nuvola_apps_cache.png": "The URI prefix is not recognized.".
"pack://siteoforigin:,,,Images/32px-Nuvola_apps_cache.png": "The URI prefix is not recognized."
All I want to do is load a Resource .png file into memory and pass it wholesale to a method in another assembly.
Thanks
Paul.
Try:
pack://application:,,,/YourAssemblyName;component/Images/32px-Nuvola_apps_cache.png

Resources