CLR无法在UWP中创建基于.NET的COM对象 [英] CLR cannot create .NET-based COM objects in UWP

查看:93
本文介绍了CLR无法在UWP中创建基于.NET的COM对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个类库(.NET Framework 4.7.1),该类库在
(带圆圈的 YngPing.TSF.dll 是.NET程序集,其中包含COM对象。由COM对象创建引起的加载从#56开始。)



基本上,在切换到IME时,TSF框架(不是应用程序)代码,但在同一进程中运行)将尝试通过调用 CoCreat创建/请求我的TextService的COM对象。 eObject 。因为这不是本机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应用中,其他第三方IME的DLL(例如一个 https://github.com/rime/可以使用C ++编写的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的文本服务,



解决方案

您,而不是基于API的旧版输入法管理器(IMM)。不应使用.net编写IME。我们仅允许将.net运行时的单个版本加载到进程中。使用.net构建IME时,我们不能保证能够加载正确版本的运行时。因此,IME可能会失败。您应该始终使用非托管C ++编写IME组件。


I have created a Class Library (.NET Framework 4.7.1) that implements a Text Service (ITfTextInputProcessorEx etc.) in TSF, using ComVisible attribute. I registered it using RegistrationServices and it can be successfully recognised by the system as an Input Method (IME) and can be used in most applications, except UWP apps.

Using in Win32 app

In a Win32 app (the 32-bit notepad.exe for example), here is what happens when I activate my .NET-based TextService (by switching to the IME in the language bar):

(The circled YngPing.TSF.dll is the .NET assembly that contains the implementation of the COM object. The loading caused by COM object creation starts at #56.)

Basically, upon switching to my IME, the TSF framework (not the application code, but running in the same process) will try to create/request a COM object of my TextService by calling CoCreateObject. Because this not a native COM object, mscoree.dll is actually the "real" COM DLL that is in the registry. mscoree.dll first gets loaded, then it loads mscoreei.dll, clr.dll etc., before finally loading the actual .NET dll.

Using in AppContainer (UWP app)

Now these all works as expected in normal Desktop apps, but in an UWP app, the same process will stop after mscoree.dll and mscoreei.dll are loaded (i.e. clr.dll and my .NET assembly are not loaded). The call stack looks like this:

(The UWP app tested here is just an blank app with a textbox. All these COM loading are all initiated by the TSF.)

Another observation: after the calls to mscoree.dll quits, one of the pointers inside combase.dll is set to E_NOTIMPL.

In the same UWP app, DLLs of other 3rd party IMEs (like this one https://github.com/rime/weasel written in C++) can be loaded and used without problem. I am yet to test the official example, https://github.com/Microsoft/Windows-classic-samples/tree/master/Samples/IME but I am pretty confident it will work too.


I have a rough idea of what's going on, but I lack the expertise to dive deeper into the root cause: what happens is for .NET-based COM objects, the CLR is loaded first when the COM object is requested; but in this case for UWP, the CLR somehow failed to load and subsequently the COM object cannot be initiated.

I also used Fusion Log (with immersive mode for UWP) but did not see any related messages. I guess it is because even clr.dll is not loaded in my case.

Can anyone offer some ideas as to how to solve this problem? Thanks!

Update: When I say "IME" in this post, I mean "a Text Service using the Text Service Framework API", not the legacy "Input Method Manager (IMM)" API-based IMEs.

解决方案

You shouldn’t be using .net to write an IME. We only allow a single version of the .net runtime to be loaded into a process. When you build an IME with .net we cannot guarantee that we will be able to load the correct version of the runtime. Because of this the IME may fail. You should always write your IME components using unmanaged C++.

这篇关于CLR无法在UWP中创建基于.NET的COM对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆