How to create a COM object in a UWP application? (C#)

Nat picture Nat · Aug 17, 2015 · Viewed 12k times · Source

Question: How to create COM object in a Universal Windows Platform (UWP) application?

Motivation: I want to switch from WPF to UWP. Since my workload requires making calls to third-party libraries accessible only through COM (so far as I know), I need to make COM calls from UWP.

Context:

  • C#
  • .NET
  • Visual Studio 2015
  • Windows 10
  • Ideally targeting all UWP devices, but okay if restricted to desktops/laptops.

Background

In Visual Studio 2013 ("Classic Desktop" project in Visual Studio 2015), I used the C# code

// 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");

The Visual Studio project required a reference to Microsoft.VisualBasic to use Interaction.CreateObject() and the COM object's type library.

I want to use this C# code in a Universal Windows Platform (UWP) application produced by Visual Studio 2015 Enterprise on Windows 10 Education. I am able to add a reference to the COM object's type library, but unable to reference Microsoft.VisualBasic since it doesn't appear in Visual Studio's Reference Manager.

Thoughts, tried solutions, speculation, etc.

I added a reference to "Windows Desktop Extensions for the UWP" hoping that it might enable calls to normal .NET features, but haven't figured out how to use it yet.

I figure that even if UWP applications fundamentally can't make COM calls, then we could at least construct a wrapper that calls a normal .NET program (even if through network ports) that would in turn be able to run the COM call. Since it's clearly possible to work around even in the worst case scenario, I feel like there should be (and so probably is) a Microsoft-provided solution to making COM objects. But I guess since UWP's so new, the online documentation's pretty sparse and hard to find right now.

Update #1

Found an MSDN article, Win32 and COM for Windows Runtime apps and Universal Windows Platform (UWP) apps, that claims that WinRT apps (which includes UWP apps) can only use a subset of COM objects. MSDN suggests either using a supported COM API element or migrating from an unsupported COM API to a functional replacement.

I was able to find this article by googling a run-time error thrown after I found a way to make a COM call to my third-party library. The error:

An exception of type 'System.Runtime.InteropServices.COMException' occurred in mscorlib.ni.dll but was not handled in user code

Additional information: Creating an instance of the COM component with CLSID {[edit: GUID removed]} using CoCreateInstanceFromApp failed due to the following error: 80040154 Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)). Please make sure your COM object is in the allowed list of CoCreateInstanceFromApp.

I'm still unsure about whether or not there's a built-in way to access the COM API for my third-party libraries. If there's not, it may mean that I'll have to make my own wrapper using network ports or something, which seems wrong.

Answer

Rob Caplan - MSFT picture Rob Caplan - MSFT · Aug 17, 2015

As you note, it isn't possible to access arbitrary COM objects from a Universal Windows app. It is likely your third party libraries also use API which aren't available directly from within the Windows Runtime.

Assuming you intend to sideload the app rather than deploying through the store you can call your COM objects and libraries indirectly through a Brokered Windows Runtime Components for side-loaded Windows Store apps (docs for Windows 8.1 but still valid for Windows 10). This feature is designed for enterprise apps to provide a modern UI while still having access to existing functionality.

If you want to deploy through the store then you will stay restricted to the API allowed in the Windows Runtime context and can't use a Brokered Windows Runtime Component.

If your main goal is to deploy through the store and you don't need to otherwise convert to a Universal app then take a look at the upcoming Windows Bridge for Classic Windows apps (also called ”Project Centennial”) which will allow packaging your current .Net project for store deployment and will allow extending it to use some UWP capabilities.