CLR 无法在 UWP 中创建基于 .NET 的 COM 对象

2024-05-23

我创建了一个类库(.NET Framework 4.7.1),它实现了文本服务(ITfTextInputProcessorEx等)中TSF https://msdn.microsoft.com/en-us/library/windows/desktop/ms629032(v=vs.85).aspx, using ComVisible属性。我注册它使用RegistrationServices它可以被系统成功识别为输入法 (IME),并且可以在除 UWP 应用程序之外的大多数应用程序中使用。

在 Win32 应用程序中使用

在 Win32 应用程序中(32 位notepad.exe例如),当我激活基于 .NET 的 TextService(通过切换到语言栏中的 IME)时,会发生以下情况:

enter image description here (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.)

基本上,在切换到我的 IME 后,TSF 框架(不是应用程序代码,而是在同一进程中运行)将尝试通过调用来创建/请求我的 TextService 的 COM 对象CoCreateObject。因为这不是本机 COM 对象,mscoree.dll实际上是注册表中的“真正的”COM DLL。mscoree.dll首先加载,然后加载mscoreei.dll, clr.dll等等,然后才最终加载实际的 .NET dll。

在AppContainer(UWP应用程序)中使用

现在,这些在普通桌面应用程序中都按预期工作,但在 UWP 应用程序中,相同的过程将在mscoree.dll and mscoreei.dll已加载(即clr.dll并且我的 .NET 程序集未加载)。调用堆栈如下所示:

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

另一个观察结果:在致电之后mscoree.dllquits,里面的指针之一combase.dll被设定为E_NOTIMPL.

在同一个 UWP 应用程序中,其他第 3 方 IME 的 DLL(例如这个)https://github.com/rime/weasel https://github.com/rime/weasel用 C++ 编写)可以毫无问题地加载和使用。我还没有测试官方的例子,https://github.com/Microsoft/Windows-classic-samples/tree/master/Samples/IME 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。


您不应该使用 .net 来编写 IME。我们只允许将单个版本的 .net 运行时加载到进程中。当您使用 .net 构建 IME 时,我们无法保证能够加载正确版本的运行时。因此,IME 可能会失败。您应该始终使用非托管 C++ 编写 IME 组件。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CLR 无法在 UWP 中创建基于 .NET 的 COM 对象 的相关文章

  • MSBuild 编译解决方案时找不到 SGen

    我在这里查看了其他几个与 SGen 相关的问题 要么他们的答案不适用 要么他们的答案不能为我解决这个问题 我安装了几个 SDK 来解决这个问题 但没有成功 不应更改引用类型 因为这是唯一出现问题的地方 一次建议是将 SGen exe 放入C
  • 为什么.NET Framework 4.0安装程序的大小小于3.0/3.5?

    我看到 Net Framework 4 0的beta2安装程序只有55MB 而 Net 3 5的安装程序有200 MB 这是怎么回事 NET 3 5 之所以这么大 是因为它在同一个包中包含 x64 版本的框架 2 0 3 0 软件包针对 x
  • 基于 Microsoft Word 模板生成 PDF 文档 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我需要一个 Word 文档 它是某种模板 收集用户输入以填充该模板中的特定字段 然后生成一个 PDF
  • 键入时自动滚动 DataGridView

    我遇到这个问题 DataGridView 中的最后一列太长 您需要使用滚动条来显示该列的其余部分 但是当我输入文本时 它不会在输入时自动滚动 我想要的是 我想在打字时自动滚动滚动条 以便用户在打字时不必使用滚动条 这是图像 As you c
  • 颜色变换器功能上的堆栈溢出错误

    我有两种颜色 红色 和 鲑鱼色 我需要动态创建面板以及面板背景颜色 这些颜色必须介于两种颜色之间 红色 public Color x y protected void Page Load object sender EventArgs e
  • 为什么在此单元测试中,BackgroundWorker 没有在正确的线程上调用 RunWorkerCompleted?

    backgroundWorker 的全部目的是在执行耗时的任务后更新 UI 组件正如广告所宣传的那样在我的 WPF 应用程序中 但是在我的测试中 回调不会在调用线程上调用 Test public void TestCallbackIsInv
  • 如果将其名称作为参数传递,如何在方法中打开表单

    我正在尝试创建一个标准方法来根据传递给它的参数打开表单 基本上 要完成此任务 using Quotes newQte new Quotes newQte ShowDialog 通过替换 Quotes with a passed parame
  • .NET 是否有相当于 Python 中的 **kwargs 的功能?

    我一直无法通过典型渠道找到这个问题的答案 在Python中我可以有以下函数定义 def do the needful kwargs Kwargs is now a dictionary i e do the needful spam 42
  • 如何在C#中使用默认浏览器打开带有锚点(#)的html文件

    我正在尝试在 C 中打开上下文帮助文件 当我没有指定锚点时 它工作得很好 Process Start C Help Help htm 但是当我指定锚点时 它不会打开 Process Start C Help Help htm Toc3420
  • 最新的反应式扩展 (Rx) 教程

    我对反应式扩展非常感兴趣 但我找不到最新的教程 我开始于使用 NET 响应式扩展消除异步忧郁症 http go microsoft com fwlink LinkId 208528但它已经过时了 我可以找出一些改变 但我无法让很多例子发挥作
  • 从 .resx 文件组获取所有可用区域性

    我需要以编程方式列出 resx 文件组中的可用区域性 但 ResourceManager 类似乎没有帮助 我可能有 Labels resx Labels fr FR resx Labels ro RO resx 等等 但是 我如何在运行时找
  • 找不到 OAuth2 参数

    我正在尝试使用 OAuth 2 0 来授权 google docs API 根据谷歌给出的例子https developers google com google apps documents list authorizing reques
  • 在 .Net 中创建 EPUB

    有没有可以用来在 NET C 中创建 epub 文件的库 Flowdocument gt epub 转换工具将是理想的选择 但任何类型的库都很棒 我还对评估编写一个程序的复杂程度感兴趣 我知道它基本上是一堆压缩的 XHTML 文件 但我不断
  • 在c#中创建sql连接

    我是这个网站的新手 也是编程的新手 我目前正在通过销售点创建库存系统 它使用模态和非模态形式 我的问题是 我正在研究change password对话框必须连接到数据库才能覆盖密码字段 我使用的数据库是Microsoft SQL Serve
  • 如何在不下载内容的情况下执行 GET 请求?

    我正在开发一个链接检查器 一般来说我可以执行HEAD请求 但是有些网站似乎禁用了这个动词 所以在失败时我还需要执行GET请求 仔细检查链接是否确实已失效 我使用以下代码作为我的链接测试器 public class ValidateResul
  • 数组与列表的性能

    假设您需要一个需要频繁迭代的整数列表 数组 我的意思是非常频繁 原因可能有所不同 但可以说它位于大容量处理的最内层循环的核心 一般来说 人们会选择使用列表 List 因为它们的大小具有灵活性 最重要的是 msdn 文档声称列表在内部使用数组
  • ELMAH 将其数据保存在哪里?

    我刚刚安装了 ELMAH MVC 更多信息here http nuget org packages Elmah MVC 并且想知道其数据保存在哪里 我读到您可以选择设置数据库进行存储 但似乎默认安装使用 内存中 它是如何工作的 如果我回收应
  • 在 Javascript 中本地化字符串

    我目前正在使用 resx文件来管理我的 NET 服务器端资源 我正在处理的应用程序还允许开发人员将 JavaScript 插入各种事件处理程序中以进行客户端验证等 对我来说本地化 JavaScript 消息和字符串的最佳方法是什么 理想情况
  • 检查列表是否包含另一个列表。 C#

    编辑 只是说 ContainsAllItem 中的注释解释得最好 很抱歉问这个问题 我知道以前有人问过这个问题 但我只是不明白 好的 所以我想检查一个列表是否包含另一个列表中的所有项目WITHOUT重叠 以及根据类字符串 名称变量 称为项目
  • 抽象类或接口。哪种方式是正确的?

    有两种方法可以选择抽象类或接口 微软解决方案和Oracle解决方案 微软 设计指南 请使用抽象 在 Visual Basic 中为 MustInherit 类而不是接口来将协定与实现分离 http msdn microsoft com en

随机推荐