Как я могу запустить приложение UWP (Xaml) из приложения Core в своем собственном потоке? - PullRequest
0 голосов
/ 17 сентября 2018

Я хотел бы, чтобы и приложение UWP xaml (называемое my_xaml_app), и приложение UWP Core (называемое my_core_app) работали в одной и той же программе в своем соответствующем потоке.

До сих пор я пробовал следующий подход:

my_core_app::my_core_app()
{
    ViewProviderFactory viewProviderFactory;
    winrt::Windows::ApplicationModel::Core::CoreApplication::Run(viewProviderFactory);
}

winrt::Windows::Foundation::IAsyncAction init_core_app()
 {
        co_await winrt::resume_background();
        my_core_app coreApp;
 }

int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int)
{
      init_core_app();

      winrt::Windows::UI::Xaml::Application::Start(
      [](auto &&)
      {
          winrt::make<winrt::my_xaml_app::implementation::App>();
      });

      return 0;
 }

Я не включил детали того, как создаются экземпляры my_core_app и my_xaml_app, но вы можете предположить, что они работают правильно, так как они запускаются правильно, если я запускаю их самостоятельно из основного потока.

В приведенном выше коде my_xaml_app запускается правильно, потому что он вызывается из основного потока. Однако my_core_app не запускается и сообщает о следующих ошибках:

WinRT originate error - 0x8001010E : 'The Application Object must initially be accessed from the multi-thread apartment.'.

The application called an interface that was marshalled for a different thread.

Microsoft C++ exception: winrt::hresult_wrong_thread at memory location 0x00000040E4EFE6E8

Возможно ли это, и если да, то как это можно сделать?

Ответы [ 2 ]

0 голосов
/ 15 октября 2018

Сообщение об ошибке показывает внутреннюю часть работы COM-квартир. Один процесс может иметь только одну квартиру MTA. Невозможно иметь два потока MTA в одном и том же процессе.

Тем не менее, вы можете запустить приложение в другом процессе, и это будет работать.

0 голосов
/ 17 сентября 2018

для первоначальной инициализации из основного потока вы можете использовать CoreDispatcher

ниже приведен пример кода из документов по запуску приложения из CoreDispatcher

// App.cpp
...
// An implementation of IFrameworkView::Run.
void Run()
{
    CoreWindow window{ CoreWindow::GetForCurrentThread() };
    window.Activate();

    CoreDispatcher dispatcher{ window.Dispatcher() };
    dispatcher.ProcessEvents(CoreProcessEventsOption::ProcessUntilQuit);
}

// The CoreApplication::Run call indirectly calls the App::Run function above.
int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int)
{
    CoreApplication::Run(App());
}
...