Skip to content

中文本地化进展艰难但顺利 / Chinese localization is progressing hard but smoothly - #4859

Closed
ElderMeow wants to merge 6 commits into
TASEmulators:masterfrom
ElderMeow:zh-cn-localize
Closed

ElderMeow wants to merge 6 commits into
TASEmulators:masterfrom
ElderMeow:zh-cn-localize

Conversation

@ElderMeow

Copy link
Copy Markdown

dev build for branch | USERNAME:BRANCHNAME

已搭建本地化框架,已解决目前遇到的本地化问题,尽量采取对原项目改动最小的本地化方式。
The localization framework has been set up. Current localization issues have been resolved, adopting approaches that minimize modifications to the original project as much as possible.

已完成窗口控件的中文本地化工作,经过粗略测试,不确定是否有遗漏。
Chinese localization for windows and controls has been completed. It has undergone basic testing, though some omissions may still exist.

Check if completed:

  • I have run any relevant test suites
  • I, the commit author, have read the contribution terms on licensing and generative AI (last updated 2026-09-20) and am compliant

…iscoHawk approximately.

大约完成了 DiscoHawk 的本地化改造和中文本地化工作。
…rk for EmuHawk

feat(WIP): 搭建 EmuHawk 本地化框架

- DiscoHawk localization finished in previous commit.
  DiscoHawk汉化已于上一个提交完成。
- Remove redundant cultureNameMapper. Root cause of some windows localization failure is mismatch between folder path and namespace, culture name mapping is no longer required.
  删除冗余 cultureNameMapper。一些窗口汉化失败根因为文件夹路径与命名空间不匹配,不再需要文化名称映射逻辑
- Adopt .NET native satellite DLL Resx localization solution, finalized the whole workflow. Handle lost culture name in CurrentDomain_AssemblyResolve. By configuring LogicalName, the failure of loading localized resources caused by mismatch between folder path and namespace can be solved.
  采用 .NET 原生卫星 dll Resx 本地化方案,确定整套工作流程。处理 CurrentDomain_AssemblyResolve 中文化名丢失问题,通过配置LogicalName,解决文件夹路径与命名空间不匹配导致的本地化资源加载失败。
- Add localization font framework (skeleton only, untested)
  新增本地化字体加载框架(仅骨架,尚未测试)
- Only a small part of EmuHawk UI translation done. This is an intermediate milestone commit, incomplete and not fully testable.
  EmuHawk界面翻译仅完成少量词条,本次为中间里程碑提交,内容未完成,暂不可完整测试。
- Continue adding translation entries for form zh-CN.resx in subsequent commits.
  后续继续补充窗体 zh-CN.resx 翻译条目。
修复项目缺陷并继续推进汉化

- 修复原项目bug:原项目未在csproj包含 MainForm.Debug.cs 与 MainForm.VSystem.cs,本地化时VS将二者误识别为窗体,引发问题。修改 BizHawk.Client.EmuHawk.csproj 第289行
  | Fix upstream bug: MainForm.Debug.cs and MainForm.VSystem.cs were missing in csproj. VS misidentifies them as forms during localization. Modified file "BizHawk.Client.EmuHawk.csproj" line 289.

- 继续推进简体中文汉化工作
  | Continue zh-CN localization work.
…te filename resource collision

扫描并审计WinForms窗体类名与文件名不匹配问题,解决重名文件资源冲突

- MacroInputTool.ButtonSelect.cs:被VS误识别为窗体,已修改于BizHawk.Client.EmuHawk.csproj第418行
  | MacroInputTool.ButtonSelect.cs: misrecognized as form by VS, modified at line 418 of BizHawk.Client.EmuHawk.csproj

- VDPViewer.Designer.cs:存在两份不同目录的同名文件,同时文件名与类名本身不匹配;已修改文件名为类名
  | VDPViewer.Designer.cs: two files with identical filename under different directories, class name mismatches filename; renamed files to match class name

检测到类名与文件基础名拼写不一致(非仅大小写差异)的文件列表:
  | Detected files with spelling mismatch between class name and file base name (not only case difference):
  | BSNESControllerConfig.Designer.cs
  | SNESControllerConfig.Designer.cs
  | HexColor.Designer.cs
  | MacroInput.Designer.cs
  | HeaderEditor.Designer.cs
  | VirtualpadsTool.Designer.cs

存在本地化风险:原生ComponentResourceManager将无法绑定资源文件,已修改文件名为类名
  | Localization risk: native ComponentResourceManager cannot bind resource files; renamed files to match class name

Localization progress: Continue localization.
  | 汉化进度:继续进行汉化工作。
…ly complete Chinese localization for all WinForms windows and controls in BizHawk. Basic tests passed; core window localization finished, though some omissions may still exist.

使用C#原生本地化机制(*.zh-CN.resx)初步完成BizHawk中所有Winform窗口与控件的中文本地化工作,并通过初步测试(确定基本窗口汉化完成,但是不确保没有遗漏)

2: Fix neutral resx files in original project: some neutral .resx missing DependentUpon. Mismatch between file path and namespace caused incorrect compiled resource path. Modifications at BizHawk.Client.EmuHawk.csproj line in 35.
修复原项目中性resx文件:部分中性.resx未指定DependentUpon,文件路径与命名空间不匹配导致编译后资源路径不正确,修改于 BizHawk.Client.EmuHawk.csproj 第 25 行

3: Several windows have namespaces neither matching file paths nor under BizHawk.Client.EmuHawk. Handled separately, modifications at BizHawk.Client.EmuHawk.csproj line in 37.
另有若干窗口命名空间既不匹配文件路径,也不属于BizHawk.Client.EmuHawk,已单独处理,修改于 BizHawk.Client.EmuHawk.csproj 第 37 行
… designer language to default to avoid polluting upstream source code.

重置原始resx内窗体语言元数据,将WinForms设计器语言恢复默认,避免污染上游源码
@YoshiRulz YoshiRulz linked an issue Oct 9, 2026 that may be closed by this pull request
@YoshiRulz

Copy link
Copy Markdown
Contributor

Firstly, thank you for working on localisation!
I don't think we should be using WinForms' built-in localisation mechanism. It's too limited and, as I'm sure you've found, annoying to work with.
There's an experimental PR #4406 which uses Fluent instead. Could you try that out and give your opinion on how easy it is, and point out any bugs or missing features?

@ElderMeow ElderMeow closed this Oct 9, 2026
@ElderMeow

Copy link
Copy Markdown
Author

Hi, sorry for the confusion! This PR was created accidentally. I'm new to GitHub operations and didn't intend to submit my localization branch to the upstream repository at this stage.

I saw your comment about the Fluent experimental PR #4406. I will check it out and share my feedback later. This current resx-based Chinese localization work is still a WIP prototype on my fork. I will close this PR shortly.

@ElderMeow

Copy link
Copy Markdown
Author

@YoshiRulz
Thanks for the response, I have evaluated the Fluent-based localization approach. Fluent only handles text translation and seemed not easy to resolve WinForms UI layout issues, so I believe using WinForms' built-in localization still necessary.

WinForms' cross-platform and localization problems. No matter what kind of localization back-end technology is adopted, these problems cannot be completely avoided. However, if the project is migrated to a modern cross-platform C# UI framework like Avalonia in the future, the `xx-XX.resx' resource file generated by Winforms' built-in localization process can still be used.

The remaining hard-coded strings in the project need to be handled separately. My plan is to wrap all hard-coded strings with a unified translation helper function. This is a necessary step, no matter which localization method is used. if the project switches to any other localization system in the future, only the internal implementation of this function needs to be replaced.

And I have solved the problem when the project uses WinForms' built-in localization mechanism. After testing, it can now work normally on Windows.

I will maintain a standalone Chinese-localized build in my fork repository. When all my localization work is completed, I will also prepare a localizable version of the project with minimal changes relative to the upstream codebase for your reference.

In fact, the only modifications necessary to enable localization are:

Necessary modification 1: Function AssemblyResolve() in Program.cs should handles CultureName. The origal project routes all DLLs through a dll/ subfolder, so satellite assemblies were never being resolved:

private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
	var requested = args.Name;
	lock (AppDomain.CurrentDomain)
	{
		var firstAsm = Array.Find(AppDomain.CurrentDomain.GetAssemblies(), asm => asm.FullName == requested);
		if (firstAsm != null)
		{
			return firstAsm;
		}
		// load missing assemblies by trying to find them in the dll directory
		var dllname = $"{new AssemblyName(requested).Name}.dll";
		var directory = Path.Combine(AppContext.BaseDirectory, "dll");

		// ====================== The added code ===================
		var cultureName = $"{new AssemblyName(requested).CultureName}";
		if (!string.IsNullOrEmpty(cultureName))
		{
			var fnameWithCulture = Path.Combine(directory, cultureName, dllname);
			if (File.Exists(fnameWithCulture))
			{
				return Assembly.LoadFile(fnameWithCulture);
			}
		}
		// cultureName processing completed.

		var fname = Path.Combine(directory, dllname);
		// it is important that we use LoadFile here and not load from a byte array; otherwise mixed (managed/unmanaged) assemblies can't load
		return File.Exists(fname) ? Assembly.LoadFile(fname) : null;
	}
}

Necessary modification 2: Update LogicalName for *.xx-XX.resx so the resource name matches the actual class namespace rather than the folder path:

<ItemGroup>
	<EmbeddedResource Update="**\*.zh-CN.resx">
		<LogicalName>BizHawk.Client.EmuHawk.%(Filename).resources</LogicalName>
	</EmbeddedResource>
</ItemGroup>

Missing DependentUpon entries added for resx files the project had left unlinked and so on (not more than 40 lines).

Only need to modify these two places, and a few other configurations, WinForms built-in localization on Windows goes working.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Localization support

2 participants