ModuleBuilder.DefineManifestResource Método
Definición
Importante
Parte de la información hace referencia a la versión preliminar del producto, que puede haberse modificado sustancialmente antes de lanzar la versión definitiva. Microsoft no otorga ninguna garantía, explícita o implícita, con respecto a la información proporcionada aquí.
Define un objeto binario grande (BLOB) que representa un recurso de manifiesto que se va a incrustar en el ensamblado dinámico.
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)
Parámetros
- name
- String
Nombre, que distingue entre mayúsculas y minúsculas, del recurso.
- stream
- Stream
Secuencia que contiene los bytes del recurso.
- attribute
- ResourceAttributes
Valor de enumeración que especifica si el recurso es público o privado.
Excepciones
name
es cadena de longitud cero.
El ensamblado dinámico que contiene el módulo actual es transitorio; es decir, no se especificó ningún nombre de archivo cuando se llamó a DefineDynamicModule(String, String).
Ejemplos
En el ejemplo siguiente se genera y se guarda un ensamblado dinámico denominado EmittedManifestResourceAssembly.exe
, que contiene un recurso no administrado incrustado. En el ejemplo se crea el ensamblado, que consta de un módulo, y se abre una secuencia de memoria para contener el recurso no administrado. A continuación, el código llama al DefineManifestResource método para definir el recurso.
Nota
Puede usar cualquier tipo de flujo para el recurso; por ejemplo, puede leer los datos binarios no administrados de un archivo.
En el ejemplo se define un tipo en el módulo dinámico con un Main
método y se genera MSIL para el cuerpo del método. Una vez generado el cuerpo del Main
método y creado el tipo, el ejemplo de código escribe cinco bytes en la secuencia asociada al recurso de manifiesto. Cuando se guarda el ensamblado, el recurso se anexa a él.
Después de ejecutar el ejemplo, puede ejecutar el ensamblado emitido. El código del método del Main
ensamblado emitido lee el recurso de manifiesto incrustado e imprime los valores de bytes en la consola. Puede usar el Ildasm.exe (Desensamblador de IL) para ver la información en el manifiesto del ensamblado.
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
'
Comentarios
Los recursos que se registran en el manifiesto del ensamblado pueden ser recursos administrados o blobs de recursos de manifiesto, y cada uno de ellos se puede incluir en el ensamblado mediante la vinculación o la inserción. Los cuatro escenarios son compatibles con ensamblados dinámicos.
Este método permite insertar un recurso de manifiesto BLOB en un ensamblado dinámico.
Para insertar un recurso administrado en el módulo de manifiesto de un ensamblado dinámico o en un módulo satélite, use el ModuleBuilder.DefineResource método para obtener un escritor de recursos y use el ResourceWriter.AddResource método para agregar el recurso.
Para vincular un recurso administrado a un ensamblado dinámico, use el AssemblyBuilder.DefineResource método para obtener un escritor de recursos y use el ResourceWriter.AddResource método para agregar el recurso vinculado.
Para vincular un recurso de manifiesto BLOB a un ensamblado dinámico, use el AssemblyBuilder.AddResourceFile método para agregar el recurso vinculado.
Además, un único recurso win32 se puede asociar a un ensamblado mediante el AssemblyBuilder.DefineUnmanagedResource método o el ModuleBuilder.DefineUnmanagedResource método . Este recurso no aparece en el manifiesto del ensamblado.