如果将应用程序作为 Web 下载(EXE /MSI)和应用商店中作为打包应用程序(MSIX)分发,你可能希望阻止用户安装这两个版本或将用户从未打包的 Web 版本迁移到应用商店版本。 本指南将提供有关如何将用户从未打包的版本无缝过渡到打包版本的说明。
下面将介绍两种方案:
- 用户已安装基于 Web 的未打包版本,并且希望将其替换为应用商店的打包版本。
- 用户已安装这两个版本,你希望优先使用 Store 打包的版本并卸载基于 Web 的未打包版本。
方案 1:将未打包的网页应用程序自动更新为商店打包的应用程序
如果打算将用户从 Web 解压缩的应用程序自动迁移到打包的应用商店版本,建议执行以下步骤:
- 确保您的商店打包应用程序能够使用现有的任务栏和开始菜单图钉,当商店打包应用程序替换未打包的Web应用程序时,用户可以保留他们的快捷方式。
- 请参阅以下部分:迁移现有的固定任务栏和开始菜单快捷方式
- 以静默方式从未打包的 Web 版本中下载并安装应用商店版本。
- 向用户指示应用程序将重启以应用更新
- 下载并安装后,启动 Microsoft Store 打包版本并关闭 Web 解压缩版本。
- 请参阅部分: 如何从 Web 解压缩的应用启动应用商店应用程序?
- 在商店打包的应用程序中,将数据迁移到新的应用数据文件夹。
- 请参阅部分: 迁移数据
- 最后,以编程方式卸载未打包的 Web 版本。
方案 2:如果用户安装了这两个版本,请卸载基于 Web 的未打包应用程序。
你可以允许用户并行使用应用程序的这两个版本,但你必须管理应用程序之间的冲突,并将负责在 2 个版本之间同步数据。
如果你希望用户仅使用 1 个版本并设置应用商店版本的优先级,下面是一些建议:
- 使商店打包的应用程序能够使用现有的任务栏和开始菜单图标,确保在商店打包的应用程序替换未打包的 Web 应用程序时,用户保留其快捷方式。
- 请参阅章节:迁移现有的固定任务栏和“开始”菜单快捷方式
- 应用商店应用程序应检测未打包的版本是否存在并在启动时卸载它
- 请参阅部分: 如何检测是否已安装并启动应用商店打包版本?
- 当用户启动未打包的应用程序时,应自动启动打包的版本
- 请参阅部分:如何从非封装的 Web 应用启动商店应用程序?
- 如果需要,可能会迁移数据
- 请参阅部分: 迁移数据
- 最后,以编程方式卸载未打包的 Web 版本。
技术建议
如何从 Web 解压缩的应用程序安装应用商店打包的应用程序
若要启动下载和安装,必须知道应用程序的应用商店 ID。 此 12 个字符的 ID 可以从合作伙伴中心获取,特别是在“产品标识”部分下,即使尚未提交应用程序。
随后,可以使用以下代码以无提示方式下载并安装应用商店应用程序。 此代码将会:
- 向当前应用商店用户分配权利(如果存在);否则,权利将与设备关联。
- 开始下载并安装产品,而无需生成任何通知提示。
- 可以使用事件 API 监视下载和安装进度。
private async Task<bool> DownloadStoreVersionAsync()
{
var productId = "<Product Id from Partner Center>";
var applicationName = "<name of your application>";
var appInstallManager = new AppInstallManager();
var entitlement = await appInstallManager.GetFreeUserEntitlementAsync(productId, string.Empty, string.Empty);
if (entitlement.Status is GetEntitlementStatus.NoStoreAccount)
{
entitlement = await appInstallManager.GetFreeDeviceEntitlementAsync(productId, string.Empty, string.Empty);
}
if (entitlement.Status is not GetEntitlementStatus.Succeeded)
{
return false;
}
var options = new AppInstallOptions()
{
LaunchAfterInstall = true,
CompletedInstallToastNotificationMode = AppInstallationToastNotificationMode.NoToast
};
var items = await appInstallManager.StartProductInstallAsync(productId, string.Empty, applicationName, string.Empty, options);
var firstItem = items.FirstOrDefault();
if(firstItem is null)
{
return false;
}
firstItem.StatusChanged += StoreInstallation_StatusChanged;
firstItem.Completed += StoreInstallation_Completed;
return true;
}
private void StoreInstallation_Completed(AppInstallItem sender, object args)
{
// Launch the new Store version when ready and close this application
// The Store version will then be responsible of migrating the data and uninstall the unpackaged version
}
private void StoreInstallation_StatusChanged(AppInstallItem sender, object args)
{
var status = sender.GetCurrentStatus();
switch(status.InstallState)
{
case AppInstallState.Installing:
{
// Show installing status
}
break;
case AppInstallState.Downloading:
{
// Show download progress using status.PercentComplete
}
break;
...
}
如何从 Web 解压缩的应用启动应用商店应用程序
若要启动应用商店应用程序,必须知道其 AMUID,该 ID 由程序包系列名称(在合作伙伴中心的“产品标识”部分中找到)和应用程序 ID(来自 appxmanifest)(以感叹号(!)分隔)。
Process.Start(
"explorer.exe",
"shell:AppsFolder\\Microsoft.WindowsCalculator_8wekyb3d8bbwe!App"
);
如何检测是否已安装应用商店打包版本并启动它
可以使用 GetPackagesByPackageFamily win32 API,并传入您打包应用程序的包系列名称,来确定应用程序的打包版本是否已安装。 如果计数值高于零,则表示已安装应用程序。
如何从已打包的版本中卸载未打包的 Web 应用程序
若要检索卸载者的绝对路径,可以访问注册表。
卸载程序信息位于注册表中:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\<your product code GUID\>
检索值中的 UninstallString
完整命令并执行它。
建议以无提示方式执行卸载,或通知用户正在迁移数据并卸载其他应用程序。
如何迁移数据
未打包的应用程序可能会将其本地数据存储在:
%localAppData%/<YourPublisherName\>/<YourAppName\>
打包的应用程序为数据存储保留空间,在卸载应用程序时会自动删除该空间。 强烈建议在首次发射时将数据迁移到此空间(尽管不是强制性的)。 可以通过调用 Windows.Storage.ApplicationData.Current.LocalFolder.Path 来检索此文件夹的绝对路径。
如何迁移购置和应用内购买
应用内购买
为了保证最佳的用户体验,用户必须无缝访问他们在应用程序未打包版本中购买的内容。 为了实现这一目标,Microsoft Store 自 2021 年 6 月以来除了Microsoft商业平台之外,还允许使用发布者自己的或第三方商业平台,从而提高发布者们的灵活性。
我们强烈建议发布者继续验证在其应用程序未打包版本中执行的应用内购买权益,并与 Microsoft Commerce 平台集成,以便用户能够在 Windows 上轻松地只需几次点击即可购买您的内容。
允许未打包应用程序的付费用户迁移到打包版本
如果用户在网站上购买了你的产品,则他们不必再次付费才能从应用商店下载打包的版本。 为了确保无缝过渡,我们建议采用以下方法:
- 提供产品的免费/演示版本,允许用户通过应用内购买解锁完整版本。 对于已在网站上付费的用户,他们可以通过登录以验证许可证或在应用程序的用户界面中输入许可证密钥来访问完整版本。
- 将应用程序设置为付费产品/服务,但通过自己的渠道将优惠券代码分发给现有用户。 这些代码将允许他们下载应用商店版本,无需额外付费。 可以在 “生成促销代码”中找到详细信息。
如何迁移现有的固定任务栏和“开始”菜单快捷方式
用户可能已将桌面应用程序固定到任务栏或“开始”菜单。 可以通过在应用程序清单中包含“windows.desktopAppMigration”扩展,将这些快捷方式定向到新的打包应用。
示例:
xmlns:rescap3="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities/3"
...
<Extensions>
<rescap3:Extension Category="windows.desktopAppMigration">
<rescap3:DesktopAppMigration>
<rescap3:DesktopApp AumId="[your_app_aumid]" />
<rescap3:DesktopApp ShortcutPath="%USERPROFILE%\Desktop\[my_app].lnk" />
<rescap3:DesktopApp ShortcutPath="%APPDATA%\Microsoft\Windows\Start Menu\Programs\[my_app].lnk" />
<rescap3:DesktopApp ShortcutPath="%PROGRAMDATA%\Microsoft\Windows\Start Menu\Programs\[my_app_folder]\[my_app].lnk"/>
</rescap3:DesktopAppMigration>
</rescap3:Extension>
</Extensions>
安装应用程序后,任务栏或“开始”菜单中的引脚以及磁贴(适用于 Windows 10)将自动启动应用商店应用程序。
如何迁移文件扩展名和协议关联
如果应用程序支持文件扩展名或协议关联,并且用户已将应用选为特定文件扩展名和协议的默认应用程序,则可以选择将这些关联迁移到应用商店打包的应用程序。 可以通过使用以下代码片段更新应用清单来实现此迁移。
xmlns:rescap3="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities/3"
...
<Extensions>
<uap:Extension Category="windows.fileTypeAssociation">
<uap3:FileTypeAssociation Name=".foo">
<rescap3:MigrationProgIds>
<rescap3:MigrationProgId>Foo.Bar.1</rescap3:MigrationProgId>
</rescap3:MigrationProgIds>
…
</uap3:FileTypeAssociation>
</uap:Extension>
</Extensions>
只需列出要迁移到的 编程标识符 ,系统会在安装后自动将其迁移到应用程序。