C#中需将文件“生成操作”设为Embedded Resource才能嵌入EXE,资源名由默认命名空间+文件夹路径+文件名组成,运行时用GetManifestResourceStream()配合完整资源名读取字节流。

在C#项目中设置文件为“嵌入的资源”
Visual Studio默认不会把普通文件打包进EXE,必须显式标记为Embedded Resource。右键文件 → “属性” → 将“生成操作”改为Embedded Resource。注意:路径中的文件夹结构会变成命名空间的一部分,比如Assets\icon.png在MyApp项目里,完整资源名是MyApp.Assets.icon.png。
常见错误:忘记改“生成操作”,仍用Content或None——编译后文件不会进入程序集,Assembly.GetExecutingAssembly().GetManifestResourceNames()也查不到。
- 确保文件“复制到输出目录”设为
Do not copy(否则会多出一个外部副本) - 若文件名含空格或特殊字符,资源名会自动转义(如
my file.txt→my_file.txt),建议用下划线或驼峰避免歧义 - 多个同名文件放在不同子目录时,资源名唯一,不会冲突
运行时读取嵌入资源的字节流
嵌入资源本质是编译进程序集的只读字节块,不能直接当文件路径使用。要用Assembly.GetExecutingAssembly().GetManifestResourceStream()打开,传入**完整资源名称**(区分大小写)。
示例代码:
var assembly = Assembly.GetExecutingAssembly();
string resourceName = "MyApp.Assets.config.json";
using var stream = assembly.GetManifestResourceStream(resourceName);
if (stream == null)
throw new InvalidOperationException($"Resource '{resourceName}' not found. Available: {string.Join(", ", assembly.GetManifestResourceNames())}");
using var reader = new StreamReader(stream);
string content = reader.ReadToEnd();容易踩的坑:
-
GetManifestResourceStream()返回null时,别假设路径错——先打印GetManifestResourceNames()确认实际注册名 - 资源名不支持通配符,也不能用
../向上跳级 - 流读完即关闭,不可重复读取;需多次使用请先
ToArray()缓存字节
处理二进制资源(图片、字体、音频等)
图片、字体这类资源必须以原始字节方式加载,不能走StreamReader。典型场景如从嵌入资源创建Bitmap或Font:
var assembly = Assembly.GetExecutingAssembly();
using var stream = assembly.GetManifestResourceStream("MyApp.Assets.logo.png");
var bitmap = new Bitmap(stream); // 直接构造,内部会读取全部字节关键点:
- 某些类型(如
Font)要求流保持打开状态,此时应传new MemoryStream(bytes)而非原始流 - 大文件(>1MB)嵌入会显著增大EXE体积,且首次加载有IO开销;频繁访问建议提取到临时文件再加载
- WPF中可用
pack://application:,,,/ResourceName语法,但仅限Resource构建操作(非Embedded Resource),二者机制不同,别混用
调试时快速验证资源是否成功嵌入
最直接的办法是在启动代码里加一行诊断输出:
Console.WriteLine("Embedded resources:");
foreach (var name in Assembly.GetExecutingAssembly().GetManifestResourceNames())
Console.WriteLine($" - {name}");运行后看输出列表是否包含你的目标资源名。如果没出现,问题一定出在构建操作或文件路径上。
另一个易忽略点:GetManifestResourceNames()返回的是编译时确定的名称,和项目中看到的相对路径不是一回事——它受项目默认命名空间、文件夹层级、文件属性共同影响,缺一不可。










