> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 更新プログラムの確認

> マルチプレイヤーの整合性を保つために、XStoreQueryGameAndDlcPackageUpdatesAsync を使用してタイトル内で XBOX ゲームおよび DLC パッケージの更新プログラムを確認して適用します。

ゲームを最新の状態に保つことが重要な場合、タイトルは更新プログラムをチェックして適用できます。この条件は、ゲームを実行するすべてのプレーヤーが同じ機能を持つことが極めて重要なマルチプレイヤー機能を含むゲームでよく重要になります。

タイトルは、次のサンプル コードに示すように、[XStoreQueryGameAndDlcPackageUpdatesAsync](/reference/system/xstore/xstore_members) を使用して更新プログラムを確認できます。

```cpp theme={null}
void CALLBACK QueryGameAndDlcPackageUpdatesCallback(XAsyncBlock* async)
{
    unsigned int numUpdates = 0;

    HRESULT hr = XStoreQueryGameAndDlcPackageUpdatesResultCount(async, &numUpdates);

    if (SUCCEEDED(hr))
    {
        if (numUpdates > 0)
        {
            std::vector<XStorePackageUpdate> packages(numUpdates);

            hr = XStoreQueryGameAndDlcPackageUpdatesResult(async, numUpdates, packages.data());

            if (SUCCEEDED(hr))
            {
                for (auto &package : packages)
                {
                    printf("Update available %s\n", package.packageIdentifier);
                }
            }
        }
        else
        {
            printf("No updates are available\n");
        }
    }

    delete async;
}

void CheckForUpdates()
{
    auto asyncBlock = new XAsyncBlock{};
    asyncBlock->queue = m_asyncQueue;
    asyncBlock->callback = QueryGameAndDlcPackageUpdatesCallback;

    if (FAILED(XStoreQueryGameAndDlcPackageUpdatesAsync(m_xStoreContext, asyncBlock)))
    {
        delete asyncBlock;
    }
}
```

更新チェックを必要としない DLC 項目がタイトルに多数含まれる場合 (たとえば、ライセンス供与のためだけに使用される空の DLC パッケージなど)、上記のコードでは各項目をチェックすることで不必要なオーバーヘッドが発生する可能性があります。

代わりに、[XPackageGetCurrentProcessPackageIdentifier](/reference/system/xstore/xstore_members) を使用して取得した現在のゲームのパッケージ ID でフィルターするか、[XPackageEnumeratePackages](/reference/system/xstore/xstore_members) から返されるパッケージ ID をフィルターして、[XStoreQueryPackageUpdatesAsync](/reference/system/xstore/xstore_members) を使用してください。

```cpp theme={null}
void CALLBACK QueryPackageUpdatesCallback(XAsyncBlock* async)
{
    unsigned int numUpdates = 0;

    HRESULT hr = XStoreQueryPackageUpdatesResultCount(async, &numUpdates);

    if (FAILED(hr))
    {
        printf("XStoreQueryPackageUpdatesResultCount failed : 0x%x\n", hr);
        return;
    }

    printf("Number of updates: %d", numUpdates);

    if (count > 0)
    {
        std::vector<XStorePackageUpdate> packages(numUpdates);

        hr = XStoreQueryPackageUpdatesResult(async, numUpdates, packages.data());
        
        if (SUCCEEDED(hr))
        {
            for (auto &package : packages)
            {
                printf("Update available %s\n", package.packageIdentifier);
            }
        }
    }
}

void QueryPackageUpdates()
{
    std::vector<std::string> packageIds;

    HRESULT hr = XPackageEnumeratePackages(
        XPackageKind::Game,
        XPackageEnumerationScope::ThisOnly, // this will return for the base game only
        &packageIds, [](void* context, const XPackageDetails* details) -> bool
        {
            auto packageIds = reinterpret_cast<std::vector<std::string>*>(context);

            printf("Identifier: %s name: %s\n", details->packageIdentifier, details->displayName);

            packageIds->push_back(details->packageIdentifier);
        });

    // packageIds now populated with just the base game package Id

    auto asyncBlock = new XAsyncBlock();
    asyncBlock->queue = m_asyncQueue;
    asyncBlock->context = m_storeContext;
    asyncBlock->callback = QueryPackageUpdatesCallback;

    hr = XStoreQueryPackageUpdatesAsync(
        m_storeContext,
        packageIds.data(),
        packageIds.size(),
        asyncBlock);

    if (FAILED(hr))
    {
        printf("XStoreQueryPackageUpdatesAsync failed: 0x%x\n", hr);
        return;
    }
}
```

## 更新プログラムのダウンロードとインストール

更新プログラムのセットを特定した後、[XStoreDownloadAndInstallPackageUpdatesAsync](/reference/system/xstore/xstore_members) を使用してすべての更新プログラムをキューに入れてダウンロードします。

<Note />

この時点で、ゲームは更新プログラムを適用するために終了します。このプロセスは警告なしに発生するため、この関数を呼び出す前にユーザーに十分な通知または確認を提供してください。

```cpp theme={null}
void DownloadUpdates()
{
    std::vector<const char*> packageIds;

    for (XStorePackageUpdate package : m_updates)
    {
        // m_updates populated from the update check
        packageIds.push_back(package.packageIdentifier);
    }

    if (!packageIds.empty())
    {
        auto asyncBlock = new XAsyncBlock{};
        asyncBlock->context = this;
        asyncBlock->queue = m_asyncQueue;
        asyncBlock->callback = [](XAsyncBlock* asyncBlockInner)
        {
            // Called when update is complete
            auto pThis = reinterpret_cast<Sample*>(asyncBlockInner->context);
            HRESULT hr = XStoreDownloadAndInstallPackageUpdatesResult(asyncBlockInner);

            delete asyncBlockInner;
        };

        HRESULT hr = XStoreDownloadAndInstallPackageUpdatesAsync(m_xStoreContext, packageIds.data(), packageIds.size(), asyncBlock);
    }
}
```

## ダウンロードの進行状況の監視

ダウンロードが進行中のときは、[XPackageCreateInstallationMonitor](/reference/system/xstore/xstore_members) を使用してダウンロードの進行状況を監視します。

```cpp theme={null}
void CreateInstallationMonitor(const char* packageId)
{
    XPackageInstallationMonitorHandle pimHandle;

    HRESULT hr = XPackageCreateInstallationMonitor(packageId, 0, nullptr, 1000, m_asyncQueue, &pimHandle);

    if(SUCCEEDED(hr))
    {
        XTaskQueueRegistrationToken callbackToken;

        XPackageRegisterInstallationProgressChanged(
            m_pimHandle,
            this,
            [](void* context, XPackageInstallationMonitorHandle pimHandle)
            {
                XPackageInstallationProgress progress;
                XPackageGetInstallationProgress(pimHandle, &progress);

                if(!progress.completed)
                {
                    printf("%llu%% installed\n", static_cast<double>(progress.installedBytes) / static_cast<double>(progress.totalBytes);
                }
                else
                {
                    XPackageCloseInstallationMonitorHandle(pimHandle);
                }
            }, &callbackToken);
    }
}
```

## 更新プログラムのテスト

開発中は、ローカル パッケージを使用してのみ、更新プログラムの可用性をテストできます。

1. 更新チェックとダウンロード コードを含む V1 パッケージを作成します。
2. 同じ ID でバージョン番号を増加させた V2 パッケージを作成します。
3. `xbapp/wdapp install` V1 を実行します。
4. `xbapp/wdapp update` V2 `/a` を実行します。
5. V1 を起動します。

パッケージ間でコンテンツ ID が一致していることを確認してください。

このプロセスの結果、V1 の `XStoreQueryGameAndDlcPackageUpdatesAsync` または `XStoreQueryPackageUpdatesAsync` の呼び出しで利用可能な更新プログラムが見つかり、`XStoreDownloadAndInstallPackageUpdatesAsync` は通知された V2 パッケージを使用して V1 を更新します。V2 の「ダウンロード」が進行中の場合、この状態は XBOX のダウンロード キュー、XBOX アプリ、または Microsoft Store アプリのキューに項目として表示されます。インストールが完了すると、V2 がインストールされます。`xbapp/wdapp list[dlc]` を使用してインストールを確認できます。

`/a` の代わりに `/m` を使用すると、更新プログラムが「必須」になります。これは、単に [XStorePackageUpdate](/reference/system/xstore/xstore_members)`.isMandatory` フィールドに影響します。

署名の違いにより、開発ビルドから Store からダウンロードするパッケージに更新することはできません。

効率的な更新プログラムの作成方法とテスト方法の詳細については、次のセクションで参照されているコンテンツ更新ページをご覧ください。

## リファレンス API ドキュメント

* [XStore (API の内容)](/reference/system/xstore/xstore_members)
  * 関数
    * [XStoreQueryGameAndDlcPackageUpdatesAsync](/reference/system/xstore/xstore_members)
    * [XStoreQueryPackageUpdatesAsync](/reference/system/xstore/xstore_members)
    * [XStoreDownloadAndInstallPackageUpdatesAsync](/reference/system/xstore/xstore_members)
  * 構造体
    * [XStorePackageUpdate](/reference/system/xstore/xstore_members)
* [XPackage (API の内容)](/reference/system/xstore/xstore_members)
  * 関数
    * [XPackageGetCurrentProcessPackageIdentifier](/reference/system/xstore/xstore_members)
    * [XPackageEnumeratePackages](/reference/system/xstore/xstore_members)
    * [XPackageCreateInstallationMonitor](/reference/system/xstore/xstore_members)

## 関連項目

[コマースの概要](/publishing/xstore-commerce/xstore-commerce-overview)

[XStore 開発とテストの有効化](/publishing/xstore-commerce/xstore-product-testing-setup)

コンテンツ更新のベスト プラクティス

コンテンツ更新の作成、確認、テスト

[XStore API リファレンス](/reference/system/xstore/xstore_members)


## Related topics

- [認定有料サービスプログラム](/ja-jp/publishing/game-publishing/concepts/certification/certification-paid-services.md)
- [Cert Bypass プログラム](/ja-jp/publishing/game-publishing/concepts/certification/cert-bypass.md)
- [Handheld Compatibility プログラム ガイドライン](/ja-jp/build/gdk-and-engines/handheld/handheld-guidance.md)
- [ゲーム サーバーのローカル デバッグと PlayFab との統合](/ja-jp/services/playfab/multiplayer/servers/locally-debugging-game-servers-and-integration-with-playfab.md)
- [Visual Studio (目次)](/ja-jp/tools/tools-pc/visualstudio/gr-visualstudio-toc.md)
