diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Reflection.Emit/PersistedAssemblyBuilder/Overview/csharp/GenerateMetadataSnippets.cs b/docs/fundamentals/runtime-libraries/snippets/System.Reflection.Emit/PersistedAssemblyBuilder/Overview/csharp/GenerateMetadataSnippets.cs
index a637dc97266f6..1b21cd5427287 100644
--- a/docs/fundamentals/runtime-libraries/snippets/System.Reflection.Emit/PersistedAssemblyBuilder/Overview/csharp/GenerateMetadataSnippets.cs
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Reflection.Emit/PersistedAssemblyBuilder/Overview/csharp/GenerateMetadataSnippets.cs
@@ -1,4 +1,6 @@
using System;
+using System.Collections;
+using System.Globalization;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;
@@ -13,11 +15,12 @@ public static void Main()
{
SetEntryPoint();
SetResource();
+ ReadResource();
}
//
public static void SetEntryPoint()
{
- PersistedAssemblyBuilder ab = new PersistedAssemblyBuilder(new AssemblyName("MyAssembly"), typeof(object).Assembly);
+ 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);
@@ -27,50 +30,93 @@ public static void SetEntryPoint()
tb.CreateType();
MetadataBuilder metadataBuilder = ab.GenerateMetadata(out BlobBuilder ilStream, out BlobBuilder fieldData);
- PEHeaderBuilder peHeaderBuilder = new PEHeaderBuilder(imageCharacteristics: Characteristics.ExecutableImage);
- ManagedPEBuilder peBuilder = new ManagedPEBuilder(
- header: peHeaderBuilder,
+ ManagedPEBuilder peBuilder = new(
+ header: PEHeaderBuilder.CreateExecutableHeader(),
metadataRootBuilder: new MetadataRootBuilder(metadataBuilder),
ilStream: ilStream,
mappedFieldData: fieldData,
entryPoint: MetadataTokens.MethodDefinitionHandle(entryPoint.MetadataToken));
- BlobBuilder peBlob = new BlobBuilder();
+ BlobBuilder peBlob = new();
peBuilder.Serialize(peBlob);
- // in case saving to a file:
- using var fileStream = new FileStream("MyAssembly.exe", FileMode.Create, FileAccess.Write);
+ // Create the executable:
+ using FileStream fileStream = new("MyAssembly.exe", FileMode.Create, FileAccess.Write);
peBlob.WriteContentTo(fileStream);
}
//
//
public static void SetResource()
{
- PersistedAssemblyBuilder ab = new PersistedAssemblyBuilder(new AssemblyName("MyAssembly"), typeof(object).Assembly);
+ PersistedAssemblyBuilder ab = new(new AssemblyName("MyAssembly"), typeof(object).Assembly);
ab.DefineDynamicModule("MyModule");
MetadataBuilder metadata = ab.GenerateMetadata(out BlobBuilder ilStream, out _);
- using MemoryStream stream = new MemoryStream();
- ResourceWriter myResourceWriter = new ResourceWriter(stream);
+ 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();
- BlobBuilder resourceBlob = new BlobBuilder();
- resourceBlob.WriteBytes(stream.ToArray());
- metadata.AddManifestResource(ManifestResourceAttributes.Public, metadata.GetOrAddString("MyResource"), default, (uint)resourceBlob.Count);
- ManagedPEBuilder peBuilder = new ManagedPEBuilder(
- header: new PEHeaderBuilder(imageCharacteristics: Characteristics.ExecutableImage | Characteristics.Dll),
+ 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 BlobBuilder();
+ BlobBuilder blob = new();
peBuilder.Serialize(blob);
- using var fileStream = new FileStream("MyAssemblyWithResource.dll", FileMode.Create, FileAccess.Write);
+
+ // Create the assembly:
+ using FileStream fileStream = new("MyAssemblyWithResource.dll", FileMode.Create, FileAccess.Write);
blob.WriteContentTo(fileStream);
}
//
+ //
+ 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}");
+ }
+ }
+ //
}
diff --git a/docs/fundamentals/runtime-libraries/system-reflection-emit-persistedassemblybuilder.md b/docs/fundamentals/runtime-libraries/system-reflection-emit-persistedassemblybuilder.md
index 8cc56fecdbaba..2c2a4fb57a63a 100644
--- a/docs/fundamentals/runtime-libraries/system-reflection-emit-persistedassemblybuilder.md
+++ b/docs/fundamentals/runtime-libraries/system-reflection-emit-persistedassemblybuilder.md
@@ -120,6 +120,10 @@ The following example shows how to create resources and attach it to the assembl
:::code language="csharp" source="./snippets/System.Reflection.Emit/PersistedAssemblyBuilder/Overview/csharp/GenerateMetadataSnippets.cs" id="Snippet2":::
+The following example shows how to read resources from the created assembly.
+
+:::code language="csharp" source="./snippets/System.Reflection.Emit/PersistedAssemblyBuilder/Overview/csharp/GenerateMetadataSnippets.cs" id="Snippet3":::
+
> [!NOTE]
> The metadata tokens for all members are populated on the 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.
>