Skip to content

Commit 7f4633e

Browse files
committed
Update samples related to creating managed resources
1 parent 53d56f9 commit 7f4633e

File tree

2 files changed

+66
-17
lines changed

2 files changed

+66
-17
lines changed

docs/fundamentals/runtime-libraries/snippets/System.Reflection.Emit/PersistedAssemblyBuilder/Overview/csharp/GenerateMetadataSnippets.cs

Lines changed: 61 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@ public static void Main()
1313
{
1414
SetEntryPoint();
1515
SetResource();
16+
ReadResource();
1617
}
1718
// <Snippet1>
1819
public static void SetEntryPoint()
1920
{
20-
PersistedAssemblyBuilder ab = new PersistedAssemblyBuilder(new AssemblyName("MyAssembly"), typeof(object).Assembly);
21+
PersistedAssemblyBuilder ab = new(new AssemblyName("MyAssembly"), typeof(object).Assembly);
2122
TypeBuilder tb = ab.DefineDynamicModule("MyModule").DefineType("MyType", TypeAttributes.Public | TypeAttributes.Class);
2223
// ...
2324
MethodBuilder entryPoint = tb.DefineMethod("Main", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static);
@@ -27,50 +28,93 @@ public static void SetEntryPoint()
2728
tb.CreateType();
2829

2930
MetadataBuilder metadataBuilder = ab.GenerateMetadata(out BlobBuilder ilStream, out BlobBuilder fieldData);
30-
PEHeaderBuilder peHeaderBuilder = new PEHeaderBuilder(imageCharacteristics: Characteristics.ExecutableImage);
3131

32-
ManagedPEBuilder peBuilder = new ManagedPEBuilder(
33-
header: peHeaderBuilder,
32+
ManagedPEBuilder peBuilder = new(
33+
header: PEHeaderBuilder.CreateExecutableHeader(),
3434
metadataRootBuilder: new MetadataRootBuilder(metadataBuilder),
3535
ilStream: ilStream,
3636
mappedFieldData: fieldData,
3737
entryPoint: MetadataTokens.MethodDefinitionHandle(entryPoint.MetadataToken));
3838

39-
BlobBuilder peBlob = new BlobBuilder();
39+
BlobBuilder peBlob = new();
4040
peBuilder.Serialize(peBlob);
4141

42-
// in case saving to a file:
43-
using var fileStream = new FileStream("MyAssembly.exe", FileMode.Create, FileAccess.Write);
42+
// Create the executable:
43+
using FileStream fileStream = new("MyAssembly.exe", FileMode.Create, FileAccess.Write);
4444
peBlob.WriteContentTo(fileStream);
4545
}
4646
// </Snippet1>
4747
// <Snippet2>
4848
public static void SetResource()
4949
{
50-
PersistedAssemblyBuilder ab = new PersistedAssemblyBuilder(new AssemblyName("MyAssembly"), typeof(object).Assembly);
50+
PersistedAssemblyBuilder ab = new(new AssemblyName("MyAssembly"), typeof(object).Assembly);
5151
ab.DefineDynamicModule("MyModule");
5252
MetadataBuilder metadata = ab.GenerateMetadata(out BlobBuilder ilStream, out _);
5353

54-
using MemoryStream stream = new MemoryStream();
55-
ResourceWriter myResourceWriter = new ResourceWriter(stream);
54+
using MemoryStream stream = new();
55+
ResourceWriter myResourceWriter = new(stream);
5656
myResourceWriter.AddResource("AddResource 1", "First added resource");
5757
myResourceWriter.AddResource("AddResource 2", "Second added resource");
5858
myResourceWriter.AddResource("AddResource 3", "Third added resource");
5959
myResourceWriter.Close();
60-
BlobBuilder resourceBlob = new BlobBuilder();
61-
resourceBlob.WriteBytes(stream.ToArray());
62-
metadata.AddManifestResource(ManifestResourceAttributes.Public, metadata.GetOrAddString("MyResource"), default, (uint)resourceBlob.Count);
6360

64-
ManagedPEBuilder peBuilder = new ManagedPEBuilder(
65-
header: new PEHeaderBuilder(imageCharacteristics: Characteristics.ExecutableImage | Characteristics.Dll),
61+
byte[] data = stream.ToArray();
62+
BlobBuilder resourceBlob = new();
63+
resourceBlob.WriteInt32(data.Length);
64+
resourceBlob.WriteBytes(data);
65+
66+
metadata.AddManifestResource(
67+
ManifestResourceAttributes.Public,
68+
metadata.GetOrAddString("MyResource.resources"),
69+
implementation: default,
70+
offset: 0);
71+
72+
ManagedPEBuilder peBuilder = new(
73+
header: PEHeaderBuilder.CreateLibraryHeader(),
6674
metadataRootBuilder: new MetadataRootBuilder(metadata),
6775
ilStream: ilStream,
6876
managedResources: resourceBlob);
6977

70-
BlobBuilder blob = new BlobBuilder();
78+
BlobBuilder blob = new();
7179
peBuilder.Serialize(blob);
72-
using var fileStream = new FileStream("MyAssemblyWithResource.dll", FileMode.Create, FileAccess.Write);
80+
81+
// Create the assembly:
82+
using FileStream fileStream = new("MyAssemblyWithResource.dll", FileMode.Create, FileAccess.Write);
7383
blob.WriteContentTo(fileStream);
7484
}
7585
// </Snippet2>
86+
// <Snippet3>
87+
public static void ReadResource()
88+
{
89+
Assembly readAssembly = Assembly.LoadFile(Path.Combine(
90+
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
91+
"MyAssemblyWithResource.dll"));
92+
93+
// Use ResourceManager.GetString() to read the resources.
94+
ResourceManager rm = new("MyResource", readAssembly);
95+
Console.WriteLine("Using ResourceManager.GetString():");
96+
Console.WriteLine($"{rm.GetString("AddResource 1", CultureInfo.InvariantCulture)}");
97+
Console.WriteLine($"{rm.GetString("AddResource 2", CultureInfo.InvariantCulture)}");
98+
Console.WriteLine($"{rm.GetString("AddResource 3", CultureInfo.InvariantCulture)}");
99+
100+
// Use ResourceSet to enumerate the resources.
101+
Console.WriteLine();
102+
Console.WriteLine("Using ResourceSet:");
103+
ResourceSet resourceSet = rm.GetResourceSet(CultureInfo.InvariantCulture, createIfNotExists: true, tryParents: false);
104+
foreach (DictionaryEntry entry in resourceSet)
105+
{
106+
Console.WriteLine($"Key: {entry.Key}, Value: {entry.Value}");
107+
}
108+
109+
// Use ResourceReader to enumerate the resources.
110+
Console.WriteLine();
111+
Console.WriteLine("Using ResourceReader:");
112+
using Stream stream = readAssembly.GetManifestResourceStream("MyResource.resources")!;
113+
using ResourceReader reader = new(stream);
114+
foreach (DictionaryEntry entry in reader)
115+
{
116+
Console.WriteLine($"Key: {entry.Key}, Value: {entry.Value}");
117+
}
118+
}
119+
// </Snippet3>
76120
}

docs/fundamentals/runtime-libraries/system-reflection-emit-persistedassemblybuilder.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,11 @@ The following example shows how to create resources and attach it to the assembl
120120

121121
:::code language="csharp" source="./snippets/System.Reflection.Emit/PersistedAssemblyBuilder/Overview/csharp/GenerateMetadataSnippets.cs" id="Snippet2":::
122122

123+
The following example shows how to read resources from the assembly created above.
124+
125+
:::code language="csharp" source="./snippets/System.Reflection.Emit/PersistedAssemblyBuilder/Overview/csharp/GenerateMetadataSnippets.cs" id="Snippet3":::
126+
127+
123128
> [!NOTE]
124129
> The metadata tokens for all members are populated on the <xref:System.Reflection.Emit.AssemblyBuilder.Save%2A> 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.
125130
>

0 commit comments

Comments
 (0)