Marvin's Blog【程式人生】

Ability will never catch up with the demand for it

10 Apr 2020

读stefanwick笔记【一】:UWP桌面扩展

三人行,必有我师矣!读stefanwick笔记。

[UWP with Desktop Extension – Part 1]

博文中的例子https://github.com/StefanWickDev/UWP-FullTrust/tree/master/UWP_FullTrust_1在VS2019中无法编译,错误:

C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VisualStudio\v16.0\AppxPackage\Microsoft.AppXPackage.Targets(900,5): error APPX3217: SDK folder containing ‘UAP.props’ for ‘UAP 10.0.16299.0’ cannot be located. See http://go.microsoft.com/fwlink/?LinkID=798187 for more information.

只好从头来过。先设置工程:

  1. 创建一个Blank App (Universal Windows)类型的C#工程,取名Hello,把解决方案取名DesktopPackage。
  2. 在DesktopPackage中添加一个Windows Application Packaging Project类型的工程,取名HybridApp。
  3. 再创建一个Console App (.NET Core)取名HiThere
  4. 将HybridApp设为启动项目,并添加引用(Project => Add References…)到Hello和HiThere
  5. 在Hello中,添加引用到Windows Desktop Extension for UWP (否则不能从UWP启动FullTrust Process)
  6. 在解决方案浏览器中确保HybridApp的Entry Point是Hello

下面来修改代码,用XML编辑器打开HybridApp的Package.appxmanifest,在

<Application Id="App"
      Executable="$targetnametoken$.exe"
      EntryPoint="Hello.App">

添加:

      <Extensions>
        <desktop:Extension
          xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10"
          Category="windows.fullTrustProcess"
          Executable="HiThere\HiThere.exe" />
      </Extensions>

打开Hello的MainPage.xaml,在Grid中添加:

        <Button Content="Run Desktop Extension Code" HorizontalAlignment="Center" VerticalAlignment="Center" Click="Button_Click"/>

在MainPage.xaml.cs中做以下修改:

using Windows.ApplicationModel;
using Windows.Foundation.Metadata;

...
        private async void Button_Click(object sender, RoutedEventArgs e)
        {
            if (ApiInformation.IsApiContractPresent("Windows.ApplicationModel.FullTrustAppContract", 1, 0))
            {
                await FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync();
            }
        }

...

打开HiThree的Program.cs,做如下修改:

    static void Main(string[] args)
    {
      Console.WriteLine("Hello World!");
      Console.WriteLine("\r\nPress ENTER to exit ...");
      Console.ReadLine();
    }

在解决方案的配置中,将Hello和HybridApp的平台改为x86或者x64;然后确保HybridApp被布署,而Hello不被布署。

然后编译布署并运行,在Hello这个UWP程序中点击中间的按键,会运行HiThree程序。

I was using the older method previously, which is no longer accepted. I’ve tried the new method using packaing project, and the problem I encountered is that this method creates two entries in the app list in Start menu, one for the appxmanifest file in UWP project, and one for the appxmanifest file in the packaging project. Is there any way to avoid that? – Mahdi Ghiasi May 29 at 11:28 @MahdiGhiasi Just need to add AppListEntry="none” on the VisualElements item for the app you don’t want to have listed in the app list. – Stefan Wick MSFT May 29 at 13:47

UWP with Desktop Extension – Part 2

一个Appx只能启动一个FullTrust进程,但是这个进程可以启动其他Win32进程。

可以从FullTrust进程启动Appx内包含的其他Win32程序,这些程序将使用Appx的package id。也可以启动Appx外的Win32进程,但是其使用的package id将会不同于Appx内的Win32程序。Package id意味着不同的安全隔离(注册表、文件系统等待)。同一Package id通常在状态栏上会成为一个群组。

被启动的Win32进程可以运行在后台,这意味着应用程序有责任对齐生命周期进行控制。

在Windows 10 S Mode,只有MS签过名的EXE能被启动。

UWP进程属于低信任级别的进程,当往高信任级别的Win32进程传递参数的时候,只能传递有限的参数。 参考fulltrustprocesslauncher

对于复杂的程序,可以通过本地的AppData机制来传递。

UWP with Desktop Extension – Part 3

UWP进程和Win32进程之前的通信可以通过AppServiceConnection来进行,也就是在UWP进程启动一个同进程的App Service,让Win32进程作为客户端来连接。

第一步是要在Packaging项目中定义AppService

<Extensions>
 <uap:Extension Category="windows.appService">
  <uap:AppService Name="SampleInteropService" />
 </uap:Extension>
 <desktop:Extension Category="windows.fullTrustProcess" Executable="FullTrust\FullTrust.exe" />
</Extensions>

UWP进程和Win32进程之间可以通过AppService的消息来通信。

当AppService双方有一端意外退出了应该怎么办:

  • 重启对端
  • 置之不理(如果不太严重的话)
  • 拒绝继续

AppService提供Disconnected和Closed两种事件。

UWP with Desktop Extension – Part 4

应用商店接受.appx、.appxbundle以及.appxupload文件。最简单的方式是使用appxupload,这种格式可以由Packaging Project自动生成。(注意,从Packaging Project生成,而不是从UWP Project生成)。 在Solution Explorer中右击项目,选择 Store > Create App Packages … 即可。

生成appxupload的同时也会生成测试包,建议对测试包进行下面的测试

  • 使用Windows App Certification Kit进行测试
  • 在Visual Studio之外进行测试(比如在一个没有装VS的虚拟机上),使用Add-AppDevpackage可以按照这个应用

如果需要运行在移动设备上,那么要配置ARM构建。

‘runFullTrust’需要额外的审批,这会在第一次提交App时发生。

UWP app with Systray extension

创建一个WinForms项目,来支持通知栏图标。运行这个WinForms项目需要FullTrust的支持。

通知栏图标做这几件事:

  • 打开UWP 应用
  • 发送消息给UWP应用
  • 打开WinForms窗口
  • 退出UWP 应用

其他参考

(本篇完)

comments powered by Disqus