ModuleBuilder.DefineManifestResource Metodo

Definizione

Definisce un oggetto binario di grandi dimensioni (BLOB) che rappresenta una risorsa del manifesto da incorporare nell'assembly dinamico.

C#
public void DefineManifestResource(string name, System.IO.Stream stream, System.Reflection.ResourceAttributes attribute);

Parametri

name
String

Nome della risorsa con distinzione tra maiuscole e minuscole.

stream
Stream

Flusso che contiene i byte della risorsa.

attribute
ResourceAttributes

Valore di enumerazione che specifica se la risorsa è pubblica o privata.

Eccezioni

name è null.

-oppure-

stream è null.

name è una stringa di lunghezza zero.

L'assembly dinamico che contiene il modulo corrente è temporaneo, ovvero non è stato specificato alcun nome file quando è stato chiamato il metodo DefineDynamicModule(String, String).

Esempio

Nell'esempio seguente viene generato e salvato un assembly dinamico denominato EmittedManifestResourceAssembly.exe, che contiene una risorsa non gestita incorporata. L'esempio crea l'assembly, costituito da un modulo e apre un flusso di memoria per contenere la risorsa non gestita. Il codice chiama quindi il DefineManifestResource metodo per definire la risorsa.

Nota

È possibile usare qualsiasi tipo di flusso per la risorsa; Ad esempio, è possibile leggere i dati binari non gestiti da un file.

L'esempio definisce un tipo nel modulo dinamico con un Main metodo e genera MSIL per il corpo del metodo. Dopo aver generato il corpo del Main metodo e il tipo è stato creato, l'esempio di codice scrive cinque byte nel flusso associato alla risorsa manifesto. Quando l'assembly viene salvato, la risorsa viene aggiunta a essa.

Dopo aver eseguito l'esempio, è possibile eseguire l'assembly generato. Il codice nel metodo dell'assembly Main generato legge la risorsa manifesto incorporata e stampa i valori di byte nella console. È possibile usare il Ildasm.exe (IL Disassembler) per visualizzare le informazioni nel manifesto dell'assembly.

C#
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

 */

Commenti

Le risorse registrate nel manifesto dell'assembly possono essere risorse gestite o BLOB di risorse manifesto e ognuna di queste può essere inclusa nell'assembly tramite collegamento o incorporamento. Tutti e quattro gli scenari sono supportati per gli assembly dinamici.

  • Questo metodo consente di incorporare un BLOB di risorse manifesto in un assembly dinamico.

  • Per incorporare una risorsa gestita nel modulo manifesto di un assembly dinamico o in un modulo satellite, usare il metodo per ottenere un writer di risorse e usare il ModuleBuilder.DefineResourceResourceWriter.AddResource metodo per aggiungere la risorsa.

  • Per collegare una risorsa gestita in un assembly dinamico, usare il metodo per ottenere un writer di risorse e usare il AssemblyBuilder.DefineResourceResourceWriter.AddResource metodo per aggiungere la risorsa collegata.

  • Per collegare un BLOB di risorse manifesto in un assembly dinamico, usare il AssemblyBuilder.AddResourceFile metodo per aggiungere la risorsa collegata.

Inoltre, una singola risorsa Win32 può essere collegata a un assembly usando il metodo o il AssemblyBuilder.DefineUnmanagedResourceModuleBuilder.DefineUnmanagedResource metodo . Questa risorsa non viene visualizzata nel manifesto dell'assembly.

Si applica a

Prodotto Versioni
.NET Framework 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1

Vedi anche