I'm trying to utilize a Shared Project concept to share the client application logic between WPF project and Android (Xamarin.Forms). In both projects I want to use the same localizable texts, therefore, it looks logical for me to move resource file (with texts) to the shared project.
The following sample is from WPF project, but the faced problem is related to shared projects, not WPF.
In my WPF project in XAML based views I access the string values as follows:
<TextBlock Text="{x:Static i18n:Strings.WelcomeMessage}" />
The file Strings.resx and its translation are located in the folder I18N, ie. they are not placed in the project's root. Therefore the generated public class Strings is placed to the namespace TestApp.I18N. When the I18N folder belongs to WPF project directly, everything works great, but if I move I18N to the shared project, the WPF application crashes with the exception:
Could not find any resources appropriate for the specified culture or the neutral culture. Make sure "TestApp.I18N.Strings.resources" was correctly embedded or linked into assembly WPF at compile time, or that all the satellite assemblies required are loadable and fully signed.
If I look into compiled assembly using some disassembly tool I can see the difference between both compilations:
In the compilation where I18N folder belongs to the shared project I see the resource named TestApp.Strings.resources
In the compilation where I18N folder belongs to the WPF project I see the resource named TestApp.I18N.Strings.resources
It actually explains good why in the first case the app crashes. And it is clear what workaround can be used (I can put Strings.resx and related to the project root). But I can feeling that having resources in shared project isn't good idea, because lack of proper support. Can someone share own experience in that direction? Why resource files from shared project are interpreted a bit differently by the compiler?
Related
I'm using an embedded resource generated by 'PublicResXFileGenerator' which generates my ResourceManager class.
I'm trying to find a way to support multiple resx files for the same language or in some way being able to modify it from a deployed application but this doesnt seem possbible.
For example client 'x' is using the en-US translation:
Flat
and the other client 'y' are using the en-US translation:
Appartment
Maybe the above example is stupid but I hope you get my point.
Different users are using different namings for the same thing and I'd like to support this.
Is it possible?
Note:
My code is written in C#.
The strings in your default resource file (probably Resources.resx) are embedded in your executable file.
If you define a language specific resource file (e.g. Resources.en-US.resx) then Visual Studio will automatically generate a satellite DLL containing the localized resources.
The same applies if you add localized resources to a WinForms form, as shown here for Form1.
The satellite DLL is generated in a sub-directory of the bin directory.
The DLL must be deployed on the target machine in a sub-directory with exactly the same name.
This works for localized strings in any language, but it works exactly the same for strings in the current default language.
If the current default is en-US, and there is a satellite DLL for en-US, and it contains the required resources, then the .NET Framework will automatically use resources from the satellite DLL.
If you don't want the resources from the satellite DLL, no problem. Don't deploy it to the target machine. Then the .NET framework will use the default resources which are embedded in the executable.
If you only have two variations, then it is easy to manage in Visual Studio using the default resource file and an en-US resource file. If you have more than two variations, you are going to need a strategy to generate the resources. The simplest way would probably be to misuse another language.
Alternatively, you could use some other tool. Winres might do the job, but I'm not 100% sure.
Technically, you can define custom cultures, e.g. en-US-medical, or en-US-legal, but in my experience that is more bother than it is worth. I don't think (just my opinion) that Microsoft is strongly committed the concept.
I have a multi-lingual MVC web application referencing multiple projects. The application's resources are also defined in separate projects/modules, for example Application.Models.Resources.
This approach has worked well with the initial language set but now I have added additional languages to the resource projects, the new language resources dlls are not be copied to the application's /bin folder. For example, a Swedish language ('sv') variant was added to the resource project, it is not being copied to the /bin/sv folder of the application.
The resource file has its Access Modifier set to 'Public'.
What am I missing? How can I ensure that the language variants are installed?
Any advice would be appreciated.
Whilst there might be other solutions to this problem, I found that removing the references to the resource projects from the solution and then re-referencing them (Add existing project) fixed the problem. Other users with this problem might also want to try unloading and then reloading the resource projects (I was unable to test this as the first method resolved the problem).
I have my auto generated Resource.resx file set up with keys and strings. I also have three other resx files for German, French and Spanish given to me from translators. I'm not able to get the localization functioning and I suspect that the resx files aren't being called correctly. I added them to the project by dragging them into the solution explorer under "Properties". I have a nagging suspicion that just dragging them in isn't creating the proper connections behind the scene.
Now It's totally possible my issue lies somewhere else. If anyone can tell me whether it's ok to add resource files this way or if not, what the correct way is, it would save me tons of time spent chasing my tail. Thanks!
Resx files in Visual Studio include a special tool which is run at build time and translates them into embedded resources. Right-click your original VS-created resx file and click Properties. You should see Build Tool or something similar. Also note the resource type (Embedded, etc.). Make sure that you match these settings for your manually added files.
Once this is set up, you will need to use the CurrentUICulture property to tell .NET to pick up the appropriate resources. You can choose to change the culture/language at install-time or run-time. Here is a comprehensive tutorial which describes the various options available to you:
WPF Localization Using RESX Files
That said, as a best practice, translated Resx files are generally deployed as satellite assemblies. The main application DLL/EXE contains only the language neutral resources file. Other resource files are compiled into separate assemblies and deployed side-by-side with specific naming conventions. This allows you to dynamically add translations, localizations, etc. even after the application is deployed. Here's an introduction: Packaging and Deploying Resources in Desktop Apps
Is it possible to create single exe file from my C# WPF project? The project contains some images and videos in Movies folder inside bin.
How can I compile all of this in singe exe file? I know it will be large in size but it is OK.
You should add this files to you project and use Build Action: Resource for this files. In this case, it will be introduced into the main assembly of application.
It will be a binary resource, because it is embedded in the compiled assembly as an opaque binary large object.
Quote from Matthew MacDonald book: Pro WPF 4.5 in C#:
There are a couple of things that you must not do in order to use assembly resources successfully:
Don’t make the mistake of setting the Build Action property to Embedded
Resource. Even though all assembly resources are embedded resources by
definition, the Embedded Resource build action places the binary data in another
area where it’s more difficult to access. In WPF applications, it’s assumed that you
always use a build type of Resource.
Don’t use the Resources tab in the Project Properties window. WPF does not
support this type of resource URI.
I developing an application which will have at least 2 if not 3-4 different versions (don't ask). The applications will basically be identical except have different product names, window titles, application icon and some other minor differences in string or image resources.
My main goal is to avoid having to create multiple projects for each executable. I want to be able to have one main application project and have it just load those resources (name, icon, etc.) and be agnostic of which version it is. This way, I can simply configure my setup project to deploy the proper resources with the version of that application. Ideally it would not be that visible to the end-user after it was installed.
What I've tried: I've experimented with creating different .resx files and swapping them based off build configuration, or I've also experimented with adding environment variables and #if on the variable. But, I really do not want multiple build configurations. I want it to only depend on deployment.
Is it possible to create resx files, either in a different project or in the same project and exclude them from the build, and have them generated into satellite .DLL assemblies similar to localization, and then load whichever one is deployed with the application?
I'm confused if I should be looking at running my own RESGEN and AL tasks, or if I should just create a DLL project (but maybe then I'd have to have multiple DLL projects for only 1 resource file). Also, any article I can find about using .RESX files is for localization. It relies on setting the CurrentCulture to resolve the specific resources to use. My scenario has nothing to do with culture... I just want to load different resources for different deployments of the application.
Without knowing how deeply you need to go, you can package the resources into separate .dll files and differentiate that way. For instance, building the various different versions into a seperate DLLs and having your installer adjust the name to match what your application expects or use an XML configuration file to specify which to load and load it that way.
Assembly.Load() will allow you to load the alternative assembly.
Assembly _assembly;
_assembly = Assembly.GetExecutingAssembly();
Stream _imageStream;
_imageStream =
_assembly.GetManifestResourceStream(
"ThumbnailPictureViewer.resources.Image1.bmp");
Bitmap theDefaultImage = new Bitmap(_imageStream);
See: http://www.attilan.com/2006/08/accessing-embedded-resources-using.html