private static void GenerateAssembly(LocBamlOptions options, TranslationDictionariesReader dictionaries)
{
// there are many names to be used when generating an assembly
string sourceAssemblyFullName = options.Input; // source assembly full path
string outputAssemblyDir = options.Output; // output assembly directory
string outputAssemblyLocalName = GetOutputFileName(options); // output assembly name
string moduleLocalName = GetAssemblyModuleLocalName(options, outputAssemblyLocalName); // the module name within the assmbly
// get the source assembly
Assembly srcAsm = Assembly.LoadFrom(sourceAssemblyFullName);
// obtain the assembly name
AssemblyName targetAssemblyNameObj = srcAsm.GetName();
// store the culture info of the source assembly
CultureInfo srcCultureInfo = targetAssemblyNameObj.CultureInfo;
// update it to use it for target assembly
targetAssemblyNameObj.Name = Path.GetFileNameWithoutExtension(outputAssemblyLocalName);
targetAssemblyNameObj.CultureInfo = options.CultureInfo;
// we get a assembly builder
AssemblyBuilder targetAssemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(
targetAssemblyNameObj, // name of the assembly
AssemblyBuilderAccess.RunAndSave, // access rights
outputAssemblyDir // storage dir
);
// we create a module builder for embeded resource modules
ModuleBuilder moduleBuilder = targetAssemblyBuilder.DefineDynamicModule(
moduleLocalName,
outputAssemblyLocalName
);
options.WriteLine(StringLoader.Get("GenerateAssembly"));
// now for each resource in the assembly
foreach (string resourceName in srcAsm.GetManifestResourceNames())
{
// get the resource location for the resource
ResourceLocation resourceLocation = srcAsm.GetManifestResourceInfo(resourceName).ResourceLocation;
// if this resource is in another assemlby, we will skip it
if ((resourceLocation & ResourceLocation.ContainedInAnotherAssembly) != 0)
{
continue; // in resource assembly, we don't have resource that is contained in another assembly
}
// gets the neutral resource name, giving it the source culture info
string neutralResourceName = GetNeutralResModuleName(resourceName, srcCultureInfo);
// gets the target resource name, by giving it the target culture info
string targetResourceName = GetCultureSpecificResourceName(neutralResourceName, options.CultureInfo);
// resource stream
Stream resourceStream = srcAsm.GetManifestResourceStream(resourceName);
// see if it is a .resources
if (neutralResourceName.ToLower(CultureInfo.InvariantCulture).EndsWith(".resources"))
{
// now we think we have resource stream
// get the resource writer
IResourceWriter writer;
// check if it is a embeded assembly
if ((resourceLocation & ResourceLocation.Embedded) != 0)
{
// gets the resource writer from the module builder
writer = moduleBuilder.DefineResource(
targetResourceName, // resource name
targetResourceName, // resource description
ResourceAttributes.Public // visibilty of this resource to other assembly
);
}
else
{
// it is a standalone resource, we get the resource writer from the assembly builder
writer = targetAssemblyBuilder.DefineResource(
targetResourceName, // resource name
targetResourceName, // description
targetResourceName, // file name to save to
ResourceAttributes.Public // visibility of this resource to other assembly
);
}
// get the resource reader
IResourceReader reader = new ResourceReader(resourceStream);
// generate the resources
GenerateResourceStream(options, resourceName, reader, writer, dictionaries);
// we don't call writer.Generate() or writer.Close() here
// because the AssemblyBuilder will call them when we call Save() on it.
}
else
{
// else it is a stand alone untyped manifest resources.
string extension = Path.GetExtension(targetResourceName);
string fullFileName = Path.Combine(outputAssemblyDir, targetResourceName);
// check if it is a .baml, case-insensitive
if (string.Compare(extension, ".baml", true, CultureInfo.InvariantCulture) == 0)
{
// try to localized the the baml
// find the resource dictionary
BamlLocalizationDictionary dictionary = dictionaries[resourceName];
// if it is null, just create an empty dictionary.
if (dictionary != null)
{
// it is a baml stream
using (Stream output = File.OpenWrite(fullFileName))
{
options.Write(" ");
options.WriteLine(StringLoader.Get("GenerateStandaloneBaml", fullFileName));
GenerateBamlStream(resourceStream, output, dictionary, options);
options.WriteLine(StringLoader.Get("Done"));
}
}
else
{
// can't find localization of it, just copy it
GenerateStandaloneResource( fullFileName, resourceStream);
}
}
else
{
// it is an untyped resource stream, just copy it
GenerateStandaloneResource( fullFileName, resourceStream);
}
// now add this resource file into the assembly
targetAssemblyBuilder.AddResourceFile(
targetResourceName, // resource name
targetResourceName, // file name
ResourceAttributes.Public // visibility of the resource to other assembly
);
}
}
// at the end, generate the assembly
targetAssemblyBuilder.Save(outputAssemblyLocalName);
options.WriteLine(StringLoader.Get("DoneGeneratingAssembly"));
}