我有WPF c#服务器应用程序(WCF),并希望在其中使用c ++ / WinRT动态库。我可以通过将WWP应用程序和包含我的dll的UWP空应用程序使用UWP桌面桥来简单地做到这一点。对于没有提升权限的应用程序来说,这很好用,但是WCF服务需要以管理员身份运行它。我可以通过以管理员身份启动应用程序或在项目清单文件中添加标签(对于WPF为requireAdministrator
,对于UWP为allowElevation
)来实现此目的。
我的问题从这里开始,如果我以管理员身份运行应用程序,则会从System.TypeLoadException
获得异常System.Runtime.InteropServices.COMException
和内部异常0x80040154 (REGDB_E_CLASSNOTREG))
,并且代码为System.StubHelpers.StubHelpers.GetWinRTFactoryObject(IntPtr pCPCMD)
。
此行为类似于在不使用桌面桥项目的情况下使用c ++ / WinRT库时得到的行为。有什么解决办法吗?
我针对Windows 10 1809(17763)版本编译了所有项目。
编辑:
我不在乎桌面桥,但这是我可以找到的将c#与c ++ / WinRT连接的唯一方法。我想要的是使用通过MSIDL导出到c#应用程序的类。
在VS 2017中重新创建此问题的说明(要求具有Windows 10 1809或更高版本):
1。为此,请先从nuget安装C ++ / WinRT项目模板。
2。接下来创建Windows运行时组件(C ++ / WinRT)的新项目,选择Windows的目标版本和最低版本为1809。您应该获得具有单个类Class
的项目。
3。现在,在同一解决方案中,创建C#WPF App项目(框架4.7.2)。在其中添加对运行时组件项目的引用,并将此引用的“复制本地”设置为False。在WPF项目中使用Class
(例如,在MainWindow
类RuntimeComponent1.Class c = new RuntimeComponent1.Class();
类中创建字段)
此时,两个项目都应可编译,但是WPF项目将在运行时引发异常(TypeLoadException可能是内部异常或根异常)。同样,这也是我要实现的步骤,所有后续步骤对我来说都是多余的,但对于创建有效的应用程序而言是必需的。
4。接下来创建Windows Universal Blank App(将平台版本设置为1809),并像以前一样使用WPF添加对运行时组件项目的引用,并将“复制本地”设置为False。
5。创建Windows应用程序打包项目(目标和最低平台版本设置为1809)之后,在其内部向应用程序添加UWP和WPF应用程序(应该不可能添加库项目)。将WPF应用设置为入口点。
6。此时,Packaging项目应该是可编译且可运行的,没有错误。另外,应该可以从菜单开始以管理员身份运行Packaging应用程序,但是它将产生运行时异常(TypeLoadException)。
7。最后,要使应用程序默认以提升的权限运行,请添加到WPF项目“应用程序清单文件”,并将requestedExecutionLevel
标记更改为<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
。同样在Package.appxmanifest的Packaging项目中,在<rescap:Capability Name="allowElevation" />
之后添加<rescap:Capability Name="runFullTrust" />
。此步骤要求以最低版本1809为基础。
在执行此步骤后,应用程序将引发TypeLoadException(因为根异常或内部异常取决于Class的使用方式)。为了真正显示它抛出的东西而不仅仅是死掉,将WPF项目类型更改为控制台,然后在死掉之前短暂地打印异常。