UWP In-Process AppService连接仅在主机应用程序运行时可用。

huangapple go评论65阅读模式
英文:

UWP In-Process AppService connection only when Host app is running

问题

我的UWP应用程序托管了一个与应用程序在同一进程中运行的AppService。为此,我遵循了这个文档

这个AppService的目标是通信两个正在运行的应用程序。

这是我用来允许传入AppService连接的代码:

        private AppServiceConnection AppServiceConnection;
        private BackgroundTaskDeferral AppServiceDeferral;

        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();
            ValueSet response = (await IPC.Controller.ProcessIncomeRequests(args.Request.Message.ToDictionary())).ToValueSet();
            await args.Request.SendResponseAsync(response);
            messageDeferral.Complete();
        }

        private void OnAppServicesCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
        {
            AppServiceDeferral.Complete();
        }
        private void AppServiceConnection_ServiceClosed(AppServiceConnection sender, AppServiceClosedEventArgs args)
        {
            AppServiceDeferral.Complete();
        }

Stackoverflow问题中所提到的,即使“宿主”应用程序未运行,也可以建立来自“客户端”应用程序的通信。
出于我的目的,我想拒绝传入的AppServices连接,除非“宿主”应用程序当前正在运行。

我可以这样做吗?我可以在OnBackgroundActivated方法中检查哪个属性来决定是否接受taskInstance吗?

更新:

可以说OnLaunched(LaunchActivatedEventArgs e)方法只在应用程序的“常规”启动之后才会触发吗(用户手动启动应用程序)?

如果是这样的话,一种解决方法可能是跟踪一个名为AppIsRunning的布尔变量:

private static bool AppIsRunning = false;

protected override async void OnLaunched(LaunchActivatedEventArgs e)
{
    ...    
    AppIsRunning = true;
    ...
}

private AppServiceConnection AppServiceConnection;
private BackgroundTaskDeferral AppServiceDeferral;

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)
{
    if (AppIsRunning)
    {
        AppServiceDeferral messageDeferral = args.GetDeferral();
        ValueSet response = (await IPC.Controller.ProcessIncomeRequests(args.Request.Message.ToDictionary())).ToValueSet();
        await args.Request.SendResponseAsync(response);
        messageDeferral.Complete();
    }
}

private void OnAppServicesCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
{
    AppServiceDeferral.Complete();
}
private void AppServiceConnection_ServiceClosed(AppServiceConnection sender, AppServiceClosedEventArgs args)
{
    AppServiceDeferral.Complete();
}

这样,当应用程序未运行时,传入的AppService请求就不会被处理。

英文:

My UWP app hosts an AppService that runs in the same process as the app does. To do this I have followed this documentation.

The goal of this AppService is to communicate two running Apps.

This is the code I use to allow incoming AppService connections:

        private AppServiceConnection AppServiceConnection;
        private BackgroundTaskDeferral AppServiceDeferral;

        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();
            ValueSet response = (await IPC.Controller.ProcessIncomeRequests(args.Request.Message.ToDictionary())).ToValueSet();
            await args.Request.SendResponseAsync(response);
            messageDeferral.Complete();
        }

        private void OnAppServicesCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
        {
            AppServiceDeferral.Complete();
        }
        private void AppServiceConnection_ServiceClosed(AppServiceConnection sender, AppServiceClosedEventArgs args)
        {
            AppServiceDeferral.Complete();
        }

As mentioned in the following Stackoverflow question, a communication from a 'client' app can be established to the 'host' app even if the 'host' app isn't running.
For my purposes, I would like to deny incoming AppServices connections unless the 'host' app is currently running.

Is there a way I can do this? What property could I check within the OnBackgroundActivated method to decide whether to accept the taskInstance or not?

UPDATE:

Is it right to say that the method OnLaunched(LaunchActivatedEventArgs e) is only fired after a "conventional" start up of the app (user launching the app manually)?

If that's the case, then one solution could be to keep track of a boolean variable AppIsRunning:

private static bool AppIsRunning = false;

protected override async void OnLaunched(LaunchActivatedEventArgs e)
{
    ...    
    AppIsRunning = true;
    ...
}

private AppServiceConnection AppServiceConnection;
private BackgroundTaskDeferral AppServiceDeferral;

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)
{
    if (AppIsRunning)
    {
        AppServiceDeferral messageDeferral = args.GetDeferral();
        ValueSet response = (await IPC.Controller.ProcessIncomeRequests(args.Request.Message.ToDictionary())).ToValueSet();
        await args.Request.SendResponseAsync(response);
        messageDeferral.Complete();
    }
}

private void OnAppServicesCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
{
    AppServiceDeferral.Complete();
}
private void AppServiceConnection_ServiceClosed(AppServiceConnection sender, AppServiceClosedEventArgs args)
{
    AppServiceDeferral.Complete();
}

This way the incoming AppService requests wouldn't be handled when the app is not currently running.

答案1

得分: 0

我想拒绝传入的AppServices连接,除非当前正在运行的应用程序是'host'应用程序。

根据当前的设计,In-Process AppService使用OnBackgroundActivated作为入口点。当触发BackgroundActivated时,客户端应用程序会唤醒AppService。目前,没有文档API可以确定主机应用程序是否正在运行。

在OnBackgroundActivated方法内,我应该检查哪个属性来决定是否接受taskInstance?

OnBackgroundActivatedAppServiceRequestReceivedEvent中,也没有可用于确定主机应用程序是否正在运行的属性。

英文:

> I would like to deny incoming AppServices connections unless the
> 'host' app is currently running.

According to the current design, In-Process AppService uses OnBackgroundActivated as EntryPoint. When BackgroundActivated is triggered, the AppService is awakened by the client app. Currently, there is no document API that can determine whether the host app is running.

> What property could I check within the OnBackgroundActivated method to
> decide whether to accept the taskInstance or not?

In OnBackgroundActivated and AppServiceRequestReceivedEvent, there is also no property that can be used to determine whether the host app is running.

答案2

得分: 0

如我在问题的更新中提到的,可以追踪一个布尔变量,在调用OnLaunched(LaunchActivatedEventArgs e)方法时更改其默认值,以用作所需目的的解决方法。在接受AppService请求之前,应检查此变量的值,以决定是否接受该请求。

英文:

As I have mentioned in my Update to the question, tracking a boolean variable that changes it's default value when the OnLaunched(LaunchActivatedEventArgs e) method is called could be used as a workaround for the required purposes. The value of this variable should be checked before accepting an AppService Request, to decide whether it is accepted or not.

huangapple
  • 本文由 发表于 2023年7月11日 03:40:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/76656836.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定