ModuleBuilder.DefineManifestResource 메서드
정의
중요
일부 정보는 릴리스되기 전에 상당 부분 수정될 수 있는 시험판 제품과 관련이 있습니다. Microsoft는 여기에 제공된 정보에 대해 어떠한 명시적이거나 묵시적인 보증도 하지 않습니다.
동적 어셈블리에 포함할 매니페스트 리소스를 나타내는 BLOB(Binary Large Object)를 정의합니다.
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)
매개 변수
- name
- String
리소스의 이름(대/소문자를 구분함)입니다.
- stream
- Stream
리소스의 바이트가 들어 있는 스트림입니다.
- attribute
- ResourceAttributes
리소스가 퍼블릭인지 아니면 프라이빗인지 지정하는 열거형 값입니다.
예외
name
이 빈 문자열입니다.
현재 모듈이 들어 있는 동적 어셈블리가 임시 어셈블리인 경우, 즉 DefineDynamicModule(String, String)을 호출할 때 파일 이름이 지정되지 않은 경우
예제
다음 예제에서는 포함된 관리되지 않는 리소스를 포함하는 라는 EmittedManifestResourceAssembly.exe
동적 어셈블리를 생성하고 저장합니다. 이 예제에서는 하나의 모듈로 구성된 어셈블리를 만들고 관리되지 않는 리소스를 포함하도록 메모리 스트림을 엽니다. 그런 다음, 코드는 메서드를 DefineManifestResource 호출하여 리소스를 정의합니다.
참고
리소스에 대해 모든 종류의 스트림을 사용할 수 있습니다. 예를 들어 파일에서 관리되지 않는 이진 데이터를 읽을 수 있습니다.
이 예제에서는 메서드를 사용하여 동적 모듈의 형식을 Main
정의하고 메서드 본문에 대한 MSIL을 생성합니다. 메서드의 Main
본문이 생성되고 형식이 생성된 후 코드 예제는 매니페스트 리소스와 연결된 스트림에 5바이트를 씁니다. 어셈블리가 저장되면 리소스가 추가됩니다.
예제를 실행한 후 내보낸 어셈블리를 실행할 수 있습니다. 내보낸 어셈블리의 Main
메서드에 있는 코드는 포함된 매니페스트 리소스를 읽고 바이트 값을 콘솔에 출력합니다.
Ildasm.exe(IL 디스어셈블러)를 사용하여 어셈블리 매니페스트의 정보를 볼 수 있습니다.
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
'
설명
어셈블리 매니페스트에 기록된 리소스는 관리되는 리소스 또는 매니페스트 리소스 BLOB일 수 있으며, 이러한 각 리소스는 연결 또는 포함을 통해 어셈블리에 포함될 수 있습니다. 네 가지 시나리오는 모두 동적 어셈블리에 대해 지원됩니다.
이 메서드를 사용하면 매니페스트 리소스 BLOB을 동적 어셈블리에 포함할 수 있습니다.
관리되는 리소스를 동적 어셈블리의 매니페스트 모듈 또는 위성 모듈에 포함하려면 메서드를 사용하여 ModuleBuilder.DefineResource 리소스 작성기를 가져와서 메서드를 사용하여 ResourceWriter.AddResource 리소스를 추가합니다.
관리되는 리소스를 동적 어셈블리에 연결하려면 메서드를 AssemblyBuilder.DefineResource 사용하여 리소스 작성기를 가져와서 메서드를 ResourceWriter.AddResource 사용하여 연결된 리소스를 추가합니다.
매니페스트 리소스 BLOB을 동적 어셈블리에 연결하려면 메서드를 AssemblyBuilder.AddResourceFile 사용하여 연결된 리소스를 추가합니다.
또한 메서드 또는 ModuleBuilder.DefineUnmanagedResource 메서드를 사용하여 AssemblyBuilder.DefineUnmanagedResource 단일 Win32 리소스를 어셈블리에 연결할 수 있습니다. 이 리소스는 어셈블리 매니페스트에 표시되지 않습니다.
적용 대상
추가 정보
.NET