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.
Related
I have a web service which supplies me with a generated .resx (XML only) which I then convert to binary a .resources file. I am currently generating an assembly file with that using al.exe. Here are my arguments:
/t:lib /c:{culture} /embed:"{.resource input}" /out:"{.dll output}"
Loading this assembly in via Assembly.LoadFrom(file) works fine, but I believe that my assembly is not properly generated. It has no type, namespace, or methods to invoke and therefor no ResourceManager apparently.
Essentially I am just wondering if it is at all possible to generate, load, and utilize resources that have no class or namespace which my project knows about at compile time. Thanks.
Your assembly is a satellite assembly. From MSDN:
By definition, satellite assemblies can only contain resources. They
cannot contain any executable code.
If you want to access the resources of this assembly - similar code should work:
ResourceManager rm = new ResourceManager(
"ResourceTest.Properties.Resources",
Assembly.LoadAssembly(file));
MessageBox.Show(rm.GetString("helloWorldString"));
Also, the article from MSDN: Walkthrough: Loading Resources from a Satellite Assembly shows an alternative way of how to load a resource string from a satellite assembly.
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 need to use same resource file for different projects.
My resource file name is named Resource1.resx
and I created a .resources extension file by using resgen and I generated a .resources.dll by using al.exe
But then as I try to use the file in my project, I am getting one error, my code is something similar to this:
ResourceManager resmgr = new ResourceManager("Resource1",
Assembly.GetExecutingAssembly());
string msg = resmgr.GetString("name");
MessageBox.Show(msg);
The error message is something like this:
Could not find any resources appropriate for the specified culture or the neutral culture. Make sure "Resource1.resources" was correctly embedded or linked into assembly "WinTest" at compile time, or that all the satellite assemblies required are loadable and fully signed.
How to solve this issue?
You are loading the Resources from the Executing Assembly but as you mentioned you have defined the resources in a separate assembly.
Instead of the executing assembly you should point it to your resources dll.
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 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