I need to create resource files (.resx) programatically. Those ressource files are meant for
other projects, not for the one where I programatically create those resx files.
Is there a clean way to tell the other solutions/projects that it has to add the externally created ressource file.
In the resoure files strings are stored which shall be used in that project later.
Example:
I create a Resource.resx file with a project called ResourceCreator.
Now I have to tell a Project called MyProject to bind it into the solution/project WITHOUT to have to manually open the solution and add it then.
I believe you really want to create Satellite Assemblies.
A satellite assembly is a compiled library (DLL) that contains
(“localizable”) resources such as strings, bitmaps, etc. You are
likely to use them when creating a multilingual (UI) application.
Satellite assemblies provide you with the capability of designing and
deploying your solution to multiple cultures, rather than hard coding
strings, bitmaps, etc., into your main application. Satellite
assemblies are used to deploy applications in multiple cultures (not
languages), with 1 satellite assembly per culture - this is the
default behavior, but you can obviously have more granular control if
you handle the build process manually.
MSDN Ref - Introduction to Satellite Assemblies
Try looking into the Microsoft.Build namespace, it has all sorts of fancy ways of loading/modifying project and solution files.
Microsoft.Build namespaces
Related
At the moment of creating a project of type "Library of Classes, usually one can generate a dll when compiling, but how could I generate a dll without losing others that I already have included?
I explain with an example: It turns out that Nuget downloaded an S22.Imap dll with the one I worked with, later I generated the dll in the traditional way that I explained in the beginning, but when I wanted to work with dll in another computer, I got errors that were not I found functions that contained the S22.IMAP dll. So to solve this problem, I had to copy the dll of my project, S22.IMAP in an additional way in a specific path of the other computer.
My question is:
How could you generate a dll that includes the ones included in the project you were working with?
All the referred 3rd party dlls (S22.Imap.dll in your example) will be copied to the output folder together with your own dll file (let's say a.dll) when you build your project. That means you should always copy them together (S22 + a.dll) to the place you want to refer them, on another computer/folder/place.
If you really want to make them only one file (although it is not recommended), you can set the S22 one as some "nested resource". Then you will get only one a.dll file and the S22 one is inside the a.dll. See below page for some reference:
Embedding one dll inside another as an embedded resource and then calling it from my code
AND, ILMerge is some tool that can help you do so.
In general, you don't. A DLL is a dynamic linked library, and you would normally only combine static libraries during a build. Here is an answer on the difference between static and dynamic linking.
Typically you would include all the DLLs you need in the installer package. If you use Visual Studio to create the installer, it can detect the dependencies for you. When you run the installer, all of the necessary DLLs are deployed. Nearly all commercial .NET software follows this pattern.
It is possible to merge an assembly into another assembly using a tool called ILMerge. This would be a very unusual thing to do, and could cause issues with intellectual property and code signing, so it is not recommended.
I've been using http://www.codeproject.com/Articles/30035/Simple-WPF-Localization project to localize an app because (well) it's simple and straight-forward and supports dynamic language change.
I put all the language resources in the main project (i.e. resources.resx, resources.ja-JP.resx). That way the satellite assemblies get generated automatically and into the correct folder structure.
However, i would like to put all the language resources (except the default/neutral one - resources.resx) in a separate project. With that, i don't need to rebuild the main project (which has the application source) if i only needed to change something in one of the translations.
So, i would like to know if there is a standard way (or at least a very straight-forward way) of creating a VS project that only contains language resources.
I already tried creating an empty project and setting the output to class-library and the assembly to match my executable's name. It does create the correct satellite assemblies in the correct folder but it also generates a dll. It would be real simple if there's a project-type for c# or wpf that are completely language resource-only but i can't seem to find any references about it.
(btw, i'm using VS 2010 with WPF project)
thanks for any help!
(late reply, but for the community)
Depending on exactly what one want to achieve, building satellite assemblies from the command line might be the ticket for you (using command line tools resgen and al.exe).
I had to do this to enable non developers to modify resources, and without going through the development team/build/deploy cycle, have their changes take effect and allow them to validate.
This is mentioned in a lot of places in the MSDN docs, but I haven't seen many end-to-end samples demostrating it:
https://github.com/JohanPGunnarsson/LocalizedResx
I know there are several questions about satellite Assembly's out there, but I still have some troubles when trying to implement them
My Goal is to separate each culture in a single assembly, giving me the flexibility to only re-compile one assembly at a time when required, I wouldn't like to compile all languages if I only want to make some minor changes to just one language
I want to fully understand how satellite Assembly's work. This is my current understanding:
Satellite Assembly's can be dropped in the bin directory without the need to recompile the whole application, which means the app does not require these assemblies in order to work correctly (as long as the fallback resource is specified)
S.A. has to be linked to a single culture
Now I can generate a S.A. using the al tool or Visual Studio can do it for me if I add the .resx files, the S.A. are created (in the bin folder I can see the folder structure for the specified cultures)
Question 1. Are these dll's equivalent, the one's generated by Visual Studio and the one's generated with the al tool?
Question 2. Do all these dll's must share a common name in order to work?? (I know for consistency they should, but if they do not share the name let's say creating them with the al tool specifying different names) can they still be recognized by the .Net framework to be loaded?
Question 3. If I want to use the ResourceManager class, do I have to instantiate one instance for each assembly-culture? (and since they contain the culture in their name, they have different assembly names, do I have to manually format the embedded resource file to load to match the current culture and load that assembly manually? Since they would probably not be loaded the first time, do I have to load it manually by specifying the file path inside the culture folder?)
Question 4. Are these S.A. loaded automatically by the .Net framework or do I have to explicitly load them?
Question 5. In case I have to load them, this means if I want to specify the resources declaratively in my control tags, do I have to create and register a custom resources factory in order to load them?
Question 6. If I add several resources for several cultures in a class project in visual studio with no code, they are automatically embedded, when I compile, the satellite assemblies for each culture are created, are these dll's related? I wonder if they are related by name, namespace or something
All these questions are based on this: I thought I would be able to just add the assemblies to the bin folder and specify something like a global assembly in the ResourceManager, and it would load automatically the resources even when they'd be in a different assembly (that's why my concern about the assembly names or how several satellite assemblies are related) just like when you define resources in a single assembly, you just call the Resources.MyResourceKey and that's it
I appreciate your hellp, this topic is driving me crazy =(
I know the resgen and al tools look a bit more complicated than they ought to be, but I am pretty sure that your goal is achievable, i.e. you can build your satellite assemblies outside of a Visual Studio solution (to save you having to maintain all your translated resources in your solution) but get exactly the same results.
Question 1: Yes
Question 2: Yes, the ResourceManager depends on the naming convention to load localized resources
Question 3: No. You can use the standard ResourceManager. In fact you don't have to use ResourceManager directly at all. Include your base resources in your solution and configure it with Build Action = Embedded Resource and Custom Tool = PublicResXFileCodeGenerator, then Visual Studio will automatically generate and maintain a class (with the same name as your resx file) that lets you access resources through static properties. Depending on Thread.CurrentThread.CurrentUICulture and on what satellite assemblies are deployed, these properties will either give you localized resources from a satellite assembly or from your base assembly.
Question 4: No. The ResourceManager does that automatically.
Question 5: See Q4. Nothing to do.
Question 6: See Q2. It's based on a naming convention (folder named as per the culture, satellite assembly named as per the base dll) and metadata (e.g. culture name used when compiling using al)
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!
The book is WPF Unleashed, and it tells that binary resources from a different assembly can be used as well, but what it doesn't explain is the concept of assembly and the need to pack resources in a different assembly. So i put the question here.
I tried to google it, but couldn't find the answer that allows me to comprehend what is an assembly in WPF, and how to create an assembly that just consist of resources using Visual Studio 2010?
And second, what is the advantage of packing resources in a different assembly except that they can be updated without shipping a brand new assembly of the product.
WPF assemblies are no different than any other .NET assembly in terms of structure and use. They are the fundamental unit of deployment of an application (web, windows, service, etc) and contain resources for the execution of a .NET application.
I'd take a look at the MSDN article on assemblies -- it's pretty straightforward.
As for your second question, I'll repeat my comment here. You already answered your question about packing resources in a separate assembly -- you can redeploy that separate assembly without having to redeploy or rebuild your original product. You gotta like that. Being able to drop in to your bin directory an assembly that has, say, a bunch of custom widgets that you want to display on your site and having your site automatically probe the bin directory and grab all of the resources that meet its criteria is wonderful. I don't end up having to touch my main app -- just create a new project for my new resources, compile it to a separate assembly (DLL in this case) and just drop it in 'bin' and voila! Awesome.
Hope this helps.
Here's a starting point:
wiki on .NET Assemblies
An Assembly is similar to a C++ DLL, but it has some other characteristics, such as metadata which describes the classes that are available for use.
One advantage of packing resources in a different assembly is that it gives a single point of reference - if you need to reuse resources across an application (or many applications) that use multiple assemblies, then this is a good strategy to adopt. This is particularly useful if those resources need to be localized.
WPF does not define assemblies, the concept is defined across the .NET Framework.