如何在UWP应用程序中创建COM对象?(C#)

14

问题: 如何在通用 Windows 平台 (UWP) 应用程序中创建 COM 对象?

动机: 我想从 WPF 切换到 UWP。由于我的工作负载需要调用只能通过 COM 访问的第三方库(据我所知),因此我需要从 UWP 进行 COM 调用。

上下文:

  • C#
  • .NET
  • Visual Studio 2015
  • Windows 10
  • 最好是针对所有 UWP 设备,但如果仅限于桌面/笔记本电脑也可以接受。

背景

在 Visual Studio 2013(Visual Studio 2015 中的“经典桌面”项目)中,我使用了以下 C# 代码:

// Conceptual:
DotNetInterface comObjectInstance =
    (DotNetInterface)Microsoft.VisualBasic.Interaction.CreateObject(
        "this string specified the COM object type"
      );

// Example:  Open Excel via COM:
Excel.Application oApp = (Excel.Application)Interaction.CreateObject("Excel.Application");
Visual Studio项目需要引用 Microsoft.VisualBasic 才能使用Interaction.CreateObject()和COM对象的类型库。 我想在Windows 10 Education上由Visual Studio 2015 Enterprise生成的通用Windows平台(UWP)应用程序中使用此C#代码。 我可以添加对COM对象类型库的引用,但无法引用Microsoft.VisualBasic,因为它不出现在Visual Studio的“引用管理器”中。

我已经添加了对“UWP的Windows桌面扩展”的引用,希望它能够启用对常规.NET功能的调用,但是还没有弄清楚如何使用它。即使UWP应用程序从根本上不能进行COM调用,我认为我们仍然可以构建一个调用正常.NET程序的包装器(即使通过网络端口),该程序将能够运行COM调用。既然明显可以在最坏的情况下解决问题,我觉得应该有(因此可能有)微软提供的解决方案来制作COM对象。但是我猜因为 UWP 很新,网上文档非常稀少且难以找到。

更新#1

找到了MSDN文章“用于Windows运行时应用程序和通用Windows平台(UWP)应用程序的Win32和COM”,它声称WinRT应用程序(包括UWP应用程序)仅能使用COM对象的子集。 MSDN建议使用受支持的COM API元素,或从不受支持的COM API迁移到功能替代品。

我通过搜索运行时错误找到了这篇文章,该错误在我找到一种方法调用第三方库后引发:

类型为'System.Runtime.InteropServices.COMException'的异常在mscorlib.ni.dll中发生,但未在用户代码中处理

其他信息:使用CoCreateInstanceFromApp创建具有CLSID {[edit:已删除GUID]}的COM组件实例失败,由于以下错误:80040154类未注册(来自HRESULT的异常:0x80040154(REGDB_E_CLASSNOTREG))。 请确保您的COM对象处于CoCreateInstanceFromApp的允许列表中。



我仍然不确定是否有内置的方法可以访问我的第三方库的COM API。 如果没有,这可能意味着我将不得不使用网络端口之类的东西制作自己的包装器,这似乎是错误的。
4个回答

17

正如您所指出的那样,通用Windows应用程序无法访问任意COM对象。很可能您的第三方库也使用了在Windows Runtime内部无法直接使用的API。

假设您打算通过侧载应用程序而非通过商店部署,则可以通过针对侧载Windows Store应用程序的代理Windows Runtime组件(适用于Windows 8.1但仍适用于Windows 10)间接调用COM对象和库。此功能旨在为企业应用程序提供现代UI,同时仍可访问现有功能。

如果您要通过商店发布,则将受限于Windows Runtime上下文中允许使用的API,并且不能使用代理Windows Runtime组件。

如果您的主要目标是通过商店部署而且不需要转换为通用应用程序,那么请查看即将推出的经典Windows应用程序的Windows桥梁(也称为“Centennial项目”),它将允许将当前的.NET项目打包以进行商店部署,并允许扩展以使用一些UWP功能。


你说的很对,重点是企业应用,所以无法使用商店并不关键。感谢提供 Brokered Windows Runtime Components 的链接 - 这正是我在寻找的! - Nat
2
我已经为通用Windows应用程序创建了一个代理组件模板。请在此处查看我的帖子:https://xamltips.wordpress.com/2015/11/13/brokered-component-for-uwp-on-windows-10/ - Lance

1
您一定知道UWP应用程序是沙盒应用程序,它们需要获得许可才能执行几乎所有操作。例如,它们不能访问整个文件系统,只能访问一个沙盒存储区域。 当您希望应用程序在Windows Store中发布时,应用程序认证工具会检查您的应用程序是否执行了不允许的操作。
提供的链接(Win32和COM用于Windows Runtime应用程序...)描述了一系列允许的WIN32 / COM调用。Microsoft允许您调用这些方法,并且仅限于这些方法。
使用Visual Basic COM对象似乎是无法实现的...
这涉及安全限制,也涉及可用功能:例如,在Windows Phone上无法注册COM对象(regsrvr32)。
你可以在WPF应用程序中使用C#调用任何COM对象(或Win32 API),当然也可以使用C ++。不确定如果您尝试将此类代码复制/粘贴到UWP应用程序中会发生什么。您可能能够在Windows桌面上运行代码,但您肯定无法将应用程序提交到Windows Store,并且它将无法在其他UWP平台上工作。Microsoft关于从UWP应用程序调用COM对象并没有提供太多详细信息。 我猜UWP并不适合/适应/兼容“旧”的COM对象...我不确定从WPF迁移到UWP会给您带来什么?

0

在这里,UWP或Windows通用应用程序似乎不是正确的解决方案。由于并非所有平台都支持COM,因此UWP不允许使用COM。我假设您想要使用Windows商店作为当前WPF应用程序的部署机制。Windows 10确实提供了Microsoft所称的WPF应用程序桥接,您可以将WPF应用程序部署为Windows商店中的appx包。

希望您在此解决方案中需要重新编写的内容很少。

有关如何在APPx文件中部署WPF应用程序的更多信息,请参见以下视频。 https://channel9.msdn.com/Events/Build/2015/2-692


0

另一方面,出于安全原因,UWP/WinRT方式似乎是微软在其操作系统上前进的唯一方式。我不知道沙盒是否能够检测到从允许对象调用的老式自定义COM对象中的不允许操作。我希望沙盒能够实现这一点。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接