.NET Localization, Part 2: Creating Satellite Assemblies
Pages: 1, 2
Making a Satellite Assembly Out of a Resource File
So the first question is, what kind of tools are available for creating satellite assemblies? You need the following tools:
-
resgen.exe -
al.exe -
ildasm.exe
Uitimately, al.exe is the program that embeds your resources into a satellite
assemby. But al.exe will only accept resources in .resources binary format. But
our inputs are usually either plain text resource files or XML-based resource
files in .resx format. resgen.exe is used to convert these alternate forms of
resources to the .resources binary format palatable to al.exe.
Where does ildasm.exe fits into this picture? If you remember what Visual
Studio IDE is doing, you will see that there is a name translation between your
resource file directory structure and how that resource file is known inside of
the assembly. Becaue we are using the Visual Studio IDE to generate the default
resources and the extenal process to generate the satellite assemblies, both
mechanisms must produce assemblies with the same kind of naming hierarchy for
the resource files.
So we use ildasm to examine the DLLs that Visual Studio IDE generates to find
out what the structure is, and use the same mechanism to generate the satellite
assemblies. You can also examine the satellite assemblies using ildasm to make
sure that you get the names right. This will be useful for debugging errors
from the resource manager telling you that it can not locate a resource.
Now that the tools are outlined, how do we convert an external resource file into a satellite assembly? As noted below, this is a three (really, two) step process.
Step 0: Set your paths for resgen and al.exe:
@set path=%path%;
"C:\Program Files\Microsoft Visual Studio .NET\FrameworkSDK\Bin";
c:\winnt\microsoft.NET\framework\v1.0.3705
Step 1: Use resgen to create a .resources file from a .resx file.
Resgen MyText.resx
The above command will create a file called:
MyText.resources
Step 2: Use al.exe to create the satellite assembly:
Al.exe
/t:lib
/embed:MyText.en-gb.Resources,MyApplication.MyText.en-gb.Resources
/culture:hi-gb
/out:MyApplication.resources.dll
There are a couple of things worth noting here:
/t:lib: Says you are interested in a .dll.
/embed:MyText.en-gb.Resources,MyApplication.MyText.en-gb.Resources
: Embeds and renames the resource to a target name to match the Visual Studio
IDE naming structure.
/culture:hi-gb : Identifies the culture in which you are interested.
/out:MyApplication.resources.dll : Name of the DLL in which you are
interested.
The generated .dll has to have that naming convention for .NET to find it. Also notice that you have to specify the culture setting, even though the culture is available in the name of the resource files. So it has to be mentioned in both places.
Place the Satellite Assembly in the Appropriate Directory
Once the satellite assembly is created, physically copy the .dll to the following directory:
\MyApplication\bin\en-gb\MyApplication.Resources.DLL
This would have been identical if Visual Studio IDE had generated this file. Repeat this process for each languagein which you are interested.
Aren't We Done Yet? A Case for Multiple Resoruce Files
Having a single resource file can give raise to some issues in a large project. There will be contention for this resource file from multiple developers. This file can grow quite large, making it difficult to locate the resource keys in which you are interested. A good way to break this dependency is to encourage multiple resource files; one for each module. If there are common language keys, you can group them into a common module.
Following this recommendation, you will have multiple resource files, as follows:
\MyApplication\resources\files\CommonResources.resx
\MyApplication\resources\files\Module1Resources.resx
\MyApplication\resources\files\Module2Resources.resx
And you can define keys for these resources in a separate hierarchy, as follows:
\MyApplication\resources\keys\CommonKeys.cs
\MyApplication\resources\keysModule1Keys.cs
\MyApplication\resources\keys\Module2Keys.cs
The idea is that you can zip and send the following directory to a language specialist.
\MyApplication\resources\files\*.*
This language specialist will return to us a new directory, as follows:
Great Britain English version
\MyApplication\resources\files\en-gb\CommonResources.resx
\MyApplication\resources\files\en-gb\Module1Resources.resx
\MyApplication\resources\files\en-gb\Module2Resources.resx
Russian version
\MyApplication\resources\files\ru-RU\CommonResources.resx
\MyApplication\resources\files\ru-RU\Module1Resources.resx
\MyApplication\resources\files\ru-RU\Module2Resources.resx
Our goal is: given a directory worth of language dependent resource files, how can I create a satellite module for that language?
Designing a Batch Program For Converting Multiple Resource Files Into a Satellite Assembly
Much of the effort here is understanding al.exe and its options to create
multi-file processing for creating the satellite assembly. Let us reconsider
what we have done for a single file.
Al.exe /t:lib /embed:file1 /culture:en-gb /out:out-assembly.dll
Although it doesn't seem to be well documented, by experimentation you will find that the following command will work for multiple files:
Al.exe /t:lib /embed:file1 /embed:file2 /embed:file3 /culture:en-gb /out:out-assembly.dll
You will also see that it will get tiring very quickly, as the command line grows larger and larger.
Again, based on some meager documentation and a little experimentation, you will see that the following works as well:
Al.exe @responsefile.txt
where the response file has multiple lines, as follows:
/t:lib
/embed:file1
/embed:file2
/embed:file3
/culture:en-gb
/out:out-assembly.dll
So the answer lies in creating a batch file that can create this response file,
so that you invoke al.exe with this response file. One more final point before
presenting you with an annotated batch file: al.exe has an alternate option for
embed, called /link. An embed will embed the resource file directly into the
assembly, whereas link will merely place a reference. It seems to me that
this is similar to making an executable and making a .dll. When you link things,
you expect the resource files to be available for getting the resources out, whereas
embedding will pull in the resources. Either way for satellite assemblies,
/embed appears to be a good enough choice.
Annotated Batch Program For Creating a Satellite Assembly From a Directory's Worth of Resource Files
@rem****************************************************************************
@rem* Batch file for generating a satelite assembly
@rem* from a directory full of .resx files
@rem*
@rem* inputs
@rem* %1: language: hi-IN
@rem* %2: Your application name: SKLocalizationSample
@rem*
@rem* output:
@rem* will create SKLocalizationSample.resources.dll
@rem* in the same directory
@rem*
@rem****************************************************************************
@rem**************************************************
@rem* Set path for resgen.exe and al.exe
@rem**************************************************
@set path=%path%;
"C:\Program Files\Microsoft Visual Studio .NET\FrameworkSDK\Bin";
c:\winnt\microsoft.NET\framework\v1.0.3705
@rem**************************************************
@rem* Convert all .resx files to .resources files
@rem**************************************************
@del *.resources
@for %%f in (*.resx) do @resgen %%f
@rem**************************************************
@rem* Create text based command file for each resourc
@rem**************************************************
@rem del a.txt
@echo /t:lib > a.txt
@for %%f in (*.resources) do @echo /embed:%%f,%2.resources.files.%%f >> a.txt
@echo /culture:%1 >> a.txt @echo /out:%2.resources.dll >> a.txt
@rem**************************************************
@rem*
@rem* The generated input command file a.txt will look like this
@rem*
@rem* /t:lib
@rem* /embed:CommonResources.hi-in.resources,
@rem* SKLocalizationSample.resources.files.CommonResources.hi-in.resources
@rem* /embed:Common1Resources.hi-in.resources,
@rem* SKLocalizationSample.resources.files.Common1Resources.hi-in.resources
@rem* /embed:Common2Resources.hi-in.resources,
@rem* SKLocalizationSample.resources.files.Common2Resources.hi-in.resources
@rem* /embed:Common3Resources.hi-in.resources,
@rem* SKLocalizationSample.resources.files.Common3Resources.hi-in.resources
@rem* /culture:hi-in
@rem* /out:SKLocalizationSample.resources.dll
@rem*
@rem* Feed this file to al.exe
@rem**************************************************
@rem****************************
@rem* Create the satelite assembly
@rem****************************
del %2.resources.dll
al @a.txt
Satya Komatineni is the CTO at Indent, Inc. and the author of Aspire, an open source web development RAD tool for J2EE/XML.
Return to .NET DevCenter
-
What about ResourceManagers?
2006-08-19 11:57:12 DotNetDev [View]
-
Excellent Article
2006-06-24 06:00:29 prakash.guru [View]
-
namespace does matter
2005-09-01 13:47:48 MendoShano [View]
- Trackback from http://blogger/dottext/bbott/articles/1178.aspx
.NET Globalization
2005-06-02 11:55:02 [View]
-
Reading satellite assembly
2005-01-20 01:55:03 rbanbph [View]
- Trackback from http://weblogs.asp.net/guys/archive/2004/08/21/218116.aspx
Building Multilanguage application/s
2004-08-20 22:36:38 [View]
-
Wonder Ful !!!!
2004-04-05 22:11:43 rukminigopal [View]
-
Perfect
2004-01-14 15:36:43 anonymous2 [View]
-
a very good article
2003-12-23 05:20:40 anonymous2 [View]
-
Good Article...
2003-11-23 22:23:09 anonymous2 [View]
-
Génial
2003-11-13 08:00:37 le_yay [View]
-
Excellent Insight
2003-09-24 16:07:11 anonymous2 [View]
-
Great article!
2003-09-24 06:23:35 anonymous2 [View]
-
Wow... Thanks
2003-09-23 14:38:02 anonymous2 [View]
-
Solved the satellite assemblies problem
2003-06-16 00:46:07 anonymous2 [View]
-
very good one easly catch the topic
2003-05-15 08:39:52 anonymous2 [View]
-
Excellent, addressing real situation
2003-05-12 15:06:39 anonymous2 [View]
-
Thanks!
2003-04-10 21:11:29 anonymous2 [View]
-
How to handle short keys for different locales
2003-02-21 08:46:10 anonymous2 [View]
-
as
2002-11-12 00:21:58 anonymous2 [View]

