我创建了一个类库(.NET Framework 4.7.1),它使用属性在TSFITfTextInputProcessorEx
中实现了文本服务(等) 。我使用它注册了它,它可以被系统成功识别为输入法(IME),并且可以在大多数应用程序中使用,除了 UWP 应用程序。ComVisible
RegistrationServices
在 Win32 应用程序中使用
在 Win32 应用程序(例如 32 位notepad.exe
)中,当我激活基于 .NET 的 TextService(通过切换到语言栏中的 IME)时会发生以下情况:
(圈出YngPing.TSF.dll
的是包含 COM 对象实现的 .NET 程序集。由 COM 对象创建引起的加载从 #56 开始。)
基本上,在切换到我的 IME 时,TSF 框架(不是应用程序代码,而是在同一进程中运行)将尝试通过调用来创建/请求我的 TextService 的 COM 对象CoCreateObject
。因为这不是本机 COM 对象,mscoree.dll
实际上是注册表中的“真实”COM DLL。mscoree.dll
首先加载,然后加载mscoreei.dll
,clr.dll
等等,最后加载实际的 .NET dll。
在 AppContainer 中使用(UWP 应用)
现在这些都在普通桌面应用程序中按预期工作,但在 UWP 应用程序中,相同的进程将在加载后停止mscoree.dll
(mscoreei.dll
即clr.dll
,我的 .NET 程序集未加载)。调用堆栈如下所示:
(这里测试的 UWP 应用只是一个带有文本框的空白应用。所有这些 COM 加载都是由 TSF 发起的。)
另一个观察:在调用mscoree.dll
退出之后,内部的一个指针combase.dll
被设置为E_NOTIMPL
.
在同一个 UWP 应用程序中,可以毫无问题地加载和使用其他 3rd 方 IME 的 DLL(比如这个用 C++ 编写的https://github.com/rime/weasel )。我还没有测试官方示例,https://github.com/Microsoft/Windows-classic-samples/tree/master/Samples/IME ,但我很有信心它也会起作用。
我对正在发生的事情有一个粗略的了解,但我缺乏深入研究根本原因的专业知识:对于基于 .NET 的 COM 对象,会在请求 COM 对象时首先加载 CLR;但在这种情况下,对于 UWP,CLR 无法加载,随后 COM 对象无法启动。
我还使用了 Fusion Log(UWP 具有沉浸式模式),但没有看到任何相关消息。我想这是因为clr.dll
在我的情况下甚至没有加载。
谁能提供一些关于如何解决这个问题的想法?谢谢!
更新:当我在这篇文章中说“IME”时,我的意思是“使用文本服务框架 API 的文本服务”,而不是传统的“输入法管理器 (IMM)”基于 API 的 IME。