[Windows翻译]MSIX教程。一个全面的24章的指南

1,833 阅读24分钟

原文地址:www.advancedinstaller.com/msix-introd…

原文作者:www.advancedinstaller.com/authors/bog…

发布时间:2018年

发现新的MSIX包格式和容器。获得5000字的快速介绍,让你快速了解Windows 10的最新打包和部署技术。订阅后可收到以下所有章节的扩展版本的未来更新。

image.png

1. 什么是MSIX?

在2018年的Windows开发者日上宣布,MSIX是一种新的通用包格式,专为Windows 10应用程序设计。桌面、移动和所有其他Windows 10设备都将得到支持。

微软将MSIX作为AppX包(最初只用于UWP应用程序)的改进版介绍给我们,通过带来他们从MSI和App-V包以及桌面桥程序中获得的知识,更好地支持Windows 10上的传统桌面应用程序。

从结构上看,MSIX包与AppX或App-V包非常相似。它基本上是一个压缩包,包含你的应用程序文件和一些配置XML文件。在这篇博文中,微软谈到了这种包格式的早期雏形,即AppX,它的祖先。

MSIX带来的主要区别是它对Win32应用程序的扩展支持,也就是我们这些年一直在使用的标准桌面应用程序。这将使你能够打包你的普通桌面应用程序,并将其发布在微软商店或简单地从你的网站上提供下载,同时利用现代Windows APIs的所有新优势。

将桌面应用程序打包成MSIX包有一些限制,这是微软为了确保新模式向我们承诺的安全性而施加的。检查上面链接的文章,确保你的应用程序适合迁移到MSIX。

2. MSIX容器

MSIX容器将桌面桥接应用和UWP应用的支持结合起来,如下图所示。

image.png

MSIX容器

当然,以MSIX打包的经典Win32应用程序仍然只能在桌面设备上运行,因此,这些应用程序不会因为我们现在以新格式打包而 "变得 "通用。

所有这些转换后的应用程序仍然是x86和x64位的应用程序,因此它们不能在平板电脑/手机或其他设备上运行。有一个例外,就是在S模式下运行Windows 10的Always-Connected-PC设备,其中Win32应用程序在ARM设备上运行,操作系统和特定的ARM CPU中包含仿真支持。

就像完整的UWP应用程序一样,Win32转换后的应用程序(并打包成MSIX)可以访问UWP APIs。然而,从一个Win32应用程序,你只能访问桌面API,而从一个完整的UWP应用程序,你有可能访问不同的API(移动,Xbox,HoloLens等...),这取决于目标设备。

这意味着,你可以使用新的Windows 10 APIs开始现代化你的Win32应用程序,甚至将整个应用程序迁移到UWP,在这种情况下,你可以得到一个完整的UWP容器的所有好处。

在微软商店发布Win32转换的应用程序是可能的,但只针对上述的设备。

3. 系统资源及更多

MSIX容器将提供对Windows 10新功能的访问,如增强的安全性和对新的UWP API的访问,但同时它也会带来一些限制。

微软的建议和限制的完整列表可以在下面的文章中找到,准备打包一个应用程序(桌面桥)。

在下面,你可以找到一个MSIX包可以安装的支持的操作系统资源(Win32应用程序)的图表。当然,在此基础上,你可以迁移和扩展你的应用程序,使用新的UWP组件(应用程序服务、后台任务等......),以更好地与操作系统或其他应用程序集成。

image.png

如果你正在寻找驱动程序,MSIX包中不支持这些。微软建议所有的驱动程序都由硬件供应商上传到微软商店,这样操作系统就会自动为最终用户管理它们的安装。由于MSIX仍在开发中,我们可以期待变化,但在那之前,你仍然可以使用App-V用户采用的混合解决方案,在那里,驱动程序仍然被部署在我们的老朋友MSI包中。

4. 构建MSIX包

有多种工具可以帮助你建立和维护你的MSIX包。对于一个完整的工具列表,请查看微软的文档。

当然,Advanced Installer可以从头开始构建MSIX包,或者将你的旧安装程序转换为你可以维护的新项目。看看下面的视频,看看你如何轻松地从一个项目中构建MSIX和MSI包,轻松地为老的Windows 7用户和当前的Windows 10用户服务。

www.youtube.com/watch?v=2av…

微软提供了自己的转换旧安装程序的工具--MSIX打包工具,不需要生成项目。Visual Studio目前可以构建AppX包,所以很可能在未来的更新中我们也会看到对MSIX包的支持。

手动构建包也是可以的,使用命令行工具MakeAppx.exe。

5. 迁移和扩展

转换你的安装程序只是第一阶段(如果你的软件仍然被维护/更新)。现在你可以开始用新的UWP API扩展你的应用程序,并一步步迁移它

来自微软的AppConsult团队编写了一些优秀的教程,展示了如何利用新的API并开始现代化你的应用程序。

  • 从UWP应用中调用一个Win32进程
  • 用UWP API扩展一个桌面应用程序
  • 在桌面应用程序中添加UWP组件
  • 识别一个应用程序的上下文

我们都知道仍然有很多客户端在Windows 7上运行(即使这个数字每天都在下降),这就是为什么上面链接的最后一个教程显示了你如何检测你的应用程序是在旧的桌面应用程序模式还是新的现代应用程序容器中运行。这样,你仍然可以在支持你的Windows 7客户端的同时对你的应用程序进行现代化改造。

除了将旧的EXE/MSI安装程序转换为MSIX,你还可以将AppX和App-V包转换为MSIX格式。这可以通过高级安装程序或MSIX打包工具来完成。这种包的转换可以自动化,因为与MSI/EXE安装程序不同,这些包不包含任何可以在安装/发布期间执行的自定义代码(App-V部署配置是另一个话题),所以整个转换过程实际上分为两个简单的步骤。

提取App-V或AppX包的内容

  1. 使用从原始包中提取(和 "翻译")的内容打包新的MSIX。
  2. 翻译阶段是指从App-V和AppX包的旧清单中生成/翻译新的包清单的部分。

6. 安装位置

所有MSIX包都被操作系统安装/提取到以下文件夹中。

%ProgramFiles%/WindowsApps 复制 这是一个系统位置,默认情况下,从Windows Explorer中是无法访问的。有一些方法可以使其可见,但这并不是本文的主题。

在这个文件夹中,你会发现每个安装在机器上的应用程序的子文件夹,包括操作系统内置的应用程序。所有文件夹的名称都遵循这个模式。

PublisherName.AppName_AppVersion_architecture_hash 下面是一个文件夹名称的例子。

Microsoft.WindowsCalculator_10.1806.1821.0_x64_8wekyb3d8bbwe 在这个文件夹里有一个已经解压的MSIX包,就像你用7-Zip或其他类似工具解压时看到的那样。

在安装你的应用程序时,只有操作系统可以在这个位置写入。如果你的应用程序在安装文件夹内写日志文件或其他数据,它就会崩溃。

你需要更新你的代码以写入%AppData%,或者,如果你不能访问代码,使用软件包支持框架来修复它。

7. 卸载清理

大多数时候,当你卸载MSI包时,AppData中的应用程序文件和注册表项,即应用程序在其生命周期中创建的文件都留在机器上,用 "垃圾 "污染系统。

另一方面,MSIX软件包通过减少机器的杂乱,简化了安装和卸载过程。

由于它的容器化模型,卸载MSIX包也将从系统中删除该应用程序在运行时创建的任何文件(在其AppData文件夹下),包括安装在%ProgramFiles%WindowsApps下的所有应用程序文件。

同样的事情也会发生在由应用程序创建的注册表上。这有助于更容易地保持干净的机器状态,从而避免所有已知的Windows腐烂(又称注册表腐烂)。

请记住,如果该应用程序还在机器上的其他非标准(不推荐)位置创建文件,这些文件在卸载时不会被删除。

8. 文件重定向

通过MSIX包安装的应用程序在沙盒环境(即容器)中运行,这意味着操作系统会重定向大部分文件和注册表操作。

当涉及到文件访问时,当你试图从包的VFS(虚拟文件系统)和AppData文件夹访问文件时,重定向会自动启动。

从你的VFS文件夹访问资源可能会给许多应用程序带来问题,但很容易解决,使用反射API,如链接的例子。

同一篇文章还解释了如何访问应用程序的AppData文件夹。Windows会自动将已知的路径C:\Users<username>\AppData\Roaming\重新映射为一个看起来像这样的路径。

AppData\Local\Packages\<AppName>.AppData_<GUID>\LocalCache\Roaming\

从旧代码中处理你的AppData,默认情况下是可以工作的(包括在Windows 7上),文件夹重映射是透明的,只要你使用推荐的Windows APIs来检索AppData文件夹路径。(硬编码的路径是不好的,会使你的应用程序崩溃)。)

上述文件夹是操作系统重定向你的应用程序的地方,了解它主要是为了调试目的。

检索你的AppData文件夹路径的推荐API调用。

//local app data
string localPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);

//roaming app data
string roamingPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);

9. 注册表重定向

所有的注册表操作都被重定向到特殊的每个应用注册表蜂巢中。你的包可以包含以下蜂巢,如果你提取它的内容,可以在单独的文件中看到。

  • Registry.dat
  • User.dat
  • User.Classes.dat

所有的HKLM条目将被放在Registry.dat文件下,而每个用户的注册表条目将被放在相应的蜂巢里。

所有这些蜂巢在运行时与操作系统上的注册表实际上是合并的,以允许应用程序将整个注册表作为一个单一的单元 "看待"。

HKLM注册表在大多数情况下是只读的,而对用户蜂巢的写入操作被重定向到每个应用程序的位置,就像AppData文件一样。

这允许系统在卸载时轻松地删除应用程序在其生命周期内使用/创建的所有注册表,并避免众所周知的注册表腐烂,这种腐烂几十年来一直拖累着Windows机器。

10. 数字签名

所有的MSIX包都必须有数字签名,没有例外。安全漏洞正在摧毁整个公司,微软决定通过对所有MSIX软件包强制执行数字签名来帮助解决这些攻击,无论这些软件包是从微软商店安装的还是在你公司内部侧载的。

有两种方法来签署一个软件包。

如果你,作为一个软件供应商,在微软商店发布软件包,你不需要签署它。一旦微软批准你的应用程序,他们将签署该软件包。 如果你发布的MSIX包可以在你的网站上直接下载,或者只是打算在你的公司内部重新分发,你需要用从认证供应商那里购买的有效代码签名证书来签名。 对于公司内部的应用程序,你甚至可以使用自我生成的证书,但要确保该证书也安装在你计划部署MSIX的机器上,否则这些机器将无法识别该证书。该证书必须在 "本地机器->受信任的根认证机构 "证书商店中找到。

要签署一个软件包,你需要使用Windows SDK。在SDK中你可以找到SignTool.exe,这是微软推荐的用于数字签名的命令行工具。

大多数打包工具都自动集成了SignTool,所以启用数字签名只需在它们的GUI中进行简单设置。

重要提示:SHA256哈希算法是数字签名MSIX软件包的必选算法,SHA1不被操作系统认为是有效的。

11. 包的内容布局

image.png

一个被提取的MSIX包的内容

上面的图片列出了最常见的,也是最小的MSIX包布局。如果使用makeappx.exe或像7-zip这样的工具提取包,你可以看到这些资源。

Assets - 顾名思义,这是所有应用程序的图形资产应该被发现的地方。

VFS - 这个文件夹通常包含应用程序的二进制文件、DLLs、EXEs、配置文件等等。阅读这篇文章以了解更多细节。VFS和Assets文件夹也被称为应用程序的有效载荷。

Registry.dat - 该文件存储应用程序的HKLM注册表项。一些软件包还在相应的文件中存储了每个用户的注册表项,即User.dat和User.Classes.dat。了解更多。

Resources.pri - 这个文件包含应用程序的资源,如本地化的字符串和其他资源文件的路径。软件包中每种语言都有一个文件。阅读更多。

AppxManifest.xml - 这个XML文件是软件包的主要资源,在下面一章中详细介绍。它包含系统识别、安装和运行应用程序所需的所有信息。

AppxBlockMap.xml - 这是一个自动生成的文件,包含所有应用程序的二进制文件及其散列值的列表。它被系统用于完整性检查和执行差异化更新时(通过只下载变化的文件来降低带宽使用)。

AppxSignature.p7x - 该文件存储软件包内容的数字签名信息。

[Content_Types].xml - 包含关于MSIX包中内容类型的信息,在安装时被系统使用。

12. AppxManifest.xml

这个XML文件是包的清单,必须存在于任何包中。它包含了定义应用程序及其特性的信息。所有这些信息都被系统用来安装/卸载、更新和控制应用程序在其生命周期内的行为。

这个文件通常由构建MSIX包的工具自动生成,无论是Visual Studio、高级安装程序还是其他工具。你也可以手动创建它,但不建议这样做。这个文件最终会出现在你的应用程序的安装文件夹中,并且是只读的。

该文件的内容必须遵循操作系统规定的模式,如上面的链接中所记载的。不同的Windows 10主要更新之间的模式可能有所不同,因此,知道你的应用程序针对的是什么操作系统版本是非常重要的,否则,你可能最终使用的功能不适合所有用户。

13. 包支持框架(又称PSF)

包支持框架(PSF)是微软为那些需要解决旧桌面应用程序的兼容性问题而又无法获得源代码的企业客户提供的解决方案。

PSF带来了对API重定向和挂钩的支持。因此,你可以修复一个未能在安装文件夹中写入文件的应用程序(这不再被允许),并将其重定向到一个推荐的位置,或者也许只是简单地更新应用程序的工作目录。

它的工作方式相当简单。微软提供了一个应用启动器、一个运行时管理器DLL、一些运行时修复程序和一个config.json文件。你也可以按照他们的文档建立你自己的修复程序。

他们的启动器(可执行文件)将成为你软件包中的主要应用,加载运行时管理器DLL和修复程序。在启动时,这个可执行程序将自动启动你的应用程序,但它也会按照config.json文件的规定,将运行时DLL和修复程序加载到你的应用程序中。

这样,当应用程序试图访问一个不再可用的资源时,例如写在其安装文件夹中,运行时修复程序将启动并重定向调用,在这个例子中,调用到AppData下的一个新位置。

image.png

PSF是如何工作的

14. 修改包

实际上,这种包类型相当于以前的MST文件(MSI变换)。然而,修改包并不直接与你的主应用程序的某个版本相联系,这意味着你可以更新主应用程序,仍然使用旧的修改包。

这将使企业的IT人员能够定制并准备大规模部署他们从ISVs收到的MSIX包,或者他们从旧的安装程序中生成的MSIX包。所有这些都是通过使用像高级安装程序或MSIX打包工具。

修改包具有与MSIX包相同的文件扩展名,但内容略有不同,主要区别在于AppXManifest.xml文件中。另外,它必须具有与目标包相同的签名(CN),否则它将无法安装。

修改包不能在其清单中定义应用程序条目,它只能向主/目标包添加新的二进制文件,以及新的注册表条目。

修改包没有直接在 "应用程序和功能 "中列出,但如果你访问目标应用程序的 "高级选项 "链接,你可以找到它们。

www.youtube.com/watch?v=-LN…

15. 商店发布

要在微软商店发布应用程序,你需要在微软注册一个开发者账户,以个人或公司账户的形式。

下一步是保留你的应用程序名称。这时,微软将检查你所要求的名称是否可用,如果没有,将提示你指定另一个名称。

一旦你的应用程序准备好了,你就可以把它提交给商店。在提交之前,我们建议你使用Windows App Compatibility Kit(WACK)来验证你的应用程序是否符合微软的要求。如果你的应用程序通过了所有检查,它就可以进入商店了。

如果你使用高级安装程序,这种验证是一键式的,只需进入文件->设置->软件包验证 "并启用WACK验证。

16. 装载

MSIX包可以从微软商店安装,也可以通过在机器上直接启动包(sideloading,即手动或脚本安装)。

有2个主要条件需要满足,才能成功地进行包的侧载。

必须使用企业策略或通过设置应用程序在机器上启用侧载功能。 MSIX软件包必须用机器识别的证书进行数字签名。正如在数字签名部分提到的,代码签名证书可以是自行生成的,也可以从授权发行商处购买。 一旦这些条件得到满足,你就可以安装MSIX软件包。你可以通过双击MSIX文件或使用PowerShell cmdlet Add-AppxPackage来实现。

这一功能意味着软件供应商不被强迫/锁定通过微软商店发布他们的应用程序。如果他们愿意,他们可以直接在他们的网站上发布MSIX包供下载,用户可以如上所述,手动下载和安装。

如果软件供应商在其服务器上发布更新包,系统对现代应用程序的自动更新支持即使对侧载的应用程序也仍然有效。阅读自动更新部分以了解更多细节。

17. 自动更新

更新部署是一项艰巨而耗时的任务,不被大多数开发者所喜爱,但也是必要的。

有了MSIX包,这项任务就大大简化了。如果你选择在商店里发布你的应用程序,你可以简单地停止担心应用程序的更新,因为操作系统会替你处理。

对于侧载的应用程序,你可以在你的网站上发布更新的包和AppInstaller文件。(下面你可以找到Appinstaller文件的样本内容)。

<?xml version="1.0" encoding="utf-8"?>
<AppInstaller Uri="https://uwpupdate.azurewebsites.net/DesktopBridge.Package.appinstaller" Version="1.0.0.0" xmlns="http://schemas.microsoft.com/appx/appinstaller/2017/2">
  <MainBundle Name="c6c08364-cbe5-4267-ae81-ce9be33ff652" Version="1.0.0.0" Publisher="CN=mpagani" Uri="https://uwpupdate.azurewebsites.net/DesktopBridge.Package_1.0.0.0_Test/DesktopBridge.Package_1.0.0.0_x86_x64.appxbundle" />
  <UpdateSettings>
    <OnLaunch HoursBetweenUpdateChecks="0" />
  </UpdateSettings>
</AppInstaller>

在你的主程序中,你需要做的就是指定你要部署.appinstaller文件和软件包的URL或文件共享的UNC路径。这通常可以在你用来构建MSIX包的应用程序的GUI中指定。这就是你用Advanced Installer和Visual Studio的方法。

如果你有更复杂的检查和下载应用程序更新的方案,比你可能需要在你的应用程序旁边包括一个自动更新工具。

18. 应用程序安装程序(GUI)

AppX包,MSIX的前身,不能总是通过简单的双击来安装包。在机器上手动安装/sideload一个应用程序的唯一方法是借助PowerShell cmdlet Add-AppXPackage。

正如你在下面的微软文章中所看到的,一个简单的GUI被引入以简化MSIX包的安装。

与旧的MSI包不同,这个GUI不能从包内定制,这意味着你不能向你的客户显示定制的安装对话框或在安装过程中要求用户输入。微软建议应用程序的配置在用户第一次启动时进行,详见我们的下一章,首次启动配置。

19. 首次启动配置

随着AppX包的引入,早在Windows 8中,微软发布了新的应用程序配置指南。

对于所有通过AppX/MSIX包安装的应用程序,用户配置将在应用程序被用户首次启动时进行。这意味着安装UI不能再被定制,以收集用户输入和执行自己的代码,在首次启动前准备好应用程序。

微软建议所有这些都在你的应用程序内部完成,将安装阶段与应用程序的初始配置脱钩。

对于企业部署来说,最终用户通常希望他们的应用程序是预先配置好的,可以随时使用,IT部门将能够使用修改包,在应用程序旁边包括所需的额外配置(例如,许可证文件等)。

20. 本地化

资源管理系统是帮助用户建立包资源索引(PRI文件)的。PRI文件只是一个命名的资源表,以及对应用包内资源文件的引用,每个MSIX包内的每种语言都有一个PRI文件。

高级安装程序或Visual Studio,取决于你使用的是什么,将根据你的项目配置自动构建这个文件。

你也可以手动构建PRI文件,在这种情况下,你还需要阅读更多关于微软的资源命名惯例。

在安装时,系统将根据用户的地区设置,只自动下载它所需要的资源,而不是整个MSIX包(其中也包含所有其他支持语言的资源)。

关于包内本地化资源的更详细的概述,请查看MSDN的这篇文章。

image.png

图片来源。MSDN博客

21. 应用程序的能力

在现代应用程序中,对于任何你想要访问的操作系统资源(用户图片、互联网连接或相机或麦克风等设备),都必须从包清单中申请权限,这些就是你的应用程序能力。

如果没有在你的包中声明它们,将导致无法加载相应的系统API,你的应用程序将无法按预期工作。

你可以在Advanced Installer的GUI中轻松定义你的应用程序的能力,从预定义的列表中选择它们,或者在Visual Studio项目中选择相应的功能。

只有完整的UWP应用程序或应用程序内部的UWP组件(例如后台任务或应用程序服务)才需要定义应用程序的功能。任何旧的(Win32)代码仍将继续正确运行,即使没有在包中声明的能力,因为它不使用任何现代API来访问这些资源。

22. 在MSIX容器内调试

在MSIX容器内调试你的代码与Visual Studio中的标准调试略有不同。

当你在Visual Studio中调试你的桌面应用程序时,应用程序并不在容器内运行,相反,Visual Studio只是将你的应用程序的主可执行文件作为一个简单的文件从磁盘上启动,而没有意识到MSIX容器所带来的限制,也没有能力访问MSIX容器所带来的新的现代API。

这整个访问实际上是依赖于AppXManifest.xml文件和VFS文件夹的复制。当用Visual Studio调试MSIX打包的应用程序时,基本上发生的情况是Visual Studio构建MSIX包,可以使用Advanced Installer的扩展或使用其内置支持,然后应用程序被安装在机器上,包被解压到一个临时位置。一旦应用程序被调试器启动,Visual Studio就会依附于它的进程,你可以继续调试它,就像你过去做的那样。

23. 按用户部署

默认情况下,部署在机器上的应用程序是按用户注册的,即使它们都安装在%ProgramFiles%\WindowsApps文件夹下,这可能会导致你错误地认为该应用程序对机器上的所有用户都是可见的,就像Win32应用程序的情况。

每个用户在他的账户下只能看到注册到他的证书的应用程序,所以如果另一个用户在机器上安装了一个新的应用程序,这个应用程序对所有其他用户来说都是隐藏的。

如果两个或更多的用户在机器上安装相同版本的应用程序,该应用程序不会被下载或安装两次。相反,同一来源被用来为两个用户提供应用程序,通过在他们各自的账户中注册该应用程序。这样一来,操作系统在更新应用程序时就减少了磁盘浪费,也减少了带宽的使用。

每台机器的部署可以通过在用户账户创建之前,在本地计算机的操作系统上或挂载的Windows镜像上配置你的包来实现。这可以通过Add-AppxProvisionedPackage cmdlet完成,适用于.appx和.msix包。阅读更多关于每台机器的部署。

24. Windows 10 S模式

Windows 10 S模式使操作系统只与来自微软商店的应用程序一起工作。

S模式下的系统可以升级到专业版,一次性收费49美元,从而解锁安装所有来源的应用程序,包括使用旧的安装程序(EXE,MSI等...)。这是一个单向的操作,升级后不再可能回到S模式。

配备Windows 10 S模式的设备似乎是微软对谷歌Chromebook的回应,Chromebook在教育用户中大受欢迎。价格低廉的机器,最终运行的是成熟的Windows 10版本,但有一些改进(使其在低规格上运行得更好),以及这些改进带来的相应限制。

用Visual Studio、MSIX打包工具或高级安装程序创建的MSIX包可以毫无问题地安装在这些机器上,只要你在微软商店发布它们。

这与微软随Windows 8推出的Windows RT版本不是一回事。那些设备使用的是ARM处理器,因此不能运行X86编译的应用程序。目前用Windows 10 S模式发货的设备配备了基于x86的CPU。

有一个例外,新的设备系列Always-Connected-PC,仍将在ARM上运行。然而,这种新一代的ARM可以模拟x86指令集,所以你的桌面应用程序仍将在一些限制下运行。

可能的常见错误

请查看MSIX(APPX)打包的应用程序的常见问题列表,了解您可能面临的错误解释。


www.deepl.com 翻译