Web のパッケージ化されていないアプリから Store のパッケージ化されているアプリにユーザーを移行する方法

アプリケーションを Web ダウンロード (EXE/MSI) として配布するのに加えて、パッケージ化されているアプリケーション (MSIX) として Store で配布する場合は、ユーザーが両方のバージョンをインストールできないようにしたり、パッケージ化されていない Web バージョンから Store バージョンにユーザーを移行したりできないようにできます。 このガイドでは、パッケージ化されていないバージョンからパッケージ化されているバージョンにユーザーをシームレスに移行する手順について説明します。

以下の 2 つのシナリオについて説明します。

  1. 既にユーザーによって Web ベースのパッケージ化されていないバージョンがインストール済みであり、Store のパッケージ化されているバージョンに置き換えたいと考えている。
  2. ユーザーによって両方のバージョンが既にインストール済みであり、Store のパッケージ化されているバージョンを優先して、Web ベースのパッケージ化されていないバージョンをアンインストールしたいと考えている。

シナリオ 1: パッケージ化されていない Web アプリケーションを Store のパッケージ化されたアプリケーションに自動的に更新する

Web のパッケージ化されていないアプリケーションから Store のパッケージ化されているバージョンにユーザーを自動的に移行する場合、次の手順に従うことをお勧めします。

  1. Store のパッケージ化されているアプリケーションで既存のタスク バーとスタート メニュー ピンを使用可能にし、Store のパッケージ化されているアプリケーションが Web のパッケージ化されていないアプリケーションに置き換わるときにユーザーがショートカットを保持できるようにします。
  2. Web のパッケージ化されていないバージョンから Store バージョンをダウンロードしてサイレント モードでインストールします。
  3. アプリケーションが再起動して更新プログラムが適用されることをユーザーに表示する
  4. ダウンロードおよびインストールされたら、Store のパッケージ化されているバージョンを起動し、Web のパッケージ化されていないバージョンを閉じます。
  5. Store のパッケージ化されているアプリケーションで、データを新しいアプリ データ フォルダーに移行します。
  6. 最後に、Web のパッケージ化されていないバージョンをプログラムによりアンインストールします。

シナリオ 2: ユーザーによって両方のバージョンがインストール済みの場合に、Web ベースのパッケージ化されていないアプリケーションをアンインストールする。

ユーザーがアプリケーションの両方のバージョンを同時に使用することを許可できますが、アプリケーション間の競合を管理する必要があり、2 つのバージョン間でデータを同期する必要もあります。

ユーザーが片方のバージョンのみを使用可能にし、Store バージョンを優先させる場合、いくつかの推奨事項を以下に示します。

  1. Store のパッケージ化されているアプリケーションで既存のタスク バーとスタート メニュー ピンを使用可能にし、Store のパッケージ化されているアプリケーションが Web のパッケージ化されていないアプリケーションに置き換わるときにユーザーがショートカットを保持できるようにします。
  2. Store アプリケーションは、パッケージ化されていないバージョンが存在するかどうかを検出し、起動時にアンインストールする必要がある
  3. ユーザーがパッケージ化されていないアプリケーションを起動しようとしたとき、パッケージ化されているバージョンを自動的に起動する
  4. 必要に応じてデータの移行が必要となる可能性がある
  5. 最後に、Web のパッケージ化されていないバージョンをプログラムによりアンインストールします。

技術的な推奨事項

パッケージ化されていない Web アプリケーションから Store のパッケージ化されてきるアプリケーションをインストールする方法

ダウンロードとインストールを開始するには、アプリケーションの Store ID を知っている必要があります。 この 12 文字の ID は、アプリケーションがまだ送信されていない場合でも、パートナー センター、具体的には [製品 ID] セクションの下から取得できます。

その後、以下のコードを使用して、Store アプリケーションをサイレント モードでダウンロードしてインストールできます。 このコードでは次のことを行います。

  1. 現在の Store ユーザーにエンタイトルメントを割り当てます (存在する場合)。存在しない場合、エンタイトルメントはデバイスに関連付けられます。
  2. 通知トーストを生成せずに製品のダウンロードとインストールを開始します。
  3. イベント 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 のパッケージ化されていないアプリから Store のアプリケーションを起動する方法

Store アプリケーションを起動するには、AMUID を知っている必要があります。これは、パッケージ ファミリ名 (パートナー センターの [製品 ID] セクションで確認できます) とアプリケーション ID (appxmanifest から) で構成されており、感嘆符 (!) で区切られています。

        Process.Start(
            "explorer.exe",
            "shell:AppsFolder\\Microsoft.WindowsCalculator_8wekyb3d8bbwe!App"
        );

Store のパッケージ化されているバージョンがインストールされているかどうかを検出して起動する方法

GetPackagesByPackageFamily win32 API を使用し、パッケージ化されているアプリのパッケージ ファミリ名を渡すことにより、パッケージ化されているバージョンのアプリケーションがインストールされているかどうかを確認できます。 カウント値が 0 より大きい場合、アプリケーションがインストールされていることを示しています。

パッケージ化されていない 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 に加えて独自またはサード パーティのコマース プラットフォームの使用が許可されているため、発行者の柔軟性が向上しています。

ユーザーが Windows で数回クリックすればコンテンツを簡単に購入可能にするため、発行者には、Microsoft Commerce プラットフォームと統合するだけでなく、パッケージ化されていないバージョンのアプリケーションで実行していたのと同じようにアプリ内購入のエンタイトルメントを引き続き検証することを強くお勧めします。

パッケージ化されていないアプリケーションの有料ユーザーがパッケージ化されているバージョンに移行可能にする

ユーザーが Web サイトで製品を購入した場合、パッケージ化されているバージョンを Store からダウンロードする際に再度お支払いの必要はありません。 シームレスな移行を確実にするため、以下のアプローチをお勧めします。

  1. 製品の無料/デモ バージョンを提供することにより、ユーザーがアプリ内購入を通じて完全バージョンのロックを解除可能にする。 Web サイトで既にお支払い済みのユーザーの場合、サインインしてライセンスを確認するか、アプリケーションのユーザー インターフェイスでライセンス キーを入力して、完全バージョンにアクセス可能にする。
  2. アプリケーションを有料サービスとして設定するが、独自のチャネルを通じて既存のユーザーにクーポン コードを配布する。 これらのコードを使用すると、追加コストなしで Store バージョンをダウンロードできます。 詳しくは、「プロモーション コードを生成する」をご覧ください。

既存のピン留めされたタスク バーとスタート メニューのショートカットを移行する方法

ユーザーは、デスクトップ アプリケーションをタスク バーやスタート メニューにピン留めすることがあります。 アプリケーション マニフェストに "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 の場合) によって Store アプリケーションが自動的に起動するようになります。

ファイル拡張子とプロトコルの関連付けを移行する方法

ファイル拡張子またはプロトコルの関連付けがアプリケーションでサポートされていて、ユーザーが特定のファイル拡張子とプロトコルの既定のアプリケーションとしてそのアプリを選択している場合は、それらの関連付けを Store のパッケージ化されているアプリケーションに移行することができます。 この移行は、次のコード スニペットを使用してアプリ マニフェストを更新することにより実現できます。

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>

移行対象のプログラム識別子を一覧表示するだけで、インストール後に自動的にそのアプリケーションに移行されます。