I added an XML file as an embedded resource in my class library by using the accessing the project properties in Visual Studio and then Resources | Add Resource | Add Existing File...
I've tried to access the file using the following code, but I keep getting a null reference returned. Anyone have any ideas?
var path = Server.MapPath("~/bin/MyAssembly.dll");
var assembly = Assembly.LoadFile(path);
var stream = assembly.GetManifestResourceStream("MyNamespace.filename.xml");
I find it much easier to use the "Resources" tab of the project's properties dialog in Visual Studio. Then you have a generated strongly typed reference to your resource through:
Properties.Resources.Filename
The MSDN page for GetManifestResourceStream makes this note:
This method returns a null reference
(Nothing in Visual Basic) if a private
resource in another assembly is
accessed and the caller does not have
ReflectionPermission with the
ReflectionPermissionFlag.MemberAccess
flag.
Have you marked the resource as "public" in your assembly?
I found that this article explains nicely how to set this up: http://www.devx.com/dotnet/Article/10831/1954
One thing that may have helped in this case is using a different method for determining the location of the embedded resource.
GetEntryAssembly: Use this method to reference the executable file that was run to start the current process. The entry assembly is set for Windows forms applications, but for most other applications (for example, web projects), GetEntryAssembly returns 'nothing' (or null, in C#).
GetExecutingAssembly: Use this method to reference the same assembly that the executing code is in.
GetCallingAssembly: Use this method to reference the assembly containing the code that called the current method. This method is useful if you write generic code to read embedded resources that is inside a shared assembly where the embedded resource is in the calling assembly.
I personally prefer this method over using the "Resources" tab because it allows me to use other tools to add resources to the project for inclusion on compilation. I don't have to use the GUI with this tool
Related
I'm having a hard time wrapping my mind around how the resources work in an ASP.NET project. In my solution I have 2 projects:
A Website project that contains an App_GlobalResources folder where most of my resources reside (build action: "content").
A utility project, compiled as class library (that the website references), where I need another set of resources (called "ExceptionMessages" hereafter).
Nota: each project uses its own resources, there is no cross linking involved here.
I added a new resource directly in my second project (both as "content" or "embeded resource") and tried to access it via ExceptionMessages.Tag. Intellisense is happy about it and correctly suggests the Tag but I get the following error at runtime:
"Could not find any resources appropriate for the specified culture or
the neutral culture. Make sure
"Resources.ExceptionMessages.resources" was correctly embedded or
linked into assembly "App_GlobalResources.lqgd5zqy" at compile time,
or that all the satellite assemblies required are loadable and fully
signed."
Somehow, I don't understand why the webserver is looking for the resource in the App_GlobalResources instead of directly in the assembly where it is used... or how I could go around this in a clean way. Any hint or idea?
Thanks!
I have a Visual Studio solution consisting of multiple projects. In one of the projects, I have a languagelocalization resource file. I would like to access this file in code in a different project using ResourceManager. Normally when accessing a resource file in the same project I would use:
ResourceManager rm = new ResourceManager("Namespace.LanguageLocalization", Assembly.GetExecutingAssembly());
However when I use that same code in a different project, it can't find the resource file. I double checked to make sure this project is referenced by the project with the resource file and its declared in a using statement at the top of the class.
Any suggestions?
The second argument to the ResourceManager constructor specifies the assembly that contains the resources. Assembly.GetExecutingAssembly() won't work because that returns the assembly for your other project. Instead, pass typeof(APublicClassInTheResourceAssembly).Assembly; any class in the resource assembly will do.
I've two Visual Basic 2008 projects - one is a class library project and another is a Windows Forms project. In the class library project, I've defined some strings in the project resources (project properties > Resources tab).
I build that class library project and get the DLL file from the debug folder and added up as a reference in my Windows Forms project.
How do I read those strings from the referenced DLL file?
While you can dynamically load the DLL as ho suggests, it's fine to use a reference as you have done. In fact I would recommend using a reference unless you had a particular requirement to dynamically load the resource assembly.
As to accessing the resources there are a few things you need to do.
In the resource assembly you will need to ensure the resources are public. By default resources are set to internal which means you will not see the resources in the winforms app. Double click on Properties\Resources.resx to open the resources view. In the top toolbar you will see a label "Access Modifier" next to a combo box drop down. Change the selection to public.
You will need to reference the assembly from the forms app. You have stated you have already done this. Just a note that a better way to do this is to create a solution that contains both projects. Then in the forms app choose add reference. Click on the Projects tab up the top. Double click on the resource DLL project name. This works better than referencing the debug DLL directly since it means if you change between a release build and debug build in your forms app, it will automatically build a matching release/debug version of your resource assembly.
Once you have added the reference you can simply reference the type out of the resources DLL, e.g.
ResourceDLLNamespace.Properties.Resource.ResourceName
Just a note, you need to be aware of type name clashes if you are using the same namespace for your forms app and resource DLL. In this situation both your forms app will have access to it's own Properties.Resources class as well as that of the resource DLL. You can do two things to avoid this:
Use a different namespace between the two assemblies
In the resource assembly don't include a default Properties\Resources.resx resource dictionary. Delete it and manually add a new resource, i.e. Add New Item and select "Resources File". You should find that you will not be able to add the new resource dictionary to the Properties folder - add it to the root or some other folder as you require. This will automatically give it a different type name by virtue of being in a different folder. You still may want to avoid using the resource file name of "Resources" however, as if you have all the relevant namespaces in scope via using statements you will get the same issue that the compiler won't know which version of Resources to use.
-Donovan
I think you just use System.Reflection.Assembly.Load to load the other assembly then use the constructor of System.Resources.ResourceManager that takes an assembly.
Note, I don't think it needs to a reference for this to work.
I'm trying to see if it is possible to pull data from a DLL. I did some research and found that you can store application resources within a DLL. What I couldn't find, was the information to tell me how to do that. There is a MS article that explains how to access resources within a satellite DLL, but I honestly don't know if that is what I'm looking for. http://msdn.microsoft.com/en-us/library/ms165653.aspx I did try some of the codes involved, but there are some "FileNotFoundExceptions" going on.
The rest of the DLL information is showing up: classes, objects, etc. I just added the DLL as a resource in my Visual Studio Project and added it with "using". I just don't know how to get at the meat of it, if it is possible.
If dlls are .net, you can use reflection.
Using System.Reflection;
....
Assembly A= Assembly.LoadFrom(YouDllFileName);
string[] STA;
STA= A.GetManifestResourceNames();
// STA contains all the resource names in the dll
...
// to extract them
Stream str= A.GetManifestResourceStream(STA[I]);
// then, you can make that stream became a file if you wish
You can also extract a .net assembly resources by using ildasm
I'm not totally sure what you might be running into based on your description, but a couple of general pointers...
If what you are trying to find is files you've added to the project you do this:
Right click on the resource in solution explorer, hit properties and set the "Build Action" to "Embedded Resource".
For strings and icons, add a .resx file to the project and insert them in there. If that's what you're doing and still running into issues, check the Build Action.
There is two types of dll.
Managed dll - dll that writen on any .net language (like csharp)
The link that you provide is working with managed dlls.
Unmanaged dll - classic c/cpp dll.
in this case you need to link between managed (your code) and unmanaged.
To find what the type of your dll, you need to add this dll as reference.
In visual studio open project, right click on references(in Solution Explorer).
Then "add reference"->browse-> add your dll.
Then at references, you can see your dll.
Right click on him, and add view in Object Browse.
If you see something like class "c" inside namespace "b", you working with managed dll.
In Object Browser you can learn a lot about your dll (maybe this is more important, than just extract resources)
At this point you can do the way that "Daniel Dolz" answer to you.
Since you say you are able to add the DLL in a using directive you can probably use the methods that the DLL exposes. If you do not have the documentation for the DLL then you may just have to try using the object browser to see what it has to offer.
assume:
using MyDll;
you should them be able to call the methods like this:
string x = MyDll.SomeType.GetValue();
is that what you were asking?
I'm trying to rebuild zlib.net and create an assembly I can reference in future projects in Visual Studio.
However, after building from the supplied source code and moving the resulting zlib.net.dll to C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\PublicAssemblies, while I can indeed add the zlib.net reference to a new project, I do not have any access to the underlying objects.
I believe I'm missing some important configuration(s) in the zlib.net.dll project settings file so I can generate an assembly that can be referenced at design time by other projects. I'm just not sure which.
Could you please help?
UPDATE:
Note that I'm testing the resulting assembly by using zlib.net (link above) own supplied demos. When I use the supplied zlib.net.dll all works fine. When I use the one I build from source, it fails.
You shouldn't ever need to add something to the PublicAssemblies folder.
Place the assembly somewhere in your development folder hierarchy (perhaps C:\dev\Reference\zlib.net\zlib.net.dll). When you want to add a reference, click Browse and locate the assembly in your dev folders. Then click the reference in Solution Explorer and bring up the Properties pane. Make sure Copy Local is set to true.
If you have your solutions in source control, you'll want to copy the DLL to the current solution hierarchy and reference it from there - you don't want to force everyone to have some specific non-source-control folder to build a source controlled project.
What do you mean, you have no access to underlying objects ?
Do you mean that you cannot instantiate objects from classes that you have defined in that assembly ?
If so, are you sure that those classes are 'public' (have the public access modifier) ?
It is possible that VS.NET doesn't add an access specifier to your class definition when you add a new class, hence the default access specifier will be used.
In this case, that means the 'internal' access specifier is used. (Classes are internal by default).
Then, this could explain why you cannot instantiate objects from those classes, since, 'internal' classes (or methods, or whatever), are only visible within the assembly in which they've been declared.
Solution: specify the 'public' access modifier on the classes that you want to be 'visible' outside that assembly.
Frederik's suggestion is the first thing I'd check. You can't access classes or class members which are non-public in an external assembly.
If they are set to public already, make sure you have proper using statements for the namespaces of the classes you want to access. So if you want to access ZLib.SomeNameSpace.Archive class, ensure you either reference it by the full name, or by adding
using ZLib.SomeNameSpace;
to the code file first. Then you should be able to access the class, such as:
Archive myArchive = new Archive();
Assuming that all your classes are indeed public, have you signed your assembly and added it to the GAC?
There are a few steps to go through, here is a short tutorial. There are a few niggly details but the example I link to should get you up and going.