Was this page helpful?
Your feedback about this content is important. Let us know what you think.
Additional feedback?
1500 characters remaining
Export (0) Print
Expand All

ModuleBuilder.DefineManifestResource Method

Defines a binary large object (BLOB) that represents a manifest resource to be embedded in the dynamic assembly.

Namespace:  System.Reflection.Emit
Assembly:  mscorlib (in mscorlib.dll)

public void DefineManifestResource(
	string name,
	Stream stream,
	ResourceAttributes attribute
)

Parameters

name
Type: System.String
The case-sensitive name for the resource.
stream
Type: System.IO.Stream
A stream that contains the bytes for the resource.
attribute
Type: System.Reflection.ResourceAttributes
An enumeration value that specifies whether the resource is public or private.

ExceptionCondition
ArgumentNullException

name is null.

-or-

stream is null.

ArgumentException

name is a zero-length string.

InvalidOperationException

The dynamic assembly that contains the current module is transient; that is, no file name was specified when DefineDynamicModule was called.

Resources that are recorded in the assembly manifest can be managed resources or manifest resource BLOBs, and each of these can be included in the assembly either by linking or by embedding. All four scenarios are supported for dynamic assemblies.

In addition, a single Win32 resource can be attached to an assembly by using the AssemblyBuilder.DefineUnmanagedResource method or the ModuleBuilder.DefineUnmanagedResource method. This resource does not appear in the assembly manifest.

The following example generates and saves a dynamic assembly named EmittedManifestResourceAssembly.exe, which contains an embedded unmanaged resource. The example creates the assembly, which consists of one module, and opens a memory stream to contain the unmanaged resource. The code then calls the DefineManifestResource method to define the resource.

NoteNote

You can use any kind of stream for your resource; for example, you can read the unmanaged binary data from a file.

The example defines a type in the dynamic module with a Main method, and generates MSIL for the method body. After the body for the Main method has been generated and the type has been created, the code example writes five bytes to the stream associated with the manifest resource. When the assembly is saved, the resource is appended to it.

After running the example, you can run the emitted assembly. The code in the emitted assembly's Main method reads the embedded manifest resource and prints the byte values to the console. You can use the Ildasm.exe (MSIL Disassembler) to view the information in the assembly manifest.


using System;
using System.Reflection;
using System.Reflection.Emit;
using System.IO;

public class Example
{
    public static void Main()
    {
        // Define a dynamic assembly with one module. The module
        // name and the assembly name are the same.
        AssemblyName asmName = 
            new AssemblyName("EmittedManifestResourceAssembly");
        AssemblyBuilder asmBuilder =
            AppDomain.CurrentDomain.DefineDynamicAssembly(
                asmName,
                AssemblyBuilderAccess.RunAndSave
            ); 
        ModuleBuilder modBuilder = asmBuilder.DefineDynamicModule(
            asmName.Name,
            asmName.Name + ".exe"
        );

        // Create a memory stream for the unmanaged resource data.
        // You can use any stream; for example, you might read the
        // unmanaged resource data from a binary file. It is not
        // necessary to put any data into the stream right now.
        MemoryStream ms = new MemoryStream(1024);

        // Define a public manifest resource with the name 
        // "MyBinaryData, and associate it with the memory stream.
        modBuilder.DefineManifestResource(
            "MyBinaryData",
            ms,
            ResourceAttributes.Public
        );

        // Create a type with a public static Main method that will
        // be the entry point for the emitted assembly. 
        //
        // The purpose of the Main method in this example is to read 
        // the manifest resource and display it, byte by byte.
        //
        TypeBuilder tb = modBuilder.DefineType("Example");
        MethodBuilder main = tb.DefineMethod("Main", 
            MethodAttributes.Public | MethodAttributes.Static
        );

        // The Main method uses the Assembly type and the Stream
        // type. 
        Type asm = typeof(Assembly);
        Type str = typeof(Stream);

        // Get MethodInfo objects for the methods called by 
        // Main.
        MethodInfo getEx = asm.GetMethod("GetExecutingAssembly");
        // Use the overload of GetManifestResourceStream that 
        // takes one argument, a string.
        MethodInfo getMRS = asm.GetMethod(
            "GetManifestResourceStream", 
            new Type[] {typeof(string)}
        );
        MethodInfo rByte = str.GetMethod("ReadByte");
        // Use the overload of WriteLine that writes an Int32.
        MethodInfo write = typeof(Console).GetMethod(
            "WriteLine", 
            new Type[] {typeof(int)}
        );

        ILGenerator ilg = main.GetILGenerator();

        // Main uses two local variables: the instance of the
        // stream returned by GetManifestResourceStream, and 
        // the value returned by ReadByte. The load and store 
        // instructions refer to these locals by position
        // (0 and 1).
        LocalBuilder s = ilg.DeclareLocal(str);
        LocalBuilder b = ilg.DeclareLocal(typeof(int));

        // Call the static Assembly.GetExecutingAssembly() method,
        // which leaves the assembly instance on the stack. Push the
        // string name of the resource on the stack, and call the
        // GetManifestResourceStream(string) method of the assembly
        // instance.
        ilg.EmitCall(OpCodes.Call, getEx, null);
        ilg.Emit(OpCodes.Ldstr, "MyBinaryData");
        ilg.EmitCall(OpCodes.Callvirt, getMRS, null);

        // Store the Stream instance.
        ilg.Emit(OpCodes.Stloc_0);

        // Create a label, and associate it with this point
        // in the emitted code.
        Label loop = ilg.DefineLabel();
        ilg.MarkLabel(loop);

        // Load the Stream instance onto the stack, and call
        // its ReadByte method. The return value is on the
        // stack now; store it in location 1 (variable b).
        ilg.Emit(OpCodes.Ldloc_0);
        ilg.EmitCall(OpCodes.Callvirt, rByte, null);
        ilg.Emit(OpCodes.Stloc_1);

        // Load the value on the stack again, and call the
        // WriteLine method to print it.
        ilg.Emit(OpCodes.Ldloc_1);
        ilg.EmitCall(OpCodes.Call, write, null);

        // Load the value one more time; load -1 (minus one)  
        // and compare the two values. If return value from
        // ReadByte was not -1, branch to the label 'loop'.
        ilg.Emit(OpCodes.Ldloc_1);
        ilg.Emit(OpCodes.Ldc_I4_M1);
        ilg.Emit(OpCodes.Ceq);
        ilg.Emit(OpCodes.Brfalse_S, loop);

        // When all the bytes in the stream have been read,
        // return. This is the end of Main.
        ilg.Emit(OpCodes.Ret);

        // Create the type "Example" in the dynamic assembly.
        tb.CreateType();

        // Because the manifest resource was added as an open
        // stream, the data can be written at any time, right up
        // until the assembly is saved. In this case, the data
        // consists of five bytes.
        ms.Write(new byte[] { 105, 36, 74, 97, 109 }, 0, 5);
        ms.SetLength(5);

        // Set the Main method as the entry point for the 
        // assembly, and save the assembly. The manifest resource
        // is read from the memory stream, and appended to the
        // end of the assembly. You can open the assembly with
        // Ildasm and view the resource header for "MyBinaryData".
        asmBuilder.SetEntryPoint(main);
	asmBuilder.Save(asmName.Name + ".exe");

        Console.WriteLine("Now run EmittedManifestResourceAssembly.exe");
    }
}

/* This code example doesn't produce any output. The assembly it
   emits, EmittedManifestResourceAssembly.exe, produces the following
   output:

105
36
74
97
109
-1

 */


.NET Framework

Supported in: 4, 3.5, 3.0, 2.0

.NET Framework Client Profile

Supported in: 4, 3.5 SP1

Windows 7, Windows Vista SP1 or later, Windows XP SP3, Windows XP SP2 x64 Edition, Windows Server 2008 (Server Core not supported), Windows Server 2008 R2 (Server Core supported with SP1 or later), Windows Server 2003 SP2

The .NET Framework does not support all versions of every platform. For a list of the supported versions, see .NET Framework System Requirements.

Community Additions

ADD
Show:
© 2015 Microsoft