除了阅读本文档外,我还尝试为本地消息传递实现 Edge-Browser 扩展,以使用Windows.System.Launcher.LaunchFileAsync
.
我明确不尝试使用后台任务通过 AppService 实现扩展,因为我需要确保在主 UI 线程上执行 LaunchFileAsync。因此,我想OnBackgroundActiviated
直接在主应用程序组件上使用。
上面提到的文档说,将基于应用服务的扩展转换为进程内扩展是通过从包清单中的应用程序标记中删除“EntryPoint”属性来完成的。但是,按照此描述,Visual Studio 2017 会引发无法注册扩展的错误(DEP0700, 0x80073CF6 windows.appService: Element not found
)。
向 AppService 标记添加EntryPoint
属性会导致此错误消息消失,但我无法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
在 File中实现,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
添加到扩展标签),因为我确实在扩展背景页面日志中立即“断开连接”。
我看不出问题出在哪里,而且关于这方面的 MS 文档很差。