在C#中获取嵌入式XML资源Stream需调用Assembly.GetManifestResourceStream()并确保资源名完全匹配默认命名空间、文件夹层级和扩展名,且生成操作设为Embedded Resource;加载时须用using确保流释放,避免资源泄漏。

如何在C#中获取嵌入式XML资源的Stream
嵌入式XML资源必须通过 Assembly.GetManifestResourceStream() 获取原始流,不能直接用文件路径打开。关键在于资源名称必须完全匹配——包括默认命名空间、文件夹层级和扩展名。
- 右键XML文件 → “属性” → 将“生成操作”设为
Embedded Resource - 资源名称默认格式为
[默认命名空间].[文件夹].[文件名],例如项目默认命名空间是MyApp,XML放在Data/config.xml,则完整名称是MyApp.Data.config.xml - 可用
Assembly.GetManifestResourceNames()列出所有嵌入资源名,调试时先打印出来确认拼写
用XDocument.Load()加载嵌入XML的正确方式
XDocument.Load() 接收 Stream,但不接受 null。如果 GetManifestResourceStream() 返回 null,说明资源名错误或资源未嵌入成功。
var assembly = Assembly.GetExecutingAssembly();
var stream = assembly.GetManifestResourceStream("MyApp.Data.settings.xml");
if (stream == null)
throw new InvalidOperationException("Embedded XML resource not found.");
var doc = XDocument.Load(stream); // ✅ 正确:传入 Stream
// 注意:不要用 XDocument.Load("MyApp.Data.settings.xml") ❌ 这会尝试读文件系统
读取后立即关闭Stream的必要性
GetManifestResourceStream() 返回的 Stream 必须显式释放(或用 using),否则可能引发资源泄漏,尤其在高频调用场景下。
-
XDocument.Load(Stream)不会自动关闭流,它只读取内容并保留流打开状态 - 推荐用
using包裹流,或用Stream.CopyTo()转成MemoryStream再加载(适合需多次读取的场景)
using var stream = assembly.GetManifestResourceStream("MyApp.Resources.data.xml");
var doc = XDocument.Load(stream); // stream 在 using 结束时自动释放
区分设计时资源路径与运行时资源名
VS里看到的文件路径(如 Resources\info.xml)≠ 运行时资源名。若项目属性中设置了“根命名空间”,它会前置到资源名;若XML文件属性中“自定义工具”设为 PublicResXFileCodeGenerator,那它就不是普通嵌入资源,而是生成了 Resources.Designer.cs —— 此时应走 Properties.Resources 访问,而非 GetManifestResourceStream。
- 纯嵌入XML:用
GetManifestResourceStream+ 手动拼资源名 - 已用ResX机制管理的XML:改用
Properties.Resources.ResourceManager.GetObject("info")(但返回的是object,需转byte[]再构造MemoryStream) - 混淆点常出现在“XML文件被意外设为
Content或None生成操作”——此时GetManifestResourceNames()根本不会列出它
GetManifestResourceNames() 输出全部名称,眼见为实。










