satellite assemblies and localization

D

Dan

I am creating a c# class library project to be used by some exe clients.
This library needs to be localized for its text messages using satellite
resource-only assemblies; I have created the library with an embedded
resource for the default language and a sample satellite assembly with
strings for another language, plus a dummy test client application, but the
library always falls back to the default resources. Here's what I do: could
anyone tell me what's wrong?

1) I create a new c# class library project, named e.g. Localizable;
2) I add a resource (Strings.resx) file to this project and insert some
string resources in the default language (english): e.g. HELLO = "Hello";
3) outside this project, I 'manually' create another resx file e.g. for
italian named Strings.it.resx (with HELLO = "Ciao");
4) I run RESGEN Strings.it.resx to create Strings.it.resources;
5) I create a satellite assembly with AL:

al /t:lib /culture:it
/embed:Strings.it.resources,Localizable.Strings.it.resources
/out:Strings.resources.dll

6) I create a dummy test console application which uses a resource manager
to get the HELLO string first with the default culture then with the "it"
culture. Assuming that it's named Test.exe, in its directory I place the
Localizable dll and a subfolder (it) with the satellite assembly:
|- Test.exe
|- Localizable.dll
|- it\Strings.resources.dll

When I run Test, the strings always come in english. Could anyone give a
hint?
Here are the MANIFEST for the satellite assembly and the Localizable dll:

==== satellite assembly manifest ====
..assembly Strings.resources
{
.hash algorithm 0x00008004
.ver 0:0:0:0
.locale = (69 00 74 00 00 00 ) // i.t...
}
..mresource public Localizable.Strings.it.resources
{
}
..module Strings.resources.dll
// MVID: {CEB4DAA0-09ED-44AA-88D8-C53C495BD45F}
..imagebase 0x00400000
..subsystem 0x00000003
..file alignment 512
..corflags 0x00000001
// Image base: 0x06e60000

==== library assembly manifest ====
..assembly extern mscorlib
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) //
..z\V.4..
.ver 1:0:5000:0
}
..assembly Localizable
{
.... (snip) ...
}
..mresource public Localizable.Strings.resources
{
}
..module Localizable.dll
// MVID: {762391D6-143E-4337-9977-283F628D4491}
..imagebase 0x11000000
..subsystem 0x00000003
..file alignment 4096
..corflags 0x00000001
// Image base: 0x06e60000
 
R

Rajasi Saha

Does the class in test.exe live in a namespace? If so, then your resources
file must have the namespace in it and when you retrieve it, you also
retrieve it by the namespace. Example:

resgen strings.it.resx yournamespace.yourclass.it.resources
al /t:lib /embed:yournamespace.yourclass.it.resources /culture:it
/out:test.resources.dll

test -

CultureInfo it = new CultureInfo("it");
ResourceManager res = new ResourceManager("yournamespace.yourclass",
this.GetType().Assembly );
Console.WriteLine( res.GetString("HELLO", it));

rajasi
 
D

Dan

Thank U very much for your reply! anyway, I'm not sure I understand what you
mean, that is, I have 2 layers:

1) the DLL with my library which has 1 embedded resource and eventually
satellite assemblies for other languages;
2) any number of independent client apps using this DLL and belonging
toother projects, namespaces, etc.

Now, the test code which uses a ResourceManager to retrieve a string
resource is placed in the DLL itself (1), not in the EXE client application;
they are 2 different projects, and it is the DLL which needs some satellite
assemblies for localization. The EXE will simply call a function of the DLL
library, which in turn will eventually need to retrieve some string
resources to format response messages, e.g.:

--in the EXE (let's say the DLL lib is in the Localizable namespace and has
a Dummy class, and that the resource file is named Strings):
Localizable.Dummy dummy = new Localizable.Dummy();
Console.WriteLine(dummy.DoSomething());

-- in the DLL:
public class Dummy { ...
public string DoSomething()
{
CultureInfo it = new CultureInfo("it");
ResourceManager res = new ResourceManager("Localizable.Strings",
this.GetType().Assembly );
return res.GetString("HELLO", it);
} }

In this case, I should create the default resource name from the DLL
namespace (Localizable) + the resource filename (Strings):
Localizable.Strings(.resources), and add the LCID to the localized resource
name (Localizable.Strings.it(.resources)? Or this is not true? I have also
looked for a working sample, but I have found nothing with a localized DLL +
an independent EXE client... (it is always the case of a localized EXE, i.e.
just one "layer").
Thank you again...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top