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.
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.
You certainly know that UWP apps are sand-boxed apps, they need a permission to do almost everything. For example, they can't access the entire file system, but only a sandboxed storage area.
When you want an app to be published in the Windows Store, the App Certification Kit checks that your app doesn't do what it is not allowed to do.
The link you provide (Win32 and COM for Windows Runtime apps...) describes a list of allowed WIN32/COM calls. Microsoft allows you to call these methods, and only them.
Using a Visual Basic COM Object seems to be out of reach...
This is about security restrictions, but also about available features: for example, there is no way to register a COM object on a Windows Phone (regsrvr32).
You can call any COM object (or Win32 API) in C# in a WPF application, and in C++ of course. Not sure what happens if you try to copy/paste this kind of code in a UWP app. You'll may be able to run the code on Windows Desktop, but you won't certainly be able to submit your app to the Windows Store, and it won't work on other UWP platforms. Microsoft doesn't give many details about calling COM objects from UWP app.
I guess that UWP is not very well suited/adapted/compatible with "old" COM objects... I'm not sure what this migration from WPF to UWP would bring you?
UWP or Windows Universal Application does not sound like the right solution here. UWP does not allow for COM because it is not available on all platforms. I am assuming that you would like to use the windows store for a deployment mechanism of your current WPF application. Windows 10 does offer what microsoft calls a bridge for WPF applications where you can deploy your WPF application as a appx package in the windows store.
Hopefully you will have very little to rewrite with this solution
For more information on how to Deploy a WPF application in an APPx file see the following video.
https://channel9.msdn.com/Events/Build/2015/2-692
On the other site, the UWP/ WinRT way seems the only way MS is going on there OS for security reasons.
I don't know if the Sandbox would be able to detect on a old school custom COM object called from allowed object a not allowed action. I hope this is possible for the Sandbox.