在物联网(IoT)领域,部署应用程序到各种设备上是一个常见的需求。例如,可能需要将一个应用程序部署到诸如树莓派这样的小型设备上,用于展示数字标牌、温度读取器或其他服务。如果已经在使用微软生态系统,或者需要诸如BitLocker、自动更新或企业数据保护(远程擦除丢失设备的能力)等功能,那么Windows IoT操作系统无疑是一个明智的选择。Windows IoT Core版本是免费的,这使得它在成本敏感的应用中更具吸引力。
然而,当开发完应用程序并准备将其部署到设备上时,如何快速且一致地将应用程序(或更可能是一组前台和后台应用程序)部署到设备上?更重要的是,当有一个bug修复或功能增强时,如何将其推送到现场设备上?
在大多数情况下,微软关于构建Windows IoT映像的文档是出色的。在安装了一些先决软件之后,使用一组提供的命令行工具来创建多个XML文件,这些文件共同描述了一个映像。然后将这些XML文件编译成一个多吉字节的.ffu映像文件,可以使用Windows IoT Core Dashboard软件(或者更好的是flashsd命令行工具)将其写入SD卡。
现在,可以将新刷新的SD卡插入一堆树莓派,并将其发送到世界各地。然而,除非是查克·诺里斯,否则将需要向这些树莓派发送bug修复,而访问每一个设备是不可能的。有两种主要的选择:基于商店的更新和侧载更新。
微软允许开发者将Windows IoT应用程序发布到微软商店,此时它将自动将应用程序更新推送到设备并安装它们。这个选项非常安全和可靠。然而,有几个缺点。
有一个特殊的注册过程可能会很耗时。想它已经变得更好了,但花了好几个星期才获得批准。后台应用程序需要额外的工作来发布,因为每个应用程序都需要一个特殊的空的前台UWP应用程序,开发者必须提交到商店(参见“无头应用程序的特殊说明”)。
将多个依赖应用程序同时作为包发布是棘手的。更新需要一个审批过程,除此之外,可能需要长达24小时才能推送到设备。
如果需要完全控制部署过程,例如,确保多个依赖包按特定顺序升级,那么有一个额外的选项。可以使用PackageManager API以及一个特殊的.appxmanifest权限来管理自己的应用程序部署,这允许侧载应用程序更新。自然,将需要一个服务器来托管应用程序更新文件,并通知客户端有更新可用。然后创建一个后台UWP应用程序,监控服务器,并在检测到变化时下载和安装包。
虽然这个选项有更多的控制权,但请记住以下缺点:手工滚动侧载代码会打开应用程序的攻击面。将不得不维护一个专用服务器和SSL证书。它可能更加脆弱,因为整个过程可能会因为URL变化、SSL证书过期或升级器后台应用程序中的某些东西出现问题而中断。
Matthijs Hoekstra在他的博客文章“侧载UWP应用程序的自动更新器”中很好地记录了一种方法。他的方法涉及使用在Visual Studio Magazine去年发表的文章中描述的UWP应用程序间通信方法向更新器后台应用程序发送通知。
如果更喜欢有一个单一的应用程序同时监控变化和安装更新,从而将所有部署责任隔离到一个单一的应用程序中,可能想看看“耻辱的警笛UWP应用程序”的SirenOfShame.Uwp.Maintenance项目。如果查看那个代码,会看到将应用程序下载到一个临时目录(可能是一个新的UWP要求),提供大量的日志,并使用证书固定以获得更好的安全性。设计那个项目足够通用,可以复制粘贴到一个新项目中,只需要做一些小的改动。
无论如何,如果结合侧载和映像创建,可能会遇到困难。以下是发现的问题和解决方案。
包更新失败 ErrorCode = -2147009293 System.Runtime.InteropServices.COMException (0x80073CF3): 包更新失败,依赖或冲突验证。当在映像中包含一个appx而不是一个appxbundle时,会得到这个错误。包含一个appx是他们在实验室1b的步骤4中告诉要做的,当他们说“生成应用程序包:永不”。问题是,只能在最初安装了appxbundle的情况下才能侧载一个appxbundle。为了解决这个问题,忽略指示,并将“生成应用程序包”设置为“总是”,当生成应用程序以包含在映像中。当运行newAppxPkg命令时,可以直接引用appxbundle而不是appx,从那时起一切都会完全一样。
移除失败 ErrorCode = -2147009286 System.Runtime.InteropServices.COMException (0x80073CFA): 移除失败。请联系软件供应商。如果尝试通过PackageManager.RemovePackageAsync()卸载一个作为appx安装到映像中的包,会得到这个错误。相反,总是包含一个appxbundle而不是一个appx,当构建映像(见上文)。