Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

UTF-8 Emulator

在 Windows 上以 UTF-8 (Code Page 65001) 运行任意可执行文件的轻量级启动器。

背景

在 Windows 上使用 MSVC 编译 llama-cpp-python 等含有非 ASCII 字符的 C/C++ 项目时,经常会因为系统默认代码页 (如 GBK / CP936) 导致各种编码错误——源文件中的 UTF-8 字符串被截断、编译器报 C2001 / C2143、链接器路径解析失败等等。

UTF-8 Emulator 通过 DLL 注入技术,在目标进程启动前将活动代码页 (ACP) 劫持为 65001 (UTF-8),从根源上解决这一问题。无需修改系统区域设置,也无需开启 Windows 的 Beta 版 UTF-8 全局选项。

工作原理

LEProc64.exe cl.exe /nologo /utf-8 hello.cpp
     │
     ├─ 1. 解析目标路径 (模拟 Windows PATH 查找逻辑)
     ├─ 2. 读取 PE 头,检测目标架构 (x86 / x64)
     │     └─ 架构不匹配时自动委派给 LEProc32.exe 或 LEProc64.exe
     ├─ 3. 以 CREATE_SUSPENDED 创建目标进程
     ├─ 4. 通过 CreateRemoteThread + LoadLibraryW 注入 LRHook DLL
     │     └─ DLL 内部 hook GetACP()、GetOEMCP() 等 API,返回 65001
     ├─ 5. 设置环境变量 (LRCodePage=65001, LRLCID, LRBIAS)
     ├─ 6. ResumeThread,目标进程在 UTF-8 环境下正常执行
     └─ 7. 等待退出,透传 exit code

快速开始

下载

Releases 下载预编译包,解压后确保以下文件在同一目录:

LEProc32.exe
LEProc64.exe
LRHookx32.dll
LRHookx64.dll

使用

LEProc64.exe <目标程序> [参数...]

示例:用 MSVC 编译含中文注释的源文件

LEProc64.exe cl.exe /nologo /utf-8 hello.cpp

示例:运行 pip install(编译 llama-cpp-python)

LEProc64.exe pip install llama-cpp-python

示例:运行 CMake + Ninja 构建

LEProc64.exe cmake --build build --config Release

程序会自动检测目标的架构——即使你用 LEProc64.exe 启动一个 32 位程序,它也会自动委派给 LEProc32.exe 处理。

从源码构建

环境要求

  • Visual Studio 2022+ 或 dotnet CLI
  • .NET Framework 4.8 SDK

编译

dotnet build -c Release -p:Platform=x64
dotnet build -c Release -p:Platform=x86

输出位于 out/Release/ 目录。

项目结构

Utf8Emulator.slnx          # Visual Studio 解决方案
LEProc/
  ├── Program.cs            # 主程序:进程创建、DLL 注入、架构委派
  ├── LEProc.csproj         # 项目配置 (双平台: x86/x64)
  ├── LRHookx32.dll         # 32 位 hook DLL (来自 Locale Remulator)
  └── LRHookx64.dll         # 64 位 hook DLL (来自 Locale Remulator)
Runner/
  └── Runner.cs             # 诊断工具:打印当前代码页信息
out/Release/                # 编译产物

常见问题

和 Windows 的"使用 Unicode UTF-8 提供全球语言支持"选项有什么区别?

Windows 的 Beta 选项是全局的,会修改整个系统的 ACP,可能导致旧版软件出现兼容性问题。UTF-8 Emulator 只对目标进程生效,不影响系统其他部分。

chcp 65001 有什么区别?

chcp 65001 只影响当前控制台窗口的代码页,对通过 CreateProcessW 创建的子进程无效。UTF-8 Emulator 通过 DLL 注入在 API 层面进行 hook,确保目标进程及其子进程的 GetACP() 等调用均返回 65001。

杀毒软件报警?

DLL 注入是合法的 Windows 编程技术,但部分杀毒软件可能会误报。如遇拦截,请将 LEProc 及 LRHook DLL 加入信任列表。

鸣谢

  • Locale Remulator — 本项目使用的 Hook DLL (LRHookx32.dll / LRHookx64.dll) 来自 Locale Remulator 项目。感谢 @InWILL 及所有贡献者的出色工作。

许可证

本项目中包含的 LRHookx32.dllLRHookx64.dll 来自 Locale Remulator,遵循其原始许可证 (LGPL-3.0)。

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages