Partager via


ModuleBuilder.DefineManifestResource Méthode

Définition

Définit un objet BLOB qui représente une ressource de manifeste à incorporer dans l'assembly dynamique.

public:
 void DefineManifestResource(System::String ^ name, System::IO::Stream ^ stream, System::Reflection::ResourceAttributes attribute);
public void DefineManifestResource (string name, System.IO.Stream stream, System.Reflection.ResourceAttributes attribute);
member this.DefineManifestResource : string * System.IO.Stream * System.Reflection.ResourceAttributes -> unit
Public Sub DefineManifestResource (name As String, stream As Stream, attribute As ResourceAttributes)

Paramètres

name
String

Nom qui respecte la casse de la ressource.

stream
Stream

Flux contenant les octets de la ressource.

attribute
ResourceAttributes

Valeur d'énumération qui spécifie si la ressource est publique ou privée.

Exceptions

name a la valeur null.

-ou-

stream a la valeur null.

name est une chaîne de longueur nulle.

L'assembly dynamique qui contient le module actuel est transitoire, ce qui signifie qu'aucun nom de fichier n'a été spécifié lorsque DefineDynamicModule(String, String) a été appelé.

Exemples

L’exemple suivant génère et enregistre un assembly dynamique nommé EmittedManifestResourceAssembly.exe, qui contient une ressource incorporée non managée. L’exemple crée l’assembly, qui se compose d’un module, et ouvre un flux de mémoire pour contenir la ressource non managée. Le code appelle ensuite la DefineManifestResource méthode pour définir la ressource.

Notes

Vous pouvez utiliser n’importe quel type de flux pour votre ressource ; par exemple, vous pouvez lire les données binaires non managées à partir d’un fichier.

L’exemple définit un type dans le module dynamique avec une Main méthode et génère MSIL pour le corps de la méthode. Une fois le corps de la Main méthode généré et le type créé, l’exemple de code écrit cinq octets dans le flux associé à la ressource manifeste. Lorsque l’assembly est enregistré, la ressource y est ajoutée.

Après avoir exécuté l’exemple, vous pouvez exécuter l’assembly émis. Le code dans la méthode de Main l’assembly émis lit la ressource de manifeste incorporée et imprime les valeurs d’octets dans la console. Vous pouvez utiliser le Ildasm.exe (désassembleur IL) pour afficher les informations dans le manifeste de l’assembly.

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

 */
Imports System.Reflection
Imports System.Reflection.Emit
Imports System.IO

Public Class Example
    
    Public Shared Sub Main() 

        ' Define a dynamic assembly with one module. The module
        ' name and the assembly name are the same.
        Dim asmName As New AssemblyName("EmittedManifestResourceAssembly")
        Dim asmBuilder As AssemblyBuilder = _
            AppDomain.CurrentDomain.DefineDynamicAssembly( _
                asmName, _
                AssemblyBuilderAccess.RunAndSave _
            )
        Dim modBuilder As ModuleBuilder = _
            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.
        Dim ms As 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.
        '
        Dim tb As TypeBuilder = modBuilder.DefineType("Example")
        Dim main As MethodBuilder = tb.DefineMethod( _
            "Main", _
            MethodAttributes.Public Or MethodAttributes.Static _
        )
        
        ' The Main method uses the Assembly type and the Stream
        ' type. 
        Dim asm As Type = GetType([Assembly])
        Dim str As Type = GetType(Stream)
        
        ' Get MethodInfo objects for the methods called by 
        ' Main.
        Dim getEx As MethodInfo = asm.GetMethod("GetExecutingAssembly")
        ' Use the overload of GetManifestResourceStream that 
        ' takes one argument, a string.
        Dim getMRS As MethodInfo = asm.GetMethod( _
            "GetManifestResourceStream", _
            New Type() {GetType(String)} _
        )
        Dim rByte As MethodInfo = str.GetMethod("ReadByte")
        ' Use the overload of WriteLine that writes an Int32.
        Dim write As MethodInfo = GetType(Console).GetMethod( _
            "WriteLine", _
            New Type() {GetType(Integer)} _
        )
        
        Dim ilg As ILGenerator = 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).
        Dim s As LocalBuilder = ilg.DeclareLocal(str)
        Dim b As LocalBuilder = ilg.DeclareLocal(GetType(Integer))
        
        ' 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, Nothing)
        ilg.Emit(OpCodes.Ldstr, "MyBinaryData")
        ilg.EmitCall(OpCodes.Callvirt, getMRS, Nothing)
        
        ' Store the Stream instance.
        ilg.Emit(OpCodes.Stloc_0)
        
        ' Create a label, and associate it with this point
        ' in the emitted code.
        Dim theLoop As Label = ilg.DefineLabel()
        ilg.MarkLabel(theLoop)
        
        ' 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, Nothing)
        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, Nothing)
        
        ' 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, theLoop)
        
        ' 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")
    
    End Sub 
End Class 

' This code example doesn't produce any output. The assembly it
' emits, EmittedManifestResourceAssembly.exe, produces the following
' output:
'
'105
'36
'74
'97
'109
'-1
'

Remarques

Les ressources enregistrées dans le manifeste de l’assembly peuvent être des ressources managées ou des objets blob de ressources de manifeste, et chacune d’elles peut être incluse dans l’assembly soit par liaison, soit par incorporation. Les quatre scénarios sont pris en charge pour les assemblys dynamiques.

  • Cette méthode vous permet d’incorporer un objet BLOB de ressource manifeste dans un assembly dynamique.

  • Pour incorporer une ressource managée dans le module manifeste d’un assembly dynamique ou dans un module satellite, utilisez la ModuleBuilder.DefineResource méthode pour obtenir un enregistreur de ressources et utilisez la ResourceWriter.AddResource méthode pour ajouter la ressource.

  • Pour lier une ressource managée à un assembly dynamique, utilisez la AssemblyBuilder.DefineResource méthode pour obtenir un enregistreur de ressources et utilisez la ResourceWriter.AddResource méthode pour ajouter la ressource liée.

  • Pour lier un objet BLOB de ressource manifeste à un assembly dynamique, utilisez la AssemblyBuilder.AddResourceFile méthode pour ajouter la ressource liée.

En outre, une seule ressource Win32 peut être attachée à un assembly à l’aide de la AssemblyBuilder.DefineUnmanagedResource méthode ou de la ModuleBuilder.DefineUnmanagedResource méthode . Cette ressource n’apparaît pas dans le manifeste de l’assembly.

S’applique à

Voir aussi