Использование C ++ / WinRT dll в WPF с приложением с повышенными правами - PullRequest
0 голосов
/ 17 декабря 2018

У меня есть серверное приложение WPF c # (WCF) и я хочу использовать внутри него динамическую библиотеку c ++ / WinRT.Я могу просто сделать это, используя настольный мост UWP с приложением WPF и пустое приложение UWP, которое включает в себя мою DLL.Это прекрасно работает для приложений без повышенных прав, но служба WCF требует, чтобы она запускалась от имени администратора.Я могу добиться этого, запустив приложение в качестве администратора или добавив теги в файлы манифеста проектов (requireAdministrator для WPF и allowElevation для UWP).

Моя проблема начинается здесь, когда я получаю исключение 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.Для этого сначала установите шаблоны проектов C ++ / WinRT из nuget.
2.Затем создайте новый проект Windows Runtime Component (C ++ / WinRT), выберите цель и минимальную версию Windows до 1809. Вы должны получить проект с одним классом Class.
3.Теперь в том же решении создайте проект C # WPF App (Framework 4.7.2).В ней добавьте ссылку на проект компонента времени выполнения и установите для этой ссылки значение «Копировать локально» на «Ложь».Используйте Class внутри проекта WPF (например, поле create внутри MainWindow class RuntimeComponent1.Class c = new RuntimeComponent1.Class();)
На этом этапе оба проекта должны быть скомпилированы, но проект WPF сгенерирует исключение (TypeLoadException может быть внутренним или корневым исключением) вво время выполнения.Также этот шаг - то, чего я хочу достичь, и все последующие шаги для меня излишни, но необходимы для создания работающего приложения.
4.Затем создайте универсальное пустое приложение Windows (установите версию платформы на 1809) и, как и в предыдущем случае с WPF, добавьте ссылку на проект компонента времени выполнения и установите для параметра «Копировать локально» значение «Ложь».
5.После этого создайте проект упаковки приложений Windows (для целевой и минимальной версий платформы установлено значение 1809), внутри него к приложениям добавьте приложения как UWP, так и WPF (не должно быть возможности добавить проект библиотеки).Установите приложение WPF в качестве точки входа.
6.На этом этапе упаковочный проект должен быть компилируемым и запускаемым без ошибок.Также должно быть возможно запустить приложение Packaging от имени администратора из меню, но оно вызовет исключение времени выполнения (TypeLoadException).
7.Наконец, чтобы приложение запускалось по умолчанию с повышенными правами, добавьте в проект файла манифеста приложения WPF и измените тег requestedExecutionLevel на <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />.Также внутри упаковочного проекта в Package.appxmanifest добавьте <rescap:Capability Name="allowElevation" /> после <rescap:Capability Name="runFullTrust" />.Для этого шага требуется сборка с минимальной версией 1809.

После этих шагов приложение выдаст исключение TypeLoadException (поскольку корневое или внутреннее исключение зависит от того, как используется класс).Чтобы показать, что он выбрасывает что-то, а не просто умирает, измените тип проекта WPF на консоль, а затем он на короткое время выведет исключение перед смертью.

...