PersistedAssemblyBuilder Class
Definition
Important
Some information relates to prerelease product that may be substantially modified before it’s released. Microsoft makes no warranties, express or implied, with respect to the information provided here.
Provides an AssemblyBuilder implementation that can persist an assembly to a disk or stream.
public ref class PersistedAssemblyBuilder sealed : System::Reflection::Emit::AssemblyBuilder
public sealed class PersistedAssemblyBuilder : System.Reflection.Emit.AssemblyBuilder
type PersistedAssemblyBuilder = class
inherit AssemblyBuilder
Public NotInheritable Class PersistedAssemblyBuilder
Inherits AssemblyBuilder
- Inheritance
Remarks
The AssemblyBuilder.Save API wasn't originally ported to .NET (Core) because the implementation depended heavily on Windows-specific native code that also wasn't ported. .NET 9 added the PersistedAssemblyBuilder class, which provides a fully managed Reflection.Emit implementation that supports saving. This implementation has no dependency on the pre-existing, runtime-specific Reflection.Emit implementation. That is, now there are two different implementations in .NET: runnable and persisted. To run the persisted assembly, first save it into a memory stream or a file, then load it back.
Before PersistedAssemblyBuilder, you could only run a generated assembly and not save it. Since the assembly was in-memory only, it was difficult to debug. Advantages of saving a dynamic assembly to a file are:
- You can verify the generated assembly with tools such as ILVerify, or decompile and manually examine it with tools such as ILSpy.
- The saved assembly can be loaded directly, without needing to compile again, which can decrease application startup time.
To create a PersistedAssemblyBuilder instance, use the PersistedAssemblyBuilder(AssemblyName, Assembly, IEnumerable<CustomAttributeBuilder>) constructor. The coreAssembly parameter is used to resolve base runtime types and can be used for resolving reference assembly versioning:
If
Reflection.Emitis used to generate an assembly that will only be executed on the same runtime version as the runtime version that the compiler is running on (typically in-proc), the core assembly can be simplytypeof(object).Assembly. The following example demonstrates how to create and save an assembly to a stream and run it with the current runtime assembly:public static void CreateSaveAndRunAssembly() { PersistedAssemblyBuilder ab = new(new AssemblyName("MyAssembly"), typeof(object).Assembly); ModuleBuilder mob = ab.DefineDynamicModule("MyModule"); TypeBuilder tb = mob.DefineType( "MyType", TypeAttributes.Public | TypeAttributes.Class); MethodBuilder meb = tb.DefineMethod( "SumMethod", MethodAttributes.Public | MethodAttributes.Static, typeof(int), [typeof(int), typeof(int)]); ILGenerator il = meb.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Add); il.Emit(OpCodes.Ret); tb.CreateType(); using var stream = new MemoryStream(); ab.Save(stream); // Or pass filename to save into a file. stream.Seek(0, SeekOrigin.Begin); Assembly assembly = AssemblyLoadContext.Default.LoadFromStream(stream); MethodInfo method = assembly.GetType("MyType").GetMethod("SumMethod"); Console.WriteLine(method.Invoke(null, [5, 10])); }If
Reflection.Emitis used to generate an assembly that targets a specific TFM, open the reference assemblies for the given TFM usingMetadataLoadContextand use the value of the MetadataLoadContext.CoreAssembly property forcoreAssembly. This value allows the generator to run on one .NET runtime version and target a different .NET runtime version. You should use types returned by theMetadataLoadContextinstance when referencing core types. For example, instead oftypeof(int), find theSystem.Int32type inMetadataLoadContext.CoreAssemblyby name:public static void CreatePersistedAssemblyBuilderCoreAssemblyWithMetadataLoadContext(string refAssembliesPath) { PathAssemblyResolver resolver = new(Directory.GetFiles(refAssembliesPath, "*.dll")); using MetadataLoadContext context = new(resolver); Assembly coreAssembly = context.CoreAssembly; PersistedAssemblyBuilder ab = new(new AssemblyName("MyDynamicAssembly"), coreAssembly); TypeBuilder typeBuilder = ab.DefineDynamicModule("MyModule").DefineType("Test", TypeAttributes.Public); MethodBuilder methodBuilder = typeBuilder.DefineMethod("Method", MethodAttributes.Public, coreAssembly.GetType(typeof(int).FullName), Type.EmptyTypes); // .. add members and save the assembly }
Set entry point for an executable
To set the entry point for an executable or to set other options for the assembly file, you can call the public MetadataBuilder GenerateMetadata(out BlobBuilder ilStream, out BlobBuilder mappedFieldData) method and use the populated metadata to generate the assembly with desired options, for example:
public static void SetEntryPoint()
{
PersistedAssemblyBuilder ab = new(new AssemblyName("MyAssembly"), typeof(object).Assembly);
TypeBuilder tb = ab.DefineDynamicModule("MyModule").DefineType("MyType", TypeAttributes.Public | TypeAttributes.Class);
// ...
MethodBuilder entryPoint = tb.DefineMethod("Main", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static);
ILGenerator il2 = entryPoint.GetILGenerator();
// ...
il2.Emit(OpCodes.Ret);
tb.CreateType();
MetadataBuilder metadataBuilder = ab.GenerateMetadata(out BlobBuilder ilStream, out BlobBuilder fieldData);
ManagedPEBuilder peBuilder = new(
header: PEHeaderBuilder.CreateExecutableHeader(),
metadataRootBuilder: new MetadataRootBuilder(metadataBuilder),
ilStream: ilStream,
mappedFieldData: fieldData,
entryPoint: MetadataTokens.MethodDefinitionHandle(entryPoint.MetadataToken));
BlobBuilder peBlob = new();
peBuilder.Serialize(peBlob);
// Create the executable:
using FileStream fileStream = new("MyAssembly.exe", FileMode.Create, FileAccess.Write);
peBlob.WriteContentTo(fileStream);
}
Emit symbols and generate PDB
The symbols metadata is populated into the pdbBuilder out parameter when you call the GenerateMetadata(BlobBuilder, BlobBuilder) method on a PersistedAssemblyBuilder instance. To create an assembly with a portable PDB:
- Create ISymbolDocumentWriter instances with the ModuleBuilder.DefineDocument(String, Guid, Guid, Guid) method. While emitting the method's IL, also emit the corresponding symbol info.
- Create a PortablePdbBuilder instance using the
pdbBuilderinstance produced by the GenerateMetadata(BlobBuilder, BlobBuilder) method. - Serialize the
PortablePdbBuilderinto a Blob, and write theBlobinto a PDB file stream (only if you're generating a standalone PDB). - Create a DebugDirectoryBuilder instance and add a DebugDirectoryBuilder.AddCodeViewEntry (standalone PDB) or DebugDirectoryBuilder.AddEmbeddedPortablePdbEntry.
- Set the optional
debugDirectoryBuilderargument when creating the PEBuilder instance.
The following example shows how to emit symbol info and generate a PDB file.
static void GenerateAssemblyWithPdb()
{
PersistedAssemblyBuilder ab = new PersistedAssemblyBuilder(new AssemblyName("MyAssembly"), typeof(object).Assembly);
ModuleBuilder mb = ab.DefineDynamicModule("MyModule");
TypeBuilder tb = mb.DefineType("MyType", TypeAttributes.Public | TypeAttributes.Class);
MethodBuilder mb1 = tb.DefineMethod("SumMethod", MethodAttributes.Public | MethodAttributes.Static, typeof(int), [typeof(int), typeof(int)]);
ISymbolDocumentWriter srcDoc = mb.DefineDocument("MySourceFile.cs", SymLanguageType.CSharp);
ILGenerator il = mb1.GetILGenerator();
LocalBuilder local = il.DeclareLocal(typeof(int));
local.SetLocalSymInfo("myLocal");
il.MarkSequencePoint(srcDoc, 7, 0, 7, 11);
...
il.Emit(OpCodes.Ret);
MethodBuilder entryPoint = tb.DefineMethod("Main", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static);
ILGenerator il2 = entryPoint.GetILGenerator();
il2.BeginScope();
...
il2.EndScope();
...
tb.CreateType();
MetadataBuilder metadataBuilder = ab.GenerateMetadata(out BlobBuilder ilStream, out _, out MetadataBuilder pdbBuilder);
MethodDefinitionHandle entryPointHandle = MetadataTokens.MethodDefinitionHandle(entryPoint.MetadataToken);
DebugDirectoryBuilder debugDirectoryBuilder = GeneratePdb(pdbBuilder, metadataBuilder.GetRowCounts(), entryPointHandle);
ManagedPEBuilder peBuilder = new ManagedPEBuilder(
header: new PEHeaderBuilder(imageCharacteristics: Characteristics.ExecutableImage, subsystem: Subsystem.WindowsCui),
metadataRootBuilder: new MetadataRootBuilder(metadataBuilder),
ilStream: ilStream,
debugDirectoryBuilder: debugDirectoryBuilder,
entryPoint: entryPointHandle);
BlobBuilder peBlob = new BlobBuilder();
peBuilder.Serialize(peBlob);
using var fileStream = new FileStream("MyAssembly.exe", FileMode.Create, FileAccess.Write);
peBlob.WriteContentTo(fileStream);
}
static DebugDirectoryBuilder GeneratePdb(MetadataBuilder pdbBuilder, ImmutableArray<int> rowCounts, MethodDefinitionHandle entryPointHandle)
{
BlobBuilder portablePdbBlob = new BlobBuilder();
PortablePdbBuilder portablePdbBuilder = new PortablePdbBuilder(pdbBuilder, rowCounts, entryPointHandle);
BlobContentId pdbContentId = portablePdbBuilder.Serialize(portablePdbBlob);
// In case saving PDB to a file
using FileStream fileStream = new FileStream("MyAssemblyEmbeddedSource.pdb", FileMode.Create, FileAccess.Write);
portablePdbBlob.WriteContentTo(fileStream);
DebugDirectoryBuilder debugDirectoryBuilder = new DebugDirectoryBuilder();
debugDirectoryBuilder.AddCodeViewEntry("MyAssemblyEmbeddedSource.pdb", pdbContentId, portablePdbBuilder.FormatVersion);
// In case embedded in PE:
// debugDirectoryBuilder.AddEmbeddedPortablePdbEntry(portablePdbBlob, portablePdbBuilder.FormatVersion);
return debugDirectoryBuilder;
}
Further, you can add CustomDebugInformation by calling the MetadataBuilder.AddCustomDebugInformation(EntityHandle, GuidHandle, BlobHandle) method from the pdbBuilder instance to add source embedding and source indexing advanced PDB information.
private static void EmbedSource(MetadataBuilder pdbBuilder)
{
byte[] sourceBytes = File.ReadAllBytes("MySourceFile2.cs");
BlobBuilder sourceBlob = new BlobBuilder();
sourceBlob.WriteBytes(sourceBytes);
pdbBuilder.AddCustomDebugInformation(MetadataTokens.DocumentHandle(1),
pdbBuilder.GetOrAddGuid(new Guid("0E8A571B-6926-466E-B4AD-8AB04611F5FE")), pdbBuilder.GetOrAddBlob(sourceBlob));
}
Add resources with PersistedAssemblyBuilder
You can call MetadataBuilder.AddManifestResource(ManifestResourceAttributes, StringHandle, EntityHandle, UInt32) to add as many resources as needed. Streams must be concatenated into one BlobBuilder that you pass into the ManagedPEBuilder argument. The following example shows how to create resources and attach them to the assembly that's created.
public static void SetResource()
{
PersistedAssemblyBuilder ab = new(new AssemblyName("MyAssembly"), typeof(object).Assembly);
ab.DefineDynamicModule("MyModule");
MetadataBuilder metadata = ab.GenerateMetadata(out BlobBuilder ilStream, out _);
using MemoryStream stream = new();
ResourceWriter myResourceWriter = new(stream);
myResourceWriter.AddResource("AddResource 1", "First added resource");
myResourceWriter.AddResource("AddResource 2", "Second added resource");
myResourceWriter.AddResource("AddResource 3", "Third added resource");
myResourceWriter.Close();
byte[] data = stream.ToArray();
BlobBuilder resourceBlob = new();
resourceBlob.WriteInt32(data.Length);
resourceBlob.WriteBytes(data);
metadata.AddManifestResource(
ManifestResourceAttributes.Public,
metadata.GetOrAddString("MyResource.resources"),
implementation: default,
offset: 0);
ManagedPEBuilder peBuilder = new(
header: PEHeaderBuilder.CreateLibraryHeader(),
metadataRootBuilder: new MetadataRootBuilder(metadata),
ilStream: ilStream,
managedResources: resourceBlob);
BlobBuilder blob = new();
peBuilder.Serialize(blob);
// Create the assembly:
using FileStream fileStream = new("MyAssemblyWithResource.dll", FileMode.Create, FileAccess.Write);
blob.WriteContentTo(fileStream);
}
The following example shows how to read resources from the created assembly.
public static void ReadResource()
{
Assembly readAssembly = Assembly.LoadFile(Path.Combine(
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
"MyAssemblyWithResource.dll"));
// Use ResourceManager.GetString() to read the resources.
ResourceManager rm = new("MyResource", readAssembly);
Console.WriteLine("Using ResourceManager.GetString():");
Console.WriteLine($"{rm.GetString("AddResource 1", CultureInfo.InvariantCulture)}");
Console.WriteLine($"{rm.GetString("AddResource 2", CultureInfo.InvariantCulture)}");
Console.WriteLine($"{rm.GetString("AddResource 3", CultureInfo.InvariantCulture)}");
// Use ResourceSet to enumerate the resources.
Console.WriteLine();
Console.WriteLine("Using ResourceSet:");
ResourceSet resourceSet = rm.GetResourceSet(CultureInfo.InvariantCulture, createIfNotExists: true, tryParents: false);
foreach (DictionaryEntry entry in resourceSet)
{
Console.WriteLine($"Key: {entry.Key}, Value: {entry.Value}");
}
// Use ResourceReader to enumerate the resources.
Console.WriteLine();
Console.WriteLine("Using ResourceReader:");
using Stream stream = readAssembly.GetManifestResourceStream("MyResource.resources")!;
using ResourceReader reader = new(stream);
foreach (DictionaryEntry entry in reader)
{
Console.WriteLine($"Key: {entry.Key}, Value: {entry.Value}");
}
}
Note
The metadata tokens for all members are populated on the Save operation. Don't use the tokens of a generated type and its members before saving, as they'll have default values or throw exceptions. It's safe to use tokens for types that are referenced, not generated.
Some APIs that aren't important for emitting an assembly aren't implemented; for example, GetCustomAttributes() is not implemented. With the runtime implementation, you were able to use those APIs after creating the type. For the persisted AssemblyBuilder, they throw NotSupportedException or NotImplementedException. If you have a scenario that requires those APIs, file an issue in the dotnet/runtime repo.
For an alternative way to generate assembly files, see MetadataBuilder.
Warning
PersistedAssemblyBuilder APIs require a fully trusted environment with trusted input, similar to other technologies such as compilers. There are no restrictions other than basic validation for generated IL that the AssemblyBuilder can contain. That includes validation for member name, count, and associated metadata, such as custom attributes.
Constructors
| Name | Description |
|---|---|
| PersistedAssemblyBuilder(AssemblyName, Assembly, IEnumerable<CustomAttributeBuilder>) |
Creates a PersistedAssemblyBuilder instance that can be saved to a file or stream. |
Properties
| Name | Description |
|---|---|
| CodeBase |
Obsolete.
Gets the location of the assembly, as specified originally (such as in an AssemblyName object). (Inherited from AssemblyBuilder) |
| CustomAttributes |
Gets a collection that contains this assembly's custom attributes. (Inherited from Assembly) |
| EntryPoint |
Returns the entry point of this assembly. (Inherited from AssemblyBuilder) |
| EscapedCodeBase |
Obsolete.
Obsolete.
Gets the URI, including escape characters, that represents the codebase. (Inherited from Assembly) |
| ExportedTypes |
Gets a collection of the public types defined in this assembly that are visible outside the assembly. (Inherited from Assembly) |
| FullName |
Gets the display name of the current dynamic assembly. |
| HostContext |
Gets the host context where the dynamic assembly is being created. (Inherited from AssemblyBuilder) |
| IsCollectible |
Gets a value that indicates whether this dynamic assembly is held in a collectible AssemblyLoadContext. (Inherited from AssemblyBuilder) |
| IsDynamic |
Gets a value that indicates that the current assembly is a dynamic assembly. (Inherited from AssemblyBuilder) |
| IsFullyTrusted |
Gets a value that indicates whether the current assembly is loaded with full trust. (Inherited from Assembly) |
| Location |
Gets the location, in codebase format, of the loaded file that contains the manifest if it is not shadow-copied. (Inherited from AssemblyBuilder) |
| ManifestModule |
Gets the module in the current PersistedAssemblyBuilder that contains the assembly manifest. |
| ReflectionOnly |
Gets a value indicating whether the dynamic assembly is in the reflection-only context. (Inherited from AssemblyBuilder) |
Methods
| Name | Description |
|---|---|
| CreateInstance(String, Boolean, BindingFlags, Binder, Object[], CultureInfo, Object[]) |
Locates the specified type from this assembly and creates an instance of it using the system activator, with optional case-sensitive search and having the specified culture, arguments, and binding and activation attributes. (Inherited from Assembly) |
| CreateInstance(String, Boolean) |
Locates the specified type from this assembly and creates an instance of it using the system activator, with optional case-sensitive search. (Inherited from Assembly) |
| CreateInstance(String) |
Locates the specified type from this assembly and creates an instance of it using the system activator, using case-sensitive search. (Inherited from Assembly) |
| DefineDynamicModule(String) |
Defines a named transient dynamic module in this assembly. (Inherited from AssemblyBuilder) |
| DefineDynamicModuleCore(String) |
When overridden in a derived class, defines a dynamic module in this assembly. (Inherited from AssemblyBuilder) |
| Equals(Object) |
Returns a value that indicates whether this instance is equal to the specified object. (Inherited from AssemblyBuilder) |
| GenerateMetadata(BlobBuilder, BlobBuilder, MetadataBuilder) |
Generates the metadata for the PersistedAssemblyBuilder. |
| GenerateMetadata(BlobBuilder, BlobBuilder) |
Generates the metadata for the PersistedAssemblyBuilder. |
| GetCustomAttributes(Boolean) |
Returns all the custom attributes that have been applied to the current AssemblyBuilder. (Inherited from AssemblyBuilder) |
| GetCustomAttributes(Type, Boolean) |
Returns all the custom attributes that have been applied to the current AssemblyBuilder, and that derive from a specified attribute type. (Inherited from AssemblyBuilder) |
| GetCustomAttributesData() |
Returns CustomAttributeData objects that contain information about the attributes that have been applied to the current AssemblyBuilder. (Inherited from AssemblyBuilder) |
| GetDynamicModule(String) |
Returns the dynamic module with the specified name. (Inherited from AssemblyBuilder) |
| GetDynamicModuleCore(String) |
When overridden in a derived class, returns the dynamic module with the specified name. (Inherited from AssemblyBuilder) |
| GetExportedTypes() |
Gets the exported types defined in this assembly. (Inherited from AssemblyBuilder) |
| GetFile(String) |
Gets a FileStream for the specified file in the file table of the manifest of this assembly. (Inherited from AssemblyBuilder) |
| GetFiles() |
Gets the files in the file table of an assembly manifest. (Inherited from Assembly) |
| GetFiles(Boolean) |
Gets the files in the file table of an assembly manifest, specifying whether to include resource modules. (Inherited from AssemblyBuilder) |
| GetForwardedTypes() | (Inherited from Assembly) |
| GetHashCode() |
Returns the hash code for this instance. (Inherited from AssemblyBuilder) |
| GetLoadedModules() |
Gets all the loaded modules that are part of this assembly. (Inherited from Assembly) |
| GetLoadedModules(Boolean) |
Returns all the loaded modules that are part of this assembly, and optionally includes resource modules. (Inherited from AssemblyBuilder) |
| GetManifestResourceInfo(String) |
Returns information about how the given resource has been persisted. (Inherited from AssemblyBuilder) |
| GetManifestResourceNames() |
Loads the specified manifest resource from this assembly. (Inherited from AssemblyBuilder) |
| GetManifestResourceStream(String) |
Loads the specified manifest resource from this assembly. (Inherited from AssemblyBuilder) |
| GetManifestResourceStream(Type, String) |
Loads the specified manifest resource, scoped by the namespace of the specified type, from this assembly. (Inherited from AssemblyBuilder) |
| GetModule(String) |
Gets the specified module in this assembly. (Inherited from AssemblyBuilder) |
| GetModules() |
Gets all the modules that are part of this assembly. (Inherited from Assembly) |
| GetModules(Boolean) |
Gets all the modules that are part of this assembly, and optionally includes resource modules. (Inherited from AssemblyBuilder) |
| GetName() |
Gets an AssemblyName for this assembly. (Inherited from Assembly) |
| GetName(Boolean) |
Gets the AssemblyName that was specified when the current dynamic assembly was created. |
| GetObjectData(SerializationInfo, StreamingContext) |
Obsolete.
Gets serialization information with all of the data needed to reinstantiate this assembly. (Inherited from Assembly) |
| GetReferencedAssemblies() |
Gets an incomplete list of AssemblyName objects for the assemblies that are referenced by this AssemblyBuilder. (Inherited from AssemblyBuilder) |
| GetSatelliteAssembly(CultureInfo, Version) |
Gets the specified version of the satellite assembly for the specified culture. (Inherited from AssemblyBuilder) |
| GetSatelliteAssembly(CultureInfo) |
Gets the satellite assembly for the specified culture. (Inherited from AssemblyBuilder) |
| GetType(String, Boolean, Boolean) |
Gets the specified type from the types that have been defined and created in the current AssemblyBuilder. (Inherited from AssemblyBuilder) |
| GetType(String, Boolean) |
Gets the Type object with the specified name in the assembly instance and optionally throws an exception if the type is not found. (Inherited from Assembly) |
| GetType(String) |
Gets the Type object with the specified name in the assembly instance. (Inherited from Assembly) |
| GetTypes() |
Gets all types defined in this assembly. (Inherited from Assembly) |
| IsDefined(Type, Boolean) |
Returns a value that indicates whether one or more instances of the specified attribute type is applied to this member. (Inherited from AssemblyBuilder) |
| LoadModule(String, Byte[], Byte[]) |
Loads the module, internal to this assembly, with a common object file format (COFF)-based image containing an emitted module, or a resource file. The raw bytes representing the symbols for the module are also loaded. (Inherited from Assembly) |
| LoadModule(String, Byte[]) |
Loads the module, internal to this assembly, with a common object file format (COFF)-based image containing an emitted module, or a resource file. (Inherited from Assembly) |
| MemberwiseClone() |
Creates a shallow copy of the current Object. (Inherited from Object) |
| Save(Stream) |
Serializes the assembly to the specified stream. |
| Save(String) |
Saves the assembly to disk. |
| SetCustomAttribute(ConstructorInfo, Byte[]) |
Set a custom attribute on this assembly using a specified custom attribute blob. (Inherited from AssemblyBuilder) |
| SetCustomAttribute(CustomAttributeBuilder) |
Set a custom attribute on this assembly using a custom attribute builder. (Inherited from AssemblyBuilder) |
| SetCustomAttributeCore(ConstructorInfo, ReadOnlySpan<Byte>) |
When overridden in a derived class, sets a custom attribute on this assembly. (Inherited from AssemblyBuilder) |
| ToString() |
Returns the full name of the assembly, also known as the display name. (Inherited from Assembly) |
Events
| Name | Description |
|---|---|
| ModuleResolve |
Occurs when the common language runtime class loader cannot resolve a reference to an internal module of an assembly through normal means. (Inherited from Assembly) |
Extension Methods
| Name | Description |
|---|---|
| GetCustomAttribute(Assembly, Type) |
Retrieves a custom attribute of a specified type that is applied to a specified assembly. |
| GetCustomAttribute<T>(Assembly) |
Retrieves a custom attribute of a specified type that is applied to a specified assembly. |
| GetCustomAttributes(Assembly, Type) |
Retrieves a collection of custom attributes of a specified type that are applied to a specified assembly. |
| GetCustomAttributes(Assembly) |
Retrieves a collection of custom attributes that are applied to a specified assembly. |
| GetCustomAttributes<T>(Assembly) |
Retrieves a collection of custom attributes of a specified type that are applied to a specified assembly. |
| GetExportedTypes(Assembly) | |
| GetModules(Assembly) | |
| GetTypes(Assembly) | |
| IsDefined(Assembly, Type) |
Indicates whether custom attributes of a specified type are applied to a specified assembly. |
| TryGetRawMetadata(Assembly, Byte*, Int32) |
Retrieves the metadata section of the assembly, for use with MetadataReader. |