Satellite assemblies and strong names

M

Mário Sobral

Hi,

I created an assembly (let's call it assembly (B)) that returns a localized
resource for a given key (similar to System.Globalization.ResourceManager).
I checks if the caller assembly (let's call it assembly (A)) has a satellite
assembly (let's call it assembly (sA)) with localized resources.
If it exists, it gets the resource with the given key and returns it,
otherwise it reads information from a support database and dinamically
compiles a new satellite assembly and places it in the calling assembly's
respective folder, and then returns the requested resource.
It is all working fine, but once I started signing the assemblies (A) and
(B) with strong names, I got a dreadful error:

"The located assembly's manifest definition with name '(A).resources' does
not match the assembly reference."

Naturally, I assume I need to sign (sA) with strong name too, so I tried to
do it when I create the satellite assembly, but so far I have been
unsuccessful. Below are my efforts to provide (sA) with a strong name
dinamically:

----------- 1st Try -----------------------------
AssemblyName assName = new AssemblyName();
assName.Name = assemblyName + ".resources";
assName.CultureInfo = new CultureInfo(culture);

// ------ Sign the satellite assembly -----
FileStream fs = null;
StrongNameKeyPair kp = null;

try
{
fs = new FileStream(@"MyKey.snk", FileMode.Open, FileAccess.Read,
FileShare.Read);
kp = new StrongNameKeyPair(fs);
}
catch (FileNotFoundException)
{
Diag.Trace.Write("Strong name key pair file not found.");
throw;
}
catch(Exception ex)
{
Diag.Trace.Write("Error obtaining strong name key pair from file." +
fs.Name);
throw;
}
finally
{
if (fs != null)
{
fs.Close();
}
}

assName.KeyPair = kp;



----------- 2nd Try -----------------------------
try
{
FileStream publicKeyStream = File.Open("MyKey.snk",
FileMode.Open,FileAccess.Read, FileShare.Read);
byte[] publicKey = new byte[publicKeyStream.Length];
publicKeyStream.Read(publicKey, 0, (int)publicKeyStream.Length);
// Provide the assembly with a public key.
assName.SetPublicKey(publicKey);
}
catch(Exception ex)
{
throw;
}
 
G

Guest

Do early signing as opposed to late signing of the assembly. The framework is going to verify the signature at load time. Try including this line in your assemblyinfo.cs class.

[assembly: AssemblyKeyFile(@"my.snk")]

Change the path of course! And take out your signing code.

jason.
 
M

Mário Sobral

Hi !

Thanks for the suggestion, but my problem is that the satellite assembly is
being generated dinamically with System.Reflection.Emit. That's why it
should be signed dinamically also.

There is a method that reads the resources associated to a certain calling
assembly from a database, then generate the satellite assembly for that
calling assembly:

----------------------------------------------------------------------------
-------
AssemblyName assName = new AssemblyName();

assName.Name = assemblyName + ".resources";

assName.CultureInfo = new CultureInfo(culture);

assName.Version = new System.Version(1,0,0,0);

AssemblyBuilder assBuilder =
Thread.GetDomain().DefineDynamicAssembly(assName,
AssemblyBuilderAccess.RunAndSave,outputPath);

[Code to sign the satellite assebly here (?)]
ModuleBuilder modBuilder = assBuilder.DefineDynamicModule(assName.Name +
".dll", assName.Name + ".dll", true);


IResourceWriter resourceWriter = modBuilder.DefineResource(assemblyName +
"." + culture + ".resources",

assemblyName + "." + culture + ".resources",

ResourceAttributes.Public);

resStream.Seek(0,System.IO.SeekOrigin.Begin);

// We need ResourceSet object for its GetObject function, to get images and
other binary objects.

System.Resources.ResourceReader reader = new
System.Resources.ResourceReader(resStream);

ResourceSet rs = new ResourceSet(reader);

IDictionaryEnumerator resourcesEnumerator = reader.GetEnumerator();

while(resourcesEnumerator.MoveNext())

{

if(resourcesEnumerator.Value.GetType().ToString().ToLower() ==
"system.string")

{

resourceWriter.AddResource(resourcesEnumerator.Key.ToString(),resourcesEnume
rator.Value.ToString());

}

else

{

resourceWriter.AddResource(resourcesEnumerator.Key.ToString(),rs.GetObject(r
esourcesEnumerator.Key.ToString()));

}

}

reader.Close();

rs.Close();


Diag.Trace.Write("Saving assembly to: " + assemblyPath + "\\" + assemblyName
+ ".resources.dll");

assBuilder.Save(assemblyName + ".resources.dll");



 

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