这是一个实验,如何使用 Rust 在 Windows 上实现一个输入法?
重复靠轮子毫无意义,除非,你要学习。
TSF
Text Services Framework (文本服务框架)是一种系统服务,主要用于 Windows 平台的键盘处理器、手写识别和语音识别,当然,也包括输入法的实现。
理论上,最小实现只需要一个实现了 TSF 接口的 DLL 就可以了。使用下面的命令注册到系统中,输入法就可以出现在输入法列表中:
regsvr32 "C:\Program Files\SampleIME\SampleIME.dll"
它的大致原理是,在输入的过程中,各个应用会自动调用这个 DLL 来处理按键输入。
但是一个功能完备的输入法肯定不可能只有一个DLL。下面是微信输入法的组件:
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 2026/5/10 11:33 BuildIn
d----- 2026/5/10 11:33 flutter_datas
...
-a---- 2026/5/8 19:27 5816936 wetype_installer.exe
-a---- 2026/5/8 19:48 6912048 wetype_renderer.exe
-a---- 2026/5/8 19:48 8137776 wetype_server.exe
-a---- 2026/5/8 19:48 1201704 wetype_service.exe
-a---- 2026/5/8 19:48 18203184 wetype_update.exe
-a---- 2026/5/8 19:48 166952 WeUIResource.dll
-a---- 2026/5/8 19:48 588336 window_manager_plugin.dll
-a---- 2026/5/8 19:48 1430056 WXP2PTransfer.dll
-a---- 2026/5/8 19:48 17777712 XNet.dll
可以看到,光exe就有5个模块。因为我们需要处理复杂的输入逻辑、候选栏、系统托盘菜单、设置面板等。
IPC 通信
自然地,这需要一个IPC通信机制,来满足多个输入法模块之间的通信。Windows 上的 IPC 常用的应该是 Windows Named Pipe(命名管道)。
同样地,我们使用 Rime 引擎来处理输入逻辑。
所以处理流程如下:
按键 → TSF DLL → IPC → Server → Rime引擎 → 返回结果 → 显示/上屏
系统托盘菜单(Server)的一些状态变更,也是通过 IPC(WNPipe)来通知的。
能使用 Rust 实现吗?
因为 Rime 引擎是 C++ 实现的,而 Windows 接口也是C/C++ 实现的,所以,理论上,最佳的实现输入法语言应该是C++。
那么,Rust 呢? 当然可以。
首先,微软官方有 Rust 的绑定库:https://github.com/microsoft/windows-rs。 其次,Rime 引擎有 C 接口输出。我们只要对 librime 进行 FFI 封装就可以了。
至此,没有什么障碍了。
架构如下:
graph TB
subgraph "RIME 模块组"
LIBRIME_SYS[librime-sys<br/>原生 FFI]
LIBRIME[librime<br/>高层封装]
RIME[winxime-rime<br/>引擎封装]
LIBRIME_C[librime/ 子模块<br/>C++ 库]
end
subgraph "核心模块"
IPC[winxime-ipc<br/>IPC 协议]
CONFIG[winxime-config<br/>配置 + 日志]
end
subgraph "应用层"
TSF[winxime-tsf<br/>TSF DLL]
SERVER[winxime-server<br/>主服务器]
SETUP[winxime-setup<br/>设置界面]
REGISTER[winxime-tsf-register<br/>注册工具]
end
subgraph "Windows 系统"
WIN_TSF[Windows TSF API]
WIN_PIPE[Named Pipe]
end
LIBRIME_SYS --> LIBRIME
LIBRIME --> RIME
RIME --> LIBRIME_C
IPC --> TSF
IPC --> SERVER
IPC --> SETUP
CONFIG --> TSF
CONFIG --> SERVER
CONFIG --> SETUP
RIME --> SERVER
WIN_TSF --> TSF
TSF --> WIN_PIPE
WIN_PIPE --> SERVER
实现
由于输入我们交给了 Rime 引擎 ,所以我们需要做的是大概有以下工作:
- TSF DLL 通过 IPC 与 server 通信。
- 实现候选栏
- 实现系统托盘菜单
- 实现设置面板
TSF <=> IPC <=> Server <=> Rime 引擎
TSF 接收到应用程序的键盘事件,通过发送 JSON 到管道(管道路径为 \\.\pipe\WinximeNamedPipe),Server 接收请求后,转交给 Rime 引擎处理。
在这个过程中, Server 只是一个中转站,它并不处理输入逻辑,有点类似于 web 开发中的 Controller。
通过 regsvr32 注册 TSF DLL,就可以在 Windows 系统中看到输入法。

实现候选栏
候选栏采用 Direct2D + DirectComposition + DXGI SwapChain 的组合方案,而非传统的 GDI 或 WPF。
采用这个方案主要有2点原因:
- 高性能,无外部依赖,候选栏并不会有太多的交互和复杂的元素,额外引用 GUI 库没有太大的必要。
- 候选栏实现在 server 模块,而整个server 模块也只有候选栏需要实现UI。

系统托盘菜单与设置菜单
事实上,实现候选栏已经完成了输入法的MVP功能。如果还需要输入法像商业输入法一样的话,就那实现系统托盘菜单了。比如,中/英 切换,输入法配置入口等。
问题
事实上,这个项目最大的难度不在于开发,而在于调试。
相对于一般的应用开发,输入法开发要难调试一些。由于它并不是一个单体应用,而是由一个 DLL 和一堆 exe 组成。
因为 windows 自带的卸载根本无法干净地卸载,它只能卸载其中一个,而dll和安装目前还存在于电脑中。所以,一个友好的独立卸载工具是必须的。