Как создать COM-объект в приложении UWP? (С#)

Вопрос: Как создать COM-объект в приложении Universal Windows Platform (UWP)?

Мотивация: Я хочу переключиться с WPF на UWP. Поскольку моя рабочая нагрузка требует обращения к сторонним библиотекам, доступным только через COM (насколько я знаю), мне нужно сделать COM-вызовы из UWP.

Контекст:

  • С#
  • .NET
  • Visual Studio 2015
  • Windows 10
  • Идеально ориентировать все устройства UWP, но в любом случае, если они ограничены рабочими столами/ноутбуками.

Фон

В Visual Studio 2013 (проект "Классический рабочий стол" в Visual Studio 2015) я использовал код С#

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

Для проекта Visual Studio требуется ссылка на Microsoft.VisualBasic для использования Interaction.CreateObject() и библиотеки типов объектов COM.

Я хочу использовать этот код С# в приложении Universal Platform (UWP), создаваемом Visual Studio 2015 Enterprise для Windows 10 Education. Я могу добавить ссылку на библиотеку типов объектов COM, но не могу ссылаться на Microsoft.VisualBasic, так как она не отображается в диспетчере ссылок Visual Studio.

Мысли, опробованные решения, спекуляции и т.д.

Я добавил ссылку на "Расширения рабочего стола Windows для UWP", надеясь, что он сможет разрешать обычные функции .NET, но пока не понял, как использовать его.

Я полагаю, что даже если приложения UWP принципиально не могут выполнять COM-вызовы, мы могли бы хотя бы построить оболочку, которая вызывает обычную .NET-программу (даже если через сетевые порты), которая, в свою очередь, сможет запускать COM вызов. Поскольку явная возможность работать даже в худшем случае, я чувствую, что должно быть (и, вероятно, это) решение, предоставленное Microsoft для создания COM-объектов. Но я предполагаю, что UWP настолько новый, онлайн-документация довольно редкая и трудно найти прямо сейчас.

Обновление # 1

Нашел статью MSDN, приложения Win32 и COM для Windows Runtime и приложения для универсальной платформы Windows (UWP), в которых утверждается, что приложения WinRT (которые включает приложения UWP) может использовать только подмножество COM-объектов. MSDN предлагает либо использовать поддерживаемый COM API-элемент, либо переносить с неподдерживаемого COM API на функциональную замену.

Мне удалось найти эту статью, перейдя по ошибке во время выполнения, после того, как я нашел способ сделать COM-вызов моей сторонней библиотеке. Ошибка:

Исключение типа 'System.Runtime.InteropServices.COMException' произошел в mscorlib.ni.dll, но не был обработан в коде пользователя

Дополнительная информация: создание экземпляра COM-компонента с помощью CLSID {[edit: GUID удален]}, используя Ошибка CoCreateInstanceFromApp из-за следующей ошибки: 80040154 Класс не зарегистрирован (Исключение из HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)). Убедитесь, что ваш COM-объект находится в разрешенный список CoCreateInstanceFromApp.

Я все еще не уверен, есть ли встроенный способ доступа к COM API для моих сторонних библиотек. Если это не так, это может означать, что мне придется сделать свою собственную оболочку, используя сетевые порты или что-то еще, что кажется неправильным.

Ответ 1

Как вы заметили, невозможно получить доступ к произвольным объектам COM из приложения Universal Windows. Вероятно, ваши сторонние библиотеки также используют API, которые недоступны непосредственно из среды выполнения Windows.

Предполагая, что вы намерены отклонять приложение, а не развертывать через хранилище, вы можете называть свои COM-объекты и библиотеки косвенно через Компоненты исполняемой среды Windows для загруженных приложений Windows Store (документы для Windows 8.1, но все еще действительные для Windows 10). Эта функция предназначена для корпоративных приложений для обеспечения современного пользовательского интерфейса при наличии доступа к существующим функциям.

Если вы хотите развернуть через хранилище, вы останетесь ограниченным API, разрешенным в контексте Windows Runtime, и не сможете использовать компонент Runtime для Brokered Windows.

Если ваша главная цель - развернуть через магазин, и вам не нужно иначе конвертировать в универсальное приложение, посмотрите на предстоящий Windows Bridge для классических приложений Windows ( также называемый "Project Centennial" ), который позволит упаковать ваш текущий проект .Net для развертывания магазина и позволит расширить его для использования некоторых возможностей UWP.

Ответ 2

Вы, конечно, знаете, что приложения UWP представляют собой приложения с песочницей, им нужно разрешение на выполнение почти всего. Например, они не могут получить доступ ко всей файловой системе, а только к изолированной области хранения. Когда вы хотите, чтобы приложение было опубликовано в Windows Store, набор сертификатов приложений проверяет, что ваше приложение не делает то, что ему не разрешено делать.

Предоставляемая вами ссылка (Win32 и COM для приложений Runtime для Windows...) описывает список разрешенных вызовов WIN32/COM. Microsoft позволяет вам вызывать эти методы и только их.

Использование COM-объекта Visual Basic, кажется, вне досягаемости...

Это касается ограничений безопасности, но также и о доступных возможностях: например, нет способа зарегистрировать COM-объект на Windows Phone (regsrvr32).

Вы можете вызывать любой COM-объект (или Win32 API) на С# в приложении WPF и, конечно же, на С++. Не уверен, что произойдет, если вы попытаетесь скопировать/вставить этот тип кода в приложение UWP. Возможно, вы сможете запустить код на Windows Desktop, но вы, конечно же, не сможете отправить свое приложение в Windows Store, и он не будет работать на других платформах UWP. Microsoft не дает много подробностей о вызове COM-объектов из приложения UWP.

Я думаю, что UWP не очень хорошо подходит/адаптирован/совместим со "старыми" COM-объектами... Я не уверен, что принесет вам этот переход из WPF в UWP?

Ответ 3

UWP или Windows Universal Application не похоже на правильное решение здесь. UWP не разрешает COM, потому что он недоступен на всех платформах. Я предполагаю, что вы хотели бы использовать хранилище Windows для механизма развертывания вашего текущего приложения WPF. Windows 10 предлагает то, что microsoft вызывает мост для приложений WPF, где вы можете развернуть свое приложение WPF в виде пакета appx в хранилище Windows.

Надеюсь, вам будет очень мало, чтобы переписать это решение

Дополнительные сведения о развертывании приложения WPF в файле APPx см. в следующем видео. https://channel9.msdn.com/Events/Build/2015/2-692

Ответ 4

На другом сайте способ UWP/WinRT кажется единственным способом, по которому MS собирается там ОС по соображениям безопасности. Я не знаю, сможет ли песочница обнаружить на старом школьном пользовательском объекте COM, вызванном из разрешенного объекта, недопустимое действие. Я надеюсь, что это возможно для Песочницы.