private static AssemblyBuilder BuildDynAssembly() { string myAsmFileName = "MyAsm.dll"; AppDomain myDomain = Thread.GetDomain(); AssemblyName myAsmName = new AssemblyName(); myAsmName.Name = "MyDynamicAssembly"; AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly( myAsmName, AssemblyBuilderAccess.RunAndSave); myAsmBuilder.AddResourceFile("MyResource", myResourceFileName); // To confirm that the resource file has been added to the manifest, // we will save the assembly as MyAsm.dll. You can view the manifest // and confirm the presence of the resource file by running // "ildasm MyAsm.dll" from the prompt in the directory where you executed // the compiled code. myAsmBuilder.Save(myAsmFileName); return(myAsmBuilder); }
public void EmbedResources(AssemblyBuilder builder) { if (EmbeddedResources != null) { foreach (string file in EmbeddedResources) { builder.AddResourceFile(file, file); // TODO: deal with resource IDs } } }
public void MixedSubclass() { AssemblyName assemblyName = new AssemblyName(); assemblyName.Name = "MyTestCSubclass1.dll"; AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave, dir_); ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name, assemblyName.Name, true); assemblyBuilder.AddResourceFile("B.subclass.hbm.xml", "B1.hbm.xml"); assemblyBuilder.AddResourceFile("A.subclass.hbm.xml", "A1.hbm.xml"); assemblyBuilder.AddResourceFile("C.subclass.hbm.xml", "C1.hbm.xml"); assemblyBuilder.Save(assemblyName.Name); Configuration cfg = new Configuration(); cfg.AddAssembly(Assembly.LoadFile(Path.Combine(dir_, assemblyName.Name))); // if no exception, success }
public void BottomUpJoined() { AssemblyName assemblyName = new AssemblyName(); assemblyName.Name = "MyTestB1.dll"; AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave); ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name, assemblyName.Name, true); assemblyBuilder.AddResourceFile("C.hbm.xml", "C1.hbm.xml"); assemblyBuilder.AddResourceFile("B.hbm.xml", "B1.hbm.xml"); assemblyBuilder.AddResourceFile("A.hbm.xml", "A1.hbm.xml"); assemblyBuilder.Save(assemblyName.Name); Configuration cfg = new Configuration(); cfg.AddAssembly(Assembly.LoadFile(dir_ + "/" + assemblyName.Name)); // if no exception, success }
/// <summary> /// Creates DLL assembly linked to policy file /// </summary> /// <param name="saveDirectory">Directory to save to</param> /// <returns>Success or failure</returns> protected bool CreateLinkedAssembly(DirectoryInfo saveDirectory) { OpenFileDialog keyDiag = new OpenFileDialog(); keyDiag.AddExtension = true; keyDiag.CheckFileExists = true; keyDiag.DefaultExt = ".snk"; keyDiag.Filter = "Key file (*.snk)|*.snk|All files (*.*)|*.*"; keyDiag.Title = "Load key file"; if (keyDiag.ShowDialog() == DialogResult.OK) { StrongNameKeyPair kp = null; using (FileStream fs = new FileStream(keyDiag.FileName, FileMode.Open, FileAccess.Read)) { kp = new StrongNameKeyPair(fs); fs.Close(); } string filename = string.Format("policy.{0}.{1}.{2}", this._nameDetails.Version.Major, this._nameDetails.Version.Minor, this._nameDetails.Name); AssemblyName assName = new AssemblyName(filename); assName.KeyPair = kp; assName.Version = new Version(this._nameDetails.Version.Major, this._nameDetails.Version.Minor); AssemblyBuilder build = System.Threading.Thread.GetDomain().DefineDynamicAssembly(assName, AssemblyBuilderAccess.Save, saveDirectory.FullName); if (this.KeyToString(build.GetName().GetPublicKeyToken()) != this._nameDetails.PublicKeyToken) { throw new System.Security.SecurityException("Provided key token does not match original assembly."); } build.AddResourceFile(filename + ".xml", filename + ".xml"); build.Save(filename + ".dll"); return(true); } return(false); }
public void bug78468(string assemblyFileName) { AssemblyName assemblyName = new AssemblyName(); assemblyName.Name = "bug78468b"; AssemblyBuilder ab = AppDomain.CurrentDomain .DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Save, Path.GetDirectoryName(assemblyFileName), AppDomain.CurrentDomain.Evidence); ab.AddResourceFile("read", "readme.txt"); ab.Save(Path.GetFileName(assemblyFileName)); Assembly assembly = Assembly.LoadFrom(assemblyFileName, AppDomain.CurrentDomain.Evidence); Assert.IsTrue(assembly.Location != string.Empty, "#B1"); string[] resNames = assembly.GetManifestResourceNames(); Assert.IsNotNull(resNames, "#B2"); Assert.AreEqual(1, resNames.Length, "#B3"); Assert.AreEqual("read", resNames[0], "#B4"); ManifestResourceInfo resInfo = assembly.GetManifestResourceInfo("read"); Assert.IsNotNull(resInfo, "#B5"); Assert.AreEqual("readme.txt", resInfo.FileName, "#B6"); Assert.IsNull(resInfo.ReferencedAssembly, "#B7"); Assert.AreEqual((ResourceLocation)0, resInfo.ResourceLocation, "#B8"); Stream s = assembly.GetManifestResourceStream("read"); Assert.IsNotNull(s, "#B9"); s.Close(); s = assembly.GetFile("readme.txt"); Assert.IsNotNull(s, "#B10"); s.Close(); }
public void EmbedResources() { // // Add Win32 resources // if (Compiler.Settings.Win32ResourceFile != null) { Builder.DefineUnmanagedResource(Compiler.Settings.Win32ResourceFile); } else { Builder.DefineVersionInfoResource(); } if (Compiler.Settings.Win32IconFile != null) { builder_extra.DefineWin32IconResource(Compiler.Settings.Win32IconFile); } if (Compiler.Settings.Resources != null) { if (Compiler.Settings.Target == Target.Module) { Report.Error(1507, "Cannot link resource file when building a module"); } else { int counter = 0; foreach (var res in Compiler.Settings.Resources) { if (!File.Exists(res.FileName)) { Report.Error(1566, "Error reading resource file `{0}'", res.FileName); continue; } if (res.IsEmbeded) { Stream stream; if (counter++ < 10) { stream = File.OpenRead(res.FileName); } else { // TODO: SRE API requires resource stream to be available during AssemblyBuilder::Save // we workaround it by reading everything into memory to compile projects with // many embedded resource (over 3500) references stream = new MemoryStream(File.ReadAllBytes(res.FileName)); } module.Builder.DefineManifestResource(res.Name, stream, res.Attributes); } else { Builder.AddResourceFile(res.Name, Path.GetFileName(res.FileName), res.Attributes); } } } } }
public void bug78468() { string assemblyFileNameA = Path.Combine(Path.GetTempPath(), "bug78468a.dll"); string resourceFileName = Path.Combine(Path.GetTempPath(), "readme.txt"); using (StreamWriter sw = File.CreateText(resourceFileName)) { sw.WriteLine("FOO"); sw.Close(); } try { AssemblyName assemblyName = new AssemblyName(); assemblyName.Name = "bug78468a"; AssemblyBuilder ab = AppDomain.CurrentDomain .DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Save, Path.GetTempPath(), AppDomain.CurrentDomain.Evidence); ab.AddResourceFile("read", "readme.txt"); ab.Save(Path.GetFileName(assemblyFileNameA)); Assembly assembly; using (FileStream fs = File.OpenRead(assemblyFileNameA)) { byte[] buffer = new byte[fs.Length]; fs.Read(buffer, 0, buffer.Length); assembly = Assembly.Load(buffer); fs.Close(); } Assert.AreEqual(string.Empty, assembly.Location, "#A1"); string[] resNames = assembly.GetManifestResourceNames(); Assert.IsNotNull(resNames, "#A2"); Assert.AreEqual(1, resNames.Length, "#A3"); Assert.AreEqual("read", resNames[0], "#A4"); ManifestResourceInfo resInfo = assembly.GetManifestResourceInfo("read"); Assert.IsNotNull(resInfo, "#A5"); Assert.AreEqual("readme.txt", resInfo.FileName, "#A6"); Assert.IsNull(resInfo.ReferencedAssembly, "#A7"); Assert.AreEqual((ResourceLocation)0, resInfo.ResourceLocation, "#A8"); try { assembly.GetManifestResourceStream("read"); Assert.Fail("#A9"); } catch (FileNotFoundException) { } try { assembly.GetFile("readme.txt"); Assert.Fail("#A10"); } catch (FileNotFoundException) { } string assemblyFileNameB = Path.Combine(Path.GetTempPath(), "bug78468b.dll"); AppDomain testDomain = CreateTestDomain(AppDomain.CurrentDomain.BaseDirectory, false); CrossDomainTester crossDomainTester = CreateCrossDomainTester(testDomain); try { crossDomainTester.bug78468(assemblyFileNameB); } finally { AppDomain.Unload(testDomain); File.Delete(assemblyFileNameB); } } finally { File.Delete(assemblyFileNameA); File.Delete(resourceFileName); } }
[Category("NotDotNet")] // path length can cause suprious failures public void TestGlobalData() { string name = "moduletest-assembly"; string fileName = name + ".dll"; AssemblyName assemblyName = new AssemblyName(); assemblyName.Name = name; AssemblyBuilder ab = Thread.GetDomain().DefineDynamicAssembly( assemblyName, AssemblyBuilderAccess.RunAndSave, TempFolder); string resfile = Path.Combine(TempFolder, "res"); using (StreamWriter sw = new StreamWriter(resfile)) { sw.WriteLine("FOO"); } ab.AddResourceFile("res", "res"); ModuleBuilder mb = ab.DefineDynamicModule(fileName, fileName); mb.DefineInitializedData("DATA", new byte [100], FieldAttributes.Public); mb.DefineInitializedData("DATA2", new byte [100], FieldAttributes.Public); mb.DefineInitializedData("DATA3", new byte [99], FieldAttributes.Public); mb.DefineUninitializedData("DATA4", 101, FieldAttributes.Public); mb.DefineInitializedData("DATA_PRIVATE", new byte [100], 0); mb.CreateGlobalFunctions(); ab.Save(fileName); Assembly assembly = Assembly.LoadFrom(Path.Combine(TempFolder, fileName)); Module module = assembly.GetLoadedModules()[0]; string[] expectedFieldNames = new string [] { "DATA", "DATA2", "DATA3", "DATA4" }; ArrayList fieldNames = new ArrayList(); foreach (FieldInfo fi in module.GetFields()) { fieldNames.Add(fi.Name); } AssertArrayEqualsSorted(expectedFieldNames, fieldNames.ToArray(typeof(string))); Assert.IsNotNull(module.GetField("DATA"), "#A1"); Assert.IsNotNull(module.GetField("DATA2"), "#A2"); Assert.IsNotNull(module.GetField("DATA3"), "#A3"); Assert.IsNotNull(module.GetField("DATA4"), "#A4"); Assert.IsNull(module.GetField("DATA_PRIVATE"), "#A5"); Assert.IsNotNull(module.GetField("DATA_PRIVATE", BindingFlags.NonPublic | BindingFlags.Static), "#A6"); // Check that these methods work correctly on resource modules Module m2 = assembly.GetModule("res"); Assert.IsNotNull(m2, "#B1"); Assert.AreEqual(0, m2.GetFields().Length, "#B2"); Assert.IsNull(m2.GetField("DATA"), "#B3"); Assert.IsNull(m2.GetField("DATA", BindingFlags.Public), "#B4"); }
internal static void GenerateAssembly(ResourceGenerationOptions options) { TranslationDictionariesReader dictionaries = new TranslationDictionariesReader(options.BamlStrings); string sourceAssemblyFullName = options.AssemblyFileName; // source assembly full path string outputAssemblyLocalName = System.IO.Path.GetFileName(options.OutputFileName); // output assembly name string moduleLocalName = GetAssemblyModuleLocalName( options.CultureInfo, System.IO.Path.GetFileName(outputAssemblyLocalName)); // the module name within the assmbly // get the source assembly Assembly sourceAssembly = options.SourceAssembly; CultureInfo cultureInfo = options.CultureInfo; // obtain the assembly name AssemblyName targetAssemblyNameObj = sourceAssembly.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 = cultureInfo; // we get a assembly builder AssemblyBuilder targetAssemblyBuilder = options.AppDomain.DefineDynamicAssembly( targetAssemblyNameObj, // name of the assembly AssemblyBuilderAccess.RunAndSave, // access rights System.IO.Path.GetDirectoryName(options.OutputFileName) // 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 sourceAssembly.GetManifestResourceNames()) { // get the resource location for the resource ResourceLocation resourceLocation = sourceAssembly.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, cultureInfo); // resource stream Stream resourceStream = sourceAssembly.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( System.IO.Path.GetDirectoryName(options.AssemblyFileName), 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")); }
//-------------------------------------------------- // The function follows Managed code parser // implementation. in the future, maybe they should // share the same code //-------------------------------------------------- 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 byte[] sourceContents = File.ReadAllBytes(sourceAssemblyFullName); Assembly srcAsm = Assembly.Load(sourceContents); // 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 ); Dictionary <string, IResourceWriter> resourceWriters = new Dictionary <string, IResourceWriter>(); // If the output assembly already exists, copy the embedded resources to the new assembly string existingAssemblyName = Path.Combine(Directory.GetCurrentDirectory(), options.CultureInfo.Name, outputAssemblyLocalName); if (File.Exists(existingAssemblyName)) { // Use ReadAllBytes() so we don't hold a file handle open, which would prevent // us from overwriting the file at the end. Assembly existingAssembly = Assembly.Load(File.ReadAllBytes(existingAssemblyName)); string[] existingResourceNames = existingAssembly.GetManifestResourceNames(); foreach (string resourceName in existingResourceNames) { ManifestResourceInfo info = existingAssembly.GetManifestResourceInfo(resourceName); if ((info.ResourceLocation & ResourceLocation.Embedded) != ResourceLocation.Embedded) { continue; } IResourceWriter writer; if (!resourceWriters.TryGetValue(resourceName, out writer)) { writer = moduleBuilder.DefineResource( resourceName, // resource name resourceName, // resource description ResourceAttributes.Public // visibilty of this resource to other assembly ); resourceWriters.Add(resourceName, writer); } Stream resourceStream = existingAssembly.GetManifestResourceStream(resourceName); using (ResourceReader reader = new ResourceReader(resourceStream)) { foreach (DictionaryEntry entry in reader) { string key = entry.Key.ToString(); object value = entry.Value; if (key.EndsWith(".baml")) { // Skip it, we're going to get this from the untranslated assembly continue; } writer.AddResource(key, value); } } } } // Add assembly info, trying to preserver original values as close as possible CopyAssemblyVersion(targetAssemblyBuilder, srcAsm); 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 (!resourceWriters.TryGetValue(targetResourceName, out writer)) { 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 ); } resourceWriters.Add(targetResourceName, writer); } // 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")); }
//-------------------------------------------------- // The function follows Managed code parser // implementation. in the future, maybe they should // share the same code //-------------------------------------------------- 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 ); // Add assembly info, trying to preserver original values as close as possible Action <Type, string> AddCustomStringAttribute = (Type type, string content) => { if (string.IsNullOrEmpty(content)) { return; } ConstructorInfo ctor = type.GetConstructor(new Type[] { typeof(string) }); targetAssemblyBuilder.SetCustomAttribute(new CustomAttributeBuilder(ctor, new object[] { content })); }; bool hasInformationalVersionAttr = false; object[] attrs = srcAsm.GetCustomAttributes(false); foreach (var attr in attrs) { if (attr is AssemblyCompanyAttribute cmp) { AddCustomStringAttribute(attr.GetType(), cmp.Company); continue; } if (attr is AssemblyCopyrightAttribute copy) { AddCustomStringAttribute(attr.GetType(), copy.Copyright); continue; } if (attr is AssemblyDescriptionAttribute da) { AddCustomStringAttribute(attr.GetType(), da.Description); continue; } if (attr is AssemblyFileVersionAttribute fva) { AddCustomStringAttribute(attr.GetType(), fva.Version); if (!hasInformationalVersionAttr) { // Also set AssemblyInformationalVersionAttribute, if not set already. // The unmanaged ProductVersion is taken from that attribute. AddCustomStringAttribute(typeof(AssemblyInformationalVersionAttribute), fva.Version); } continue; } if (attr is AssemblyInformationalVersionAttribute iva) { AddCustomStringAttribute(attr.GetType(), iva.InformationalVersion); hasInformationalVersionAttr = true; continue; } if (attr is AssemblyProductAttribute pa) { AddCustomStringAttribute(attr.GetType(), pa.Product); continue; } if (attr is AssemblyTitleAttribute ta) { AddCustomStringAttribute(attr.GetType(), ta.Title); continue; } if (attr is AssemblyTrademarkAttribute tm) { AddCustomStringAttribute(attr.GetType(), tm.Trademark); continue; } if (attr is AssemblyVersionAttribute va) { AddCustomStringAttribute(attr.GetType(), va.Version); continue; } } targetAssemblyBuilder.DefineVersionInfoResource(); // 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")); }
public static void AddResource(this AssemblyBuilder a, string key, string value) { File.WriteAllText(key, value); a.AddResourceFile(key, key); }