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

Posted

技术标签:

【中文标题】如何在 UWP 应用程序中创建 COM 对象? (C#)【英文标题】:How to create a COM object in a UWP application? (C#) 【发布时间】:2015-11-09 14:44:20 【问题描述】:

问题:如何在通用 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 文章 Win32 and COM for Windows Runtime apps and Universal Windows Platform (UWP) apps,声称 WinRT 应用(包括 UWP 应用)只能使用 COM 对象的子集。 MSDN 建议要么使用受支持的 COM API 元素,要么从不受支持的 COM API 迁移到功能替代品。

我可以通过谷歌搜索在找到对我的第三方库进行 COM 调用的方法后引发的运行时错误来找到这篇文章。错误:

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

附加信息:使用以下命令创建 COM 组件的实例 CLSID [edit: GUID removed] 使用 CoCreateInstanceFromApp 由于以下错误而失败:80040154 类未注册(HRESULT 异常:0x80040154 (REGDB_E_CLASSNOTREG))。请确保您的 COM 对象位于 允许的 CoCreateInstanceFromApp 列表。

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

【问题讨论】:

【参考方案1】:

如您所述,无法从通用 Windows 应用程序访问任意 COM 对象。很可能您的第三方库也使用了在 Windows 运行时中无法直接使用的 API。

假设您打算旁加载应用程序而不是通过应用商店进行部署,您可以通过 Brokered Windows Runtime Components for side-loaded Windows Store apps 间接调用您的 COM 对象和库(文档适用于 Windows 8.1,但仍适用于 Windows 10)。此功能专为企业应用而设计,可提供现代 UI,同时仍可访问现有功能。

如果您想通过应用商店进行部署,那么您将受限于 Windows 运行时上下文中允许的 API,并且不能使用代理的 Windows 运行时组件。

如果您的主要目标是通过商店进行部署,并且您不需要转换为通用应用程序,那么请查看即将推出的 Windows Bridge for Classic Windows apps (also called ”Project Centennial”),它将允许打包您当前的 .Net 项目以进行商店部署,并将允许对其进行扩展以使用某些 UWP 功能。

【讨论】:

您对企业应用的关注是正确的,因此无法使用应用商店并不重要。感谢您提供指向代理 Windows 运行时组件的链接 - 这正是我想要的! 我为通用 Windows 应用程序的代理组件创建了一个模板。在这里查看我的帖子xamltips.wordpress.com/2015/11/13/…【参考方案2】:

您当然知道 UWP 应用是沙盒应用,它们需要权限才能执行几乎所有操作。例如,他们无法访问整个文件系统,而只能访问沙盒存储区域。 当您希望在 Windows 应用商店中发布应用时,应用认证工具包会检查您的应用没有做不允许做的事情。

您提供的链接(Windows 运行时应用程序的 Win32 和 COM...)描述了允许的 WIN32/COM 调用的列表。 Microsoft 允许您调用这些方法,并且只允许调用它们。

使用 Visual Basic COM 对象似乎遥不可及...

这与安全限制有关,但也与可用功能有关:例如,无法在 Windows Phone (regsrvr32) 上注册 COM 对象。

您可以在 WPF 应用程序中使用 C# 使用 call any COM object (or Win32 API),当然也可以使用 C++。不确定如果您尝试在 UWP 应用中复制/粘贴此类代码会发生什么。您可能能够在 Windows 桌面上运行代码,但您肯定无法将您的应用提交到 Windows 应用商店,并且它无法在其他 UWP 平台上运行。微软doesn't give many details about calling COM objects from UWP app。

我猜 UWP 不太适合/适应/兼容“旧” COM 对象...我不确定从 WPF 迁移到 UWP 会给您带来什么?

【讨论】:

【参考方案3】:

UWP 或 Windows 通用应用程序在这里听起来不像是正确的解决方案。 UWP 不允许 COM,因为它并非在所有平台上都可用。我假设您希望将 Windows 商店用于当前 WPF 应用程序的部署机制。 Windows 10 确实提供了微软所说的 WPF 应用程序的桥梁,您可以在其中将 WPF 应用程序部署为 Windows 商店中的 appx 包。

希望你用这个解决方案几乎不需要重写

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

【讨论】:

【参考方案4】:

在另一个站点上,出于安全原因,UWP/WinRT 方式似乎是 MS 在操作系统上运行的唯一方式。 我不知道沙盒是否能够在从允许对象调用的旧式自定义 COM 对象上检测到不允许的操作。我希望沙盒可以做到这一点。

【讨论】:

以上是关于如何在 UWP 应用程序中创建 COM 对象? (C#)的主要内容,如果未能解决你的问题,请参考以下文章

如何在UWP App中创建信息丰富的Toast通知

在 UWP 应用中创建使用调试 App Service (应用服务)

允许在 UWP 中创建的 PWA 在最小化时不处于非活动状态

如何在 C++ 中创建一个公开返回对象的函数的 COM Dll?

在 Xamarin UWP 中创建包后,视频只能用语音播放,我看不到视频

在 Visual Studio 2015 中创建后未构建 Xamarin UWP 项目