Using C++/WinRT dll in WPF with elevated rights application
Asked Answered
S

0

8

I have got WPF c# server application (WCF) and want to use c++/WinRT dynamic library inside it. I can simply do this by using UWP desktop bridge with WPF app and UWP empty app that includes my dll. This works fine for applications without elevated rights but WCF service require to run it as admin. I can achieve this by starting my application as admin or adding tags in projects manifest files (requireAdministrator for WPF and allowElevation for UWP).

My problem starts here as I get exception System.TypeLoadException with inner exception System.Runtime.InteropServices.COMException with code 0x80040154 (REGDB_E_CLASSNOTREG)) from System.StubHelpers.StubHelpers.GetWinRTFactoryObject(IntPtr pCPCMD) if I run app as admin.

This behavior is similar to what I get when I use c++/WinRT library without desktop bridge project. Is there any solution for such problem?

I compiled all projects against Windows 10 1809 (17763) build.

Edit:

I do not care about desktop bridge but it was only way that I could find to connect c# with c++/WinRT. What I want is to use classes exported through MSIDL to c# application.

Instruction to recreate this issue in VS 2017 (requirement is to have Windows 10 1809 or later):
1. To do so first install C++/WinRT projects templates from nuget.
2. Next create new project of Windows Runtime Component (C++/WinRT), chose target and minimum version of windows to 1809. You should get project with single class Class.
3. Now in same solution create C# WPF App project (Framework 4.7.2). In it add reference to runtime component project and set Copy Local to False for this reference. Use Class inside WPF project (ex. create field inside MainWindow class RuntimeComponent1.Class c = new RuntimeComponent1.Class();)
At this point both projects should be compilable but WPF project will throw an exception (TypeLoadException may be inner exception or root exception) at runtime. Also this step is what I want to achieved and all next steps are redundant for me but are necessary to create working application.
4. Next create Windows Universal Blank App (set platform versions to 1809) and as previous with WPF add reference to runtime component project and set Copy Local to False.
5. After that create Windows Application Packaging Project (target and minimum platform versions set to 1809), inside it to applications add both UWP and WPF Apps (it should be not possible to add library project). Set WPF app as Entry Point.
6. At this point Packaging project should be compilable and runnable without an error. Also it should be possible to run Packaging application as administrator from menu start but it will produce a runtime exception (TypeLoadException).
7. Finally to make application run by default with elevated rights add to WPF project Application Manifest File and change requestedExecutionLevel tag to <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />. Also inside Packaging project in Package.appxmanifest add <rescap:Capability Name="allowElevation" /> after <rescap:Capability Name="runFullTrust" />. This step require to build against 1809 as a minimum version.

After thous steps application will throw TypeLoadException (as root or inner exception depends how Class is used). To actually show it throwing something instead of just dying change WPF project type to console and then it will print exception for a brief moment before dying.

Smail answered 17/12, 2018 at 12:44 Comment(12)
It's unclear, what problem you are trying to solve. Do you actually need to use the Desktop Bridge (as opposed to simply consuming Windows Runtime types)?Ingoing
@Ingoing Yes, it is not possible to link c# framework (WPF) application against c++/winRT dll without desktop bridge as you will get runtime exception. My problem is described in second part of a question.Smail
C++/WinRT is not a technology. It is a library, capable of implementing Windows Runtime types (among others). You can link to Windows Runtime Components from native Desktop applications without using the Desktop Bridge (as long as the Windows Runtime types do not require app identity). I'm not a .NET developer, but I cannot think of a reason, why consuming Windows Runtime Components from C# would require the Desktop Bridge. I could be wrong, though.Ingoing
Er, no, that's not the problem. That's an issue you run into, when implementing your proposed solution.Ingoing
@Ingoing From my knowledge you are wron about c++/WinRT but I could be wrong too. I'm interested in solving this particular issue as it is convenient for me to use c++/WinRT lib with c# project. If you know how to run WPF application with c++/WinRT dll as administrator please write it as an answer.Smail
I am using Windows Runtime types in my desktop applications all the time, using C++/WinRT. All types with the DualApiPartitionAttribute are readily available, without even the need for an application manifest.Ingoing
@Ingoing did you actually try to use class from custom c++/WinRT dll inside c# desktop project?Smail
No, I haven't. I do know however, that .NET can P/Invoke, allowing it to discover and call into a component's exported factory, and that COM Interop exists. That's all a platform needs to consume a Windows Runtime Component.Ingoing
@Ingoing as I written in an edit I did not found another way to connect c++/WinRT to C# desktop application if you have something that could help me please write it as an answer.Smail
Do you have some repro code so we don't reinvent the wheel you're trying to get rolling?Electrify
@SimonMourier Sorry but no, my code is part of non open project. But I will provide steps to recreate my problem as it can be easily recreated.Smail
I do reproduce the problem at step 3) (independent from admin vs non admin).Electrify

© 2022 - 2024 — McMap. All rights reserved.