在C#中获取嵌入式XML资源Stream需调用Assembly.GetManifestResourceStream()并确保资源名完全匹配默认命名空间、文件夹层级和扩展名,且生成操作设为Embedded Resource;加载时须用using确保流释放,避免资源泄漏。
嵌入式XML资源必须通过 Assembly.GetManifestResourceStream() 获取原始流,不能直接用文件路径打开。关键在于资源名称必须完全匹配——包括默认命名空间、文件夹层级和扩展名。
Embedded Resource
[默认命名空间].[文件夹].[文件名],例如项目默认命名空间是 MyApp,XML放在 Data/config.xml,则完整名称是 MyApp.Data.config.xml
Assembly.GetManifestResourceNames() 列出所有嵌入资源名,调试时先打印出来确认拼写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") ❌ 这会尝试读文件系统
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。
GetManifestResourceStream + 手动拼资源名Properties.Resources.ResourceManager.GetObject("info")(但返回的是 object,需转 byte[] 再构造 MemoryStream)Content 或 None 生成操作”——此时 GetManifestResourceNames() 根本不会列出它GetManifestResourceN
ames() 输出全部名称,眼见为实。