zoukankan      html  css  js  c++  java
  • 2020年的UWP(3)——UWP和desktop extension的简单交互

    上一篇《2020年的UWP(2)——In Process App Service》中我们了解了UWP和Desktop Extension可以通过AppService进行数据交互。本篇我们就来梳理在不同场景,UWP和Desktop Extension可能存在的交互方式。

    对Desktop Extension中程序的类型,我暂时分为以下四种:

    • 执行后立即退出
    • 等待request,处理完后退出
    • 一或多个request/response周期
    • 和UWP程序相同生命周期

    本篇我们仅讨论第一种,Desktop Extension中执行后立即退出的程序。该类型有以下特征:

    1. 简单的单向调用:
    2. 不接受request
    3. 不关心返回结果
    4. 调用后立即退出

    下图是该类型交互场景的示意图。通过FullTrustProcessLauncher从UWP端启动Desktop Extension,我已在《迁移桌面程序到MS Store(9)——APPX With Desktop Extension》介绍过了,本篇不再赘述。

    比较典型的如执行某个特定操作,例如调用LockScreen的Win32 API。

        class Program
        {
            [DllImport("user32.dll", SetLastError = true)]
            public static extern bool LockWorkStation();
    
            static void Main(string[] args)
            {
                    LockWorkStation();
            }
        }

    我们观察从UWP端启动Desktop Extension的代码:

            private async void Button_Click(object sender, RoutedEventArgs e)
            {
                await FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync();
            }

    LaunchFullTrustProcessForCurrentAppAsync方法没有传递参数给LockScreen方法,也不关心返回值。启动Desktop Extension后也不会通过AppService进一步发送request。
    似乎和本篇的主题,数据交互毫不相关。但实际情况下,一个Desktop Extension的exe中,会有多个像LockScreen这种一次性的消费型方法。这就要求我们能够区分UWP端具体要执行哪一个。
    首先我们来介绍标准的做法,给LaunchFullTrustProcessForCurrentAppAsync方法传参。

    public static IAsyncAction LaunchFullTrustProcessForCurrentAppAsync(string parameterGroupId);

    这里要注意的是。这里所谓的参数parameterGroupId,不会传递到Desktop Extension的Main方法里。而是用这个string参数去Package.appxmanifest文件中做匹配,在Package.appxmanifest文件中对应的那个字符串才会被传递给Main方法。

      <Applications>
        <Application Id="App"
          Executable="$targetnametoken$.exe"
          EntryPoint="$targetentrypoint$">
          <uap:VisualElements
            DisplayName="DataExchangeSimpleCallPackage"
            Description="DataExchangeSimpleCallPackage"
            BackgroundColor="transparent"
            Square150x150Logo="ImagesSquare150x150Logo.png"
            Square44x44Logo="ImagesSquare44x44Logo.png">
            <uap:DefaultTile Wide310x150Logo="ImagesWide310x150Logo.png" />
            <uap:SplashScreen Image="ImagesSplashScreen.png" />
          </uap:VisualElements>
            <Extensions>
                <desktop:Extension Category="windows.fullTrustProcess" Executable="ExistAfterCallsProgramExistAfterCallsProgram.exe">
                    <desktop:FullTrustProcess>
                        <desktop:ParameterGroup GroupId="LockScreen" Parameters="LockScreen" />
                        <desktop:ParameterGroup GroupId="ControlPanel" Parameters="ControlPanel" />
                    </desktop:FullTrustProcess>
                </desktop:Extension>
            </Extensions>
        </Application>
      </Applications>

    因为都是写死的字符串,除了用来区分Desktop Extension中数量有限的方法外,并不适合作为一种灵活的传参方式用于具体方法的逻辑判断。
    通常意义上的灵活传参给Desktop Extension,基本都是通过AppService来实现,在介绍另外三种类型时会展开讨论。
    在不使用AppService的简单交互场景,除了钦定的使用parameterGroupId的做法外。还有一种容易被忽视的方式,即使用LocalSettings。

    不提示的话,很难想到在同一个Package里的UWP和Desktop Extension,是可以访问相同的LocalSettings对象的。
    在UWP的MainPage.cs中,我们将“mspaint.exe”存储到key为“content”的LocalSettings键值对中。

            private async void ButtonLocalSettings_Click(object sender, RoutedEventArgs e)
            {
                ApplicationData.Current.LocalSettings.Values["content"] = "mspaint.exe";
                await FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync("LocalSettings");
            }

    而在Desktop Extension中,我们同样也可以取到这个值,从而达成数据交互的目的。在这个例子中,我们可以传递需要运行的exe、msi文件名或路径,而不用为每一个文件创建单独的parameterGroupId。

            static void Main(string[] args)
            {
                string funcName = args[2];
                switch (funcName)
                {
                    case "LockScreen":
                        LockWorkStation();
                        break;
                    case "ControlPanel":
                        Process.Start("control.exe");
                        break;
                    case "LocalSettings":
                        var content = ApplicationData.Current.LocalSettings.Values["content"].ToString();
                        Process.Start(content);
                        break;
                }
            }

    本篇讨论了UWP和Desktop Extension的简单数据交互,“执行后立即退出”的场景。后续我们会接着讲另外的三种类型,感谢看到这里的同学们!
    Github:
    https://github.com/manupstairs/UWPSamples/tree/master/UWPSamples/DataExchangeUWP/ExitAfterCalls

  • 相关阅读:
    Python量化分析,计算KDJ
    Ubuntu16.04安装Python3.6 和pip(python3 各版本切换)
    使用docker加载已有镜像安装Hyperledger Fabric v1.1.0
    Ubuntu 16.04将左侧面板置于底部
    解决Flask局域网内访问不了的问题
    Ubuntu 16.04 安装Go 1.9.2
    Ubuntu16.04下安装Hyperledger Fabric 1.0.0
    Ubuntu 16.04安装Docker-CE
    用Python抓取网页并解析
    图解python中赋值、浅拷贝、深拷贝的区别
  • 原文地址:https://www.cnblogs.com/manupstairs/p/13956235.html
Copyright © 2011-2022 走看看