上一篇《2020年的UWP(2)——In Process App Service》中咱们了解了UWP和Desktop Extension能够经过AppService进行数据交互。本篇咱们就来梳理在不一样场景,UWP和Desktop Extension可能存在的交互方式。html
对Desktop Extension中程序的类型,我暂时分为如下四种:git
本篇咱们仅讨论第一种,Desktop Extension中执行后当即退出的程序。该类型有如下特征:github
下图是该类型交互场景的示意图。经过FullTrustProcessLauncher从UWP端启动Desktop Extension,我已在《迁移桌面程序到MS Store(9)——APPX With Desktop Extension》介绍过了,本篇再也不赘述。windows
比较典型的如执行某个特定操做,例如调用LockScreen的Win32 API。app
class Program { [DllImport("user32.dll", SetLastError = true)] public static extern bool LockWorkStation(); static void Main(string[] args) { LockWorkStation(); } }
咱们观察从UWP端启动Desktop Extension的代码:async
private async void Button_Click(object sender, RoutedEventArgs e) { await FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync(); }
LaunchFullTrustProcessForCurrentAppAsync方法没有传递参数给LockScreen方法,也不关心返回值。启动Desktop Extension后也不会经过AppService进一步发送request。
彷佛和本篇的主题,数据交互绝不相关。但实际状况下,一个Desktop Extension的exe中,会有多个像LockScreen这种一次性的消费型方法。这就要求咱们可以区分UWP端具体要执行哪个。
首先咱们来介绍标准的作法,给LaunchFullTrustProcessForCurrentAppAsync方法传参。ide
public static IAsyncAction LaunchFullTrustProcessForCurrentAppAsync(string parameterGroupId);
这里要注意的是。这里所谓的参数parameterGroupId,不会传递到Desktop Extension的Main方法里。而是用这个string参数去Package.appxmanifest文件中作匹配,在Package.appxmanifest文件中对应的那个字符串才会被传递给Main方法。spa
<Applications> <Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="$targetentrypoint$"> <uap:VisualElements DisplayName="DataExchangeSimpleCallPackage" Description="DataExchangeSimpleCallPackage" BackgroundColor="transparent" Square150x150Logo="Images\Square150x150Logo.png" Square44x44Logo="Images\Square44x44Logo.png"> <uap:DefaultTile Wide310x150Logo="Images\Wide310x150Logo.png" /> <uap:SplashScreen Image="Images\SplashScreen.png" /> </uap:VisualElements> <Extensions> <desktop:Extension Category="windows.fullTrustProcess" Executable="ExistAfterCallsProgram\ExistAfterCallsProgram.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。code
不提示的话,很难想到在同一个Package里的UWP和Desktop Extension,是能够访问相同的LocalSettings对象的。
在UWP的MainPage.cs中,咱们将“mspaint.exe”存储到key为“content”的LocalSettings键值对中。htm
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