如何将 arm64 应用程序作为 WAP 项目分发到 Microsoft Store 中?

How to distribute arm64 app in the Microsoft Store as a WAP project?

我的 WPF 应用程序在 .NET Framework 4.8 上 运行 并作为 anyCPU 分发到应用商店。随着迁移到 .NET 6,我打算将应用程序重新分发为 x64、x86 和 arm64。

尝试将其发布为 appxbundle 时,我注意到 arm64 不可用:

当作为 anyCPU 发布时,我得到这个错误:

'Project.csproj' was resolved using '.NETCoreApp,Version=v6.0' instead of the project target framework '.NETFramework,Version=v4.5.1'. This project may not be fully compatible with your project.


我认为 WAP 项目是旧版本,这就是它没有 arm64 变体的原因,所以我尝试以某种方式更新它。没有找到任何方法来更新它,我创建了一个新的,引用相同的二进制文件(我的项目)并得到了这个:

但是在发布时,我得到这个错误:

The specified RuntimeIdentifier 'win-ARM64' is not recognized.


我的案例的迁移路径是什么? 此外,对于新的 Windows 11 Store,是否有任何方法可以使用相同的应用程序名称并使用 MSIX 或仅使用 MSI 进行分发?


当最新的包是 appxbundle 时尝试添加 msix 包给我这个错误:

A previous submission for this app was released with a Windows 10/11 .msixbundle or .appxbundle. Subsequent submissions must continue to contain a Windows 10/11 .msixbundle or .appxbundle.

它通过将应用发布为 msixbundle 而起作用。

起初,我尝试将其发布为三个独立的 msix(x86、x64 和 arm64),但由于我已发布为 appxbundle,因此我需要继续以捆绑形式发布,每Microsoft Store 的规则。

构建 msixmsixbundle 的过程并不直接,因为我没有这方面的经验,而且除了来自 Microsoft 的一些神秘文档外,可用的信息不多。


第一步是尝试了解 msix 包文件结构以及构建一个包需要什么。

我最初的想法是使用安装程序并使用 MSIX 打包工具 生成 msix 包。不幸的是,几乎无法控制设置或不设置的内容,而且过程非常繁琐(构建一个特殊的安装程序只是为了使用该工具进行转换)。

我选择使用命令行构建自己的 msix,而不是通过一组松散的文件。

过程有点简单,一开始发现要做什么不是。 我需要将所有文件复制到一个文件夹,然后设置一个名为 AppxManifest.xml 的清单文件,如下所示:

步骤是:

  1. 将所有文件复制到一个文件夹。由于我的应用程序是使用 .NET 6 制作的,因此我将其导出为独立的并将所有文件复制到其中 (~70MB)。
  2. 创建清单文件,命名为 AppxManifest.xml,只需根据需要更改版本和体系结构:
<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:uap6="http://schemas.microsoft.com/appx/manifest/uap/windows10/6" xmlns:uap10="http://schemas.microsoft.com/appx/manifest/uap/windows10/10" xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities" IgnorableNamespaces="uap uap6 uap10 rescap">
  <Identity Name="App ID" Publisher="Publisher ID" Version="0.0.0.0" ProcessorArchitecture="x64"/>

  <Properties>
    <DisplayName>App Name</DisplayName>
    <PublisherDisplayName>Publisher Name</PublisherDisplayName>
    <Description>App Description</Description>
    <Logo>Assets\StoreLogo.png</Logo>

    <uap10:PackageIntegrity>
      <uap10:Content Enforcement="on" />
    </uap10:PackageIntegrity>
  </Properties>

  <Resources>
    <Resource Language="en-us" />
  </Resources>

  <Dependencies>
    <TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.17763.0" MaxVersionTested="10.0.22000.1" />
  </Dependencies>

  <Applications>
    <Application Id="A Simple ID" Executable="AppName.exe" EntryPoint="Windows.FullTrustApplication">
      <uap:VisualElements BackgroundColor="transparent" DisplayName="AppName" Square150x150Logo="Assets/AppName-Square150x150Logo.png" Square44x44Logo="Assets/AppName-Square44x44Logo.png" Description="App Description">
        <uap:DefaultTile Wide310x150Logo="Assets/AppName-Wide310x150Logo.png" Square310x310Logo="Assets/AppName-Square310x310Logo.png" Square71x71Logo="Assets/AppName-Square71x71Logo.png" />
      </uap:VisualElements>
    </Application>
  </Applications>

  <Capabilities>
    <rescap:Capability Name="runFullTrust" />
  </Capabilities>
</Package>
  1. 生成一个 PRI 文件,索引资源。这个很难,因为我遇到了很多问题。我想索引我的图像资产,而不是其他文件。这是使徽标出现在 msix 安装程序 UI.
  2. 中的唯一方法

我通过调用 MakePri CLI 应用程序使用了一个配置文件:

.\makepri.exe new
/v
/cf '.\Resources\PriConfig.xml' --The config file bellow
/pr '.\Output' --The output folder where all files are located
/mn '.\Output\AppxManifest.xml' --The manifest file created before.
/o
/of '.\Output\Resources.pri'
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<resources targetOsVersion="10.0.0" majorVersion="1">
    <packaging>
        <autoResourcePackage qualifier="Scale"/>
    </packaging>

    <index root="\" startIndexAt="\">
        <default>
            <qualifier name="Language" value="en-us"/>
            <qualifier name="Contrast" value="standard"/>
            <qualifier name="Scale" value="100"/>
            <qualifier name="HomeRegion" value="001"/>
            <qualifier name="TargetSize" value="256"/>
            <qualifier name="LayoutDirection" value="LTR"/>
            <qualifier name="Theme" value="dark"/>
            <qualifier name="AlternateForm" value=""/>
            <qualifier name="DXFeatureLevel" value="DX9"/>
            <qualifier name="Configuration" value=""/>
            <qualifier name="DeviceFamily" value="Universal"/>
        </default>

        <indexer-config type="folder" foldernameAsQualifier="true" filenameAsQualifier="true" qualifierDelimiter=".">
            <exclude type="extension" value=".dll" doNotTraverse="true" doNotIndex="true"/>
            <exclude type="extension" value=".exe" doNotTraverse="true" doNotIndex="true"/>
            <exclude type="extension" value=".xml" doNotTraverse="true" doNotIndex="true"/>
            <exclude type="extension" value=".txt" doNotTraverse="true" doNotIndex="true"/>
            <exclude type="extension" value=".json" doNotTraverse="true" doNotIndex="true"/>
        </indexer-config>
    </index>
</resources>

重要的是在生成另一个文件时删除以前的 *.pri 文件,否则它也会将其编入索引。

  1. 生成每个 msix 包,每个架构一个。我只需要调用 makeappx.exe 传递这个命令:
makeappx.exe pack /d ".\Output" /p ".\AppName.Version.Architecture.msix" /v /o

根据需要更换版本和架构。

  1. (可选)唱包:

这一步我慢了下来。我有使用代码签名证书对包进行签名的想法(就像我的正常安装程序版本一样),但我发现我不能,至少不能用于商店版本,因为我需要使用相同的发布者 ID在 AppxManifest.xml 中,因为它是在我的用户的 Microsoft Store 配置中设置的。

为了能够对包进行签名,我需要将发布者 ID 设置为与证书的主题名称相同。

最后,我发布到商店的 msix/msixbundle 包没有代码签名,但我将在商店外分发的包是。

要签名,我只需要使用这个命令:

signtool.exe sign /f CERTIFICA-PATH /p PASSWORD /tr TIMESTAMP-URL /v /td sha256 /fd sha256 /du WEBSITE /a PATH-TO-MSIX-FILE

如果发布者 ID 与证书主题不同,它将失败。

  1. 由于我之前是作为捆绑包发布的(如appxbundle),我现在需要继续作为捆绑包发布(如msixbundle)。

要创建一个包,只需将所有 msix(在我的例子中是三个,x86、x64 和 arm64)复制到一个没有任何其他内容的文件夹中,然后调用此命令:

makeappx.exe bundle /bv 0.0.0.0 /d "PATH-TO-FOLDER-WITH-MISX" /p "PATH-TO-OUTPUT-MSIXBUNDLE"
  1. (可选)如果您打算在商店外发布,您也可以签署捆绑包。与步骤 5 相同。