compile satellite assembly programmatically

T

Tom Regan

Can anyone provide sample code on how to compile a satellite assembly
(resource *.dll) programmatically using C# from Asp.Net?

The idea is to give end users the ability to customize their resource
files, then overwrite their satellite assembly with the new,
customized set of resources.

This is of course possible using the Assembly Linker (al.exe) and
Process.Start(). But is there a means to compile using a .Net class?

I've tried the System.CodeDom.Compiler object, but it does not seem to
work
for .resource files (it returns error CS0116 "A namespace does not
directly contain members such as fields or methods").
 
T

Tom Regan

Thanks for the tip, but that article describes how to compile
satellite assemblies using the assembly linker (al.exe).

That works, but it means having to use Process.Start(), which means
users must find the latest version of their machine.config file and
alter it to allow the asp.net process to execute from the command
line. Since machine.config comes new with each update of the .Net
framework, every time the framework is updated this will break. It is
a much better solution to compile programmatically using .Net classes.

I finally bumbled across a solution. If anyone else has any other code
that works I'd be interested in seeing it. I've not yet tried the
code below in a production environment, but it "works on my machine,"
as they say.

I'd be especially interested in learning if there is a way to load the
entire .resource file into the assembly in one step. The best means I
could find was the iterate through the .resource file and load each
item individually.

In the code below "AspTestingTool" is both the name of the the Asp.net
dll AND the name of the vs.net project used to create all satellite
assemblies. See http://msdn.microsoft.com/library/d...-us/cpguide/html/cpconresourcesinasppages.asp
for why this is vital.

In the code below the word "Global" is a convention we use to name
resource files. Its arbitrary.

In the code below I've already created a .resource file, now I am
iterating through the .resource file and adding each item into a new
satellite assembly, over-writing the old one.

using System.Threading;
using System.Reflection;
using System.Reflection.Emit;

private void CompileNewAssembly()
{
string sLang="de";
string sResource=Server.MapPath("").ToString()+"\\bin\\" + sLang +
"\\Global."+sLang+".resources";
string sPath=Server.MapPath("").ToString()+"\\bin\\" + sLang;

AssemblyName an = new AssemblyName();
an.Name = "AspTestingTool.resources";
an.CultureInfo = new CultureInfo(sLang);
an.CodeBase = String.Concat("file:///",sPath.ToString());

AppDomain domain = Thread.GetDomain();
AssemblyBuilder ab =
domain.DefineDynamicAssembly(an,AssemblyBuilderAccess.RunAndSave,sPath.ToString());
ModuleBuilder mb = ab.DefineDynamicModule("AspTestingTool.resources.dll","AspTestingTool.resources.dll",true);

IResourceWriter rw =
mb.DefineResource("AspTestingTool.Global."+sLang+".resources","Global."+sLang+".resources",ResourceAttributes.Public);

//there is no way to load an entire .resource file into the module.
must iterate each resource and add it individually
//fill resource reader with the .resource file
System.Resources.ResourceReader rsr = new
System.Resources.ResourceReader(sResource);

//need resourceset object for its GetObject function, to return
images
//this only need to retrieve images; if just getting strings could
use en.Value.ToString()
ResourceSet rs = new ResourceSet(rsr);

System.Drawing.Image img;
string sType=String.Empty;
IDictionaryEnumerator en = rsr.GetEnumerator();
while(en.MoveNext())
{
sType=en.Value.GetType().ToString();
switch(sType.ToLower())
{
case "system.string":
rw.AddResource(en.Key.ToString(),en.Value.ToString());
break;
case "system.drawing.bitmap":
img=(System.Drawing.Image)rs.GetObject(en.Key.ToString());
rw.AddResource(en.Key.ToString(),img);
break;
default:
break;
}

}
rsr.Close();

ab.Save("AspTestingTool.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