MS Edge: встроенный обмен сообщениями

Наряду с чтением этой документации я пытаюсь реализовать расширение Edge-Browser для нативного обмена сообщениями для вызова стандартного настольного приложения с использованием Windows.System.Launcher.LaunchFileAsync,

Я явно не пытаюсь реализовать расширение с помощью AppService с использованием Background-Task, так как мне нужно убедиться, что LaunchFileAsync выполняется в главном потоке пользовательского интерфейса. Следовательно, я хочу использовать OnBackgroundActiviated на основной компонент приложения напрямую.

В упомянутой выше документации говорится, что превращение расширения на основе приложения в расширение в процессе выполняется путем удаления атрибута "EntryPoint" из тега приложения в манифесте пакета. Однако после этого описания Visual Studio 2017 выдает ошибку, что расширение не может быть зарегистрировано (DEP0700, 0x80073CF6 windows.appService: Element not found).

Добавление EntryPoint Атрибут тега AppService приводит к исчезновению этого сообщения об ошибке, но я не могу получить OnBackgroundActivated стрелять

Вот мой манифест пакета:

    <?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3" IgnorableNamespaces="uap mp">
  <Identity Name="0d2a700c-9f88-4445-8250-a3e82aedb1d2" Publisher="CN=Sebastian Blessing" Version="1.0.0.0" />
  <mp:PhoneIdentity PhoneProductId="0d2a700c-9f88-4445-8250-a3e82aedb1d2" PhonePublisherId="00000000-0000-0000-0000-000000000000" />
  <Properties>
    <DisplayName>edgeextension</DisplayName>
    <PublisherDisplayName>Sebastian Blessing</PublisherDisplayName>
    <Logo>Assets\StoreLogo.png</Logo>
  </Properties>
  <Dependencies>
    <TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
  </Dependencies>
  <Resources>
    <Resource Language="x-generate" />
  </Resources>
  <Applications>
    <Application Id="App" Executable="$targetnametoken$.exe">
      <uap:VisualElements AppListEntry="none" DisplayName="edgeextension" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png" Description="abs.mira.edgeextension" BackgroundColor="transparent">
        <uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png">
        </uap:DefaultTile>
        <uap:SplashScreen Image="Assets\SplashScreen.png" />
      </uap:VisualElements>
      <Extensions>
        <uap:Extension Category="windows.appService">
          <uap:AppService Name="EdgeExtensionRuntime" />
        </uap:Extension>
        <uap3:Extension Category="windows.appExtension">
          <uap3:AppExtension Name="com.microsoft.edge.extension" Id="EdgeExtensionRuntime" PublicFolder="Extension" DisplayName="ms-resource:DisplayName">
            <uap3:Properties>
              <Capabilities>
                <Capability Name="browserStorage" />
              </Capabilities>
            </uap3:Properties>
          </uap3:AppExtension>
        </uap3:Extension>
      </Extensions>
    </Application>
  </Applications>
  <Capabilities>
    <Capability Name="internetClient" />
    <Capability Name="internetClientServer" />
  </Capabilities>
</Package>

Можете ли вы указать мне на потенциальную проблему этого файла манифеста? Класс приложения реализован как App в файле App.xaml.cs а также реализует OnBackgroundActivatedи вот код:

using System;
using Windows.ApplicationModel;
using Windows.Foundation.Collections;
using Windows.ApplicationModel.Activation;
using Windows.ApplicationModel.AppService;
using Windows.ApplicationModel.Background;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
using Newtonsoft.Json;

namespace edgeextension
{
    sealed partial class App : Application
    {
        private BackgroundTaskDeferral appServiceDeferral = null;
        private AppServiceConnection appServiceConnection;

        public App()
        {
            this.InitializeComponent();
            this.Suspending += OnSuspending;
        }

        protected override void OnBackgroundActivated(BackgroundActivatedEventArgs args)
        {
            base.OnBackgroundActivated(args);
            IBackgroundTaskInstance taskInstance = args.TaskInstance;
            AppServiceTriggerDetails appService = taskInstance.TriggerDetails as AppServiceTriggerDetails;
            appServiceDeferral = taskInstance.GetDeferral();
            taskInstance.Canceled += OnAppServicesCanceled;
            appServiceConnection = appService.AppServiceConnection;
            appServiceConnection.RequestReceived += OnAppServiceRequestReceived;
            appServiceConnection.ServiceClosed += AppServiceConnection_ServiceClosed;
        }

        private async void OnAppServiceRequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args)
        {
            AppServiceDeferral messageDeferral = args.GetDeferral();

            try
            {
                //Has to run on the UI-Thread !!                       
                await Windows.System.Launcher.LaunchFileAsync(...);
            }
            finally
            {
                messageDeferral.Complete();
            }
        }

        private void OnAppServicesCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
        {
            this.appServiceDeferral.Complete();

        }

        private void AppServiceConnection_ServiceClosed(AppServiceConnection sender, AppServiceClosedEventArgs args)
        {
            this.appServiceDeferral.Complete();
        }

        void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
        {
            throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
        }

        private void OnSuspending(object sender, SuspendingEventArgs e)
        {
            var deferral = e.SuspendingOperation.GetDeferral();
            //TODO
            //deferral.Complete();
        }
    }
}

В фоновом скрипте я подключаюсь к расширению под тем же именем EdgeExtensionRuntime как в файле манифеста:

// Store port for native messaging connections
var port = null;

browser.runtime.onMessage.addListener(
    function (request, sender, sendResponse) {
        if (port === null) {
            port = browser.runtime.connectNative("EdgeExtensionRuntime");
            port.onDisconnect.addListener(onDisconnected);

            port.onMessage.addListener(function (response) { console.log(response); });
        }

        try {
            port.postMessage(request.message);
        } catch (e) {
            console.log(e);
        }


        return true;
    });

function onDisconnected() {
    console.log("disconnect!");
    port = null;
}

По-видимому, это не работает (даже с EntryPoint добавлен к тегу extension), так как я получаю немедленное "отключение" в журнале фоновых страниц расширений.

Я не вижу, в чем проблема, и документация MS по этому вопросу очень плохая.

1 ответ

Решение

Решение, которое вызывает OnBackgroundActivation для запуска, заключается в добавлении следующей информации протокола в манифест пакета:

<uap:Extension Category="windows.protocol">
  <uap:Protocol Name="msghost1" />
</uap:Extension>

Тем не менее, теперь преобразование приложения в плагин в процессе не решает проблему Windows.System.Launcher.LaunchFileAsync(IStorageFile) бежать по основному потоку. Пока что этот вызов успешен только в режиме отладки (с подключенным отладчиком). Выложу отдельный вопрос по этому вопросу.

Другие вопросы по тегам