资源文件命名须严格匹配标准文化标识,如resources.zh-cn.resx;切换语言需重设currentuiculture并手动刷新界面;key区分大小写且禁用空格;卫星程序集发布时需启用publishincludesatelliteassemblies。

资源文件命名必须严格匹配文化标识
Visual Studio 里右键项目 → “添加” → “新建项” → 选“资源文件”,名字不能随便起。Resources.resx 是默认中性资源,Resources.zh-CN.resx 和 Resources.en-US.resx 才会被自动识别为对应语言变体。如果写成 Resources_zh.resx 或 Resources.en.resx,运行时 ResourceManager 就找不到——它只认标准文化名(culture name),不接受自定义缩写。
常见错误现象:MissingManifestResourceException 或取到的字符串始终是默认语言(比如总显示中文,切英文没反应)。
- 确保所有资源文件名以
Resources.开头 + 标准文化代码 +.resx - 文化代码用
zh-CN不用zh,用en-US不用en(除非你明确只支持通用英语且已设CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("en")) - 编译后检查输出目录:
zh-CN\Resources.resources和en-US\Resources.resources应该真实存在子文件夹中
运行时切换语言要重设 CurrentUICulture 并重建 UI
Thread.CurrentThread.CurrentUICulture 决定 ResourceManager 查哪套资源,但它不会自动刷新已有控件的文本。WinForms 里改完文化后,得手动触发界面更新;WPF 更麻烦,绑定不会自动响应文化变更。
使用场景:用户点“切换英文”按钮后,菜单、标签、提示文字都要立刻变。
- 切换前先保存原文化:
var old = Thread.CurrentThread.CurrentUICulture - 切换后立即赋值:
Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US") - WinForms:调用
this.ApplyResources(null, null)或逐个重设控件Text属性(推荐封装一个RefreshLocalizedText()方法) - WPF:没有内置刷新机制,需重新绑定或用
Language属性配合x:Uid+ MSBuild 生成的 BAML 资源(实际项目中多数人选择重启窗口或重载 ViewModel)
ResourceManager.GetString() 的 key 区分大小写且不能含空格
资源文件里每个字符串都有一个 key,GetString("SaveButton_Text") 能取到,但 GetString("savebutton_text") 或 GetString("Save Button Text") 会返回 null —— 它底层用的是哈希查找,且设计器生成的 .resources 文件对 key 是严格大小写敏感的。
性能影响:key 错误导致反复返回 null 后又 fallback 到默认资源,看似没报错,实则埋下逻辑隐患(比如某按钮文案始终不更新)。
- 统一用 PascalCase 命名 key,如
LoginForm_Title、ConfirmDialog_OK - 避免在 key 里用连字符、空格、中文,VS 资源编辑器虽允许输入,但生成的 .Designer.cs 可能出问题
- 调试时可临时加断点检查
rm.GetResourceSet(CultureInfo.CurrentUICulture, true, true)返回的集合,确认 key 是否真存在
发布时别漏掉卫星程序集
发布 .NET Framework 或 .NET 5+ 自包含部署时,zh-CN 和 en-US 文件夹必须随主程序一起拷贝。如果只复制了 MyApp.exe 和 MyApp.dll,那无论怎么设文化,都只能回退到中性资源。
容易踩的坑:用 dotnet publish -c Release -r win-x64 默认不会把卫星程序集放进 publish/ 目录,除非你在 csproj 里显式开启:
<propertygroup><publishtrimmed>false</publishtrimmed><publishreadytorun>true</publishreadytorun><publishincludesatelliteassemblies>true</publishincludesatelliteassemblies></propertygroup>
另外,IIS 或 Windows 服务环境下,CurrentUICulture 可能被宿主重置,建议在入口处(如 Main() 或 Application_Start)强制初始化一次。
最常被忽略的一点:资源文件的“生成操作”属性必须是 Embedded Resource,不是 Content 或 None——否则编译器根本不会把它打包进程序集或卫星程序集。











