> ## 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. 동일한 identity를 가지되 버전 번호가 증가된 V2 패키지를 만듭니다.
3. `xbapp/wdapp install` V1을 실행합니다.
4. `xbapp/wdapp update` V2 `/a`를 실행합니다.
5. V1을 실행합니다.

패키지 간에 content ID가 일치하는지 확인합니다.

이 프로세스의 결과로 V1의 `XStoreQueryGameAndDlcPackageUpdatesAsync` 또는 `XStoreQueryPackageUpdatesAsync` 호출이 사용 가능한 업데이트를 찾고 `XStoreDownloadAndInstallPackageUpdatesAsync`가 광고된 V2 패키지를 사용하여 V1을 업데이트합니다. V2 "다운로드"가 진행 중일 때 이 상태는 XBOX 다운로드 큐, XBOX 앱 또는 Microsoft Store 앱에 큐의 항목으로 표시됩니다. 설치가 완료되면 V2가 설치됩니다. `xbapp/wdapp list[dlc]`를 사용하여 설치를 확인할 수 있습니다.

`/a` 대신 `/m`을 사용하면 업데이트가 "mandatory(필수)"로 표시되며, 이는 단순히 [XStorePackageUpdate](/reference/system/xstore/xstore_members)`.isMandatory` 필드에 영향을 줍니다.

서명 차이로 인해 개발 빌드에서 스토어에서 다운로드되는 패키지로 업데이트할 수 없습니다.

효율적인 업데이트를 만들고 다양한 방법으로 테스트하는 방법에 대한 자세한 내용은 다음 섹션에서 참조하는 콘텐츠 업데이트 페이지를 참고하세요.

## 참조 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

- [콘텐츠 업데이트 모범 사례](/ko/build/core-features/common/packaging/packaging-updates.md)
- [콘텐츠 업데이트 만들기, 검토 및 테스트](/ko/build/core-features/common/packaging/packaging-testing-updates.md)
- [패키지 고급 설정](/ko/publishing/game-publishing/how-to/how-to-manage-advanced-settings-for-packages.md)
- [XStoreQueryGameAndDlcPackageUpdatesAsync](/ko/reference/system/xstore/functions/xstorequerygameanddlcpackageupdatesasync.md)
- [XStoreQueryPackageUpdatesAsync](/ko/reference/system/xstore/functions/xstorequerypackageupdatesasync.md)
