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");
}