Programmatically embed non-localizable resource in assembly?

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Hi,

I would like to know how to programmatically embed a non-localizable
resource in assembly. I know I can do this in the IDE (using 'Embedded
Resource' Build Action) or using the C# compiler in the command line like
this:

csc /res:myImage.bmp /out:myassembly.exe /target:exe /recurse:*.cs

and I know I can programatically create the resource at runtime:

Assembly executingAssembly = GetExecutingAssembly();
Stream resourceStream = executingAssembly. GetManifestResourceStream(
"myImage.bmp" );
Bitmap image = new Bitmap(resourceStream);

But how I can programmatically generate an assembly that contains some
non-localizable resources, e.g like an XML file, a bitmap, and some arbitrary
binary content?

Thanks,
Notre
 
Little typo on the original post. I meant to say, I know how to
progammatically get the resource at runtime. I have no idea how to
programatically create it run time, if I did, I wouldnt' need to post the
question!
 
Hi,

Look for Reflection.Emit, and ICodeCompiler

The ICodeCompiler interface can be implemented for a specific compiler to
enable developers to programmatically compile assemblies from Code Document
Object Model (CodeDOM) compile units, strings containing source code, or
source code files.

Nicolas Guinet


The next 2 samples show how to programmatically generate an assembly
(.exe...)

#1
---------------------------------------------------

public static CompilerResults CompileCode(CodeDomProvider provider,
String sourceFile,
String exeFile)
{
// Configure a CompilerParameters that links System.dll
// and produces the specified executable file.
String[] referenceAssemblies = { "System.dll" };
CompilerParameters cp = new CompilerParameters(referenceAssemblies,
exeFile, false);

// Generate an executable rather than a DLL file.
cp.GenerateExecutable = true;

// Invoke compilation.
CompilerResults cr = provider.CompileAssemblyFromFile(cp, sourceFile);

// Return the results of compilation.
return cr;
}
#2 ---------------------------------------------------using System;using
System.Reflection;using System.Reflection.Emit;using System.Threading;public
class EmitHelloWorld{ static void Main(string[] args)
{ // create a dynamic assembly and module
AssemblyName assemblyName = new AssemblyName();
assemblyName.Name = "HelloWorld"; AssemblyBuilder
assemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(assemblyName,
AssemblyBuilderAccess.RunAndSave); ModuleBuilder module;
module = assemblyBuilder.DefineDynamicModule("HelloWorld.exe");
// create a new type to hold our Main method TypeBuilder
typeBuilder = module.DefineType("HelloWorldType", TypeAttributes.Public |
TypeAttributes.Class); // create the Main(string[]
args) method MethodBuilder methodbuilder =
typeBuilder.DefineMethod("Main", MethodAttributes.HideBySig |
MethodAttributes.Static | MethodAttributes.Public, typeof(void), new Type[]
{ typeof(string[]) }); // generate the IL for the
Main method ILGenerator ilGenerator =
methodbuilder.GetILGenerator(); ilGenerator.EmitWriteLine("hello,
world"); ilGenerator.Emit(OpCodes.Ret); // bake it
Type helloWorldType = typeBuilder.CreateType(); // run it
helloWorldType.GetMethod("Main").Invoke(null, new string[] {null});
// set the entry point for the application and save it
assemblyBuilder.SetEntryPoint(methodbuilder,
PEFileKinds.ConsoleApplication);
assemblyBuilder.Save("HelloWorld.exe"); }}
 
Hello Nicolas,

Thank you for your quick reply. I have reviewed your second example program
in some level of detail and I've scanned your first sample program. As I
understand it, what you are showing me is how to write a program that
generates an assembly, in both cases, an exe. This generated assembly can
actually be run by an end user (the second program is a console application
that displays hello, world).

I'm not sure if my original question was misleading, or perhaps I'm not
fullly appreciating your advice. What I'd like to do is generate an assembly
(a DLL rather than an EXE) that contains a number of embedded resources like
text files, XML files, bitmaps, etc. I listed a few ways to generate such an
assembly (with an embedded resource) in the original post. I'm not really
concerned that the assembly I generate can run; I just want to use it to
store some content which I can later query for its resources. I'm not sure
if what you've suggested so far (which has been pretty interesting in it's
own right) will help me do this, or whether there is a more straightforward
way to create a 'resource only' DLL (whose manifest resources I can query)?

Thanks again!
 
Thank you Peter. I'm very familiar with that post, as I was the one who
posed the question! :) A community member did give a response which answered
my question.

Now, the question is slightly different. In the earlier post, I was
creating a satellite assembly, so I was embedding culture specific content
(in that example, I was creating a french satellite resource assembly). In
this case, I want my resource to be neutral (not associated with any specific
culture). Furthermore, I would like to be able to use files as input
(probably in the form of some sort of stream) rather than encoding simple
(name, value) pairs as was demonstrated before.
 
Hi

Based on my researching, another way to add a resource file is to use the
AddResourceFile.
You may have a look at the link below which has some code sinppet.
AssemblyBuilder.AddResourceFile
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/
frlrfSystemReflectionEmitAssemblyBuilderClassAddResourceFileTopic2.asp

Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
 
Back
Top