Wednesday, August 20, 2008

Resource files, satellite assemblies, and you

So while at work doing a POC for a C# windows form, i was fiddling with the resource files for my app. If you are not aware of them, resource files are compiled text or XML files that contain key-value pairs. You create a form (or a website if yer doing ASP.NET) that has some default textboxes, labels, and such. Then you create some text/resx files that contain the key-value pairs and rename them to match the culture you are using (en-US for US english, de-DE for german, etc).
After adding a custom section in the app.config file via an example from this guy Derik, i was now able to add languages to a drop down on the fly.
The next step was to create the resource files for each of the languages. Now creating them through the 2k5 IDE is obviously the simple and easier way to go as the compilation and generation of resources is done for you at compile time.

But my requirements needed to be able to compile the app once and add language resource files at any given time. While there is still a process to do it, it can be done with very little effort.
The steps include:
- create a text file or resx file and add some key-value pairs
- compile the file into a resource file using the resgen executable that comes along with Visual Studio
- link the resource file into a DLL
- create a new folder in the working folder, named after the culture you are adding
- plop it in, edit the app.config and POOF, yer off

Now as easy as it sounds, i did run into issues. The main error message being:

Could not find any resources appropriate for the specified culture or the neutral culture. Make sure "YOUR RESOURCE HERE" was correctly embedded or linked into assembly "YOUR ASSEMBLY" at compile time, or that all the satellite assemblies required are loadable and fully signed.


There were some details left out in the many examples out on the interwebs and it seemed a lot of people came across the same issue i had. Basically, after compiling the resource file and linking to a DLL, the application still couldnt find said DLL and its resources.
It turns out that when you compile the resource file, you need to add the namespace of the calling application thats using it.
Before, i was doing this:

resgen german.txt Form1.de-DE.resources


where Form1 was the default form name from Visual Studio. Where as the correct way to do it was to run it as
resgen german.txt TestAPP.Form1.de-DE.resources


and then from there we need to link it to a DLL

Al.exe /t:lib /embed:TestAPP.Form1.de-DE.resources /culture:de-DE /out:TestAPP.resources.dll


After putting it in the correct folder, things went great. Now im currently working on getting a datetime object to format correctly for neutral cultures... if anyone has info on that let me know

1 comment:

Matt said...

Oooooooh... wait, what?