> ## 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.

# XUserAddAsync

> XUserAddAsync

# XUserAddAsync

ゲーム セッションにユーザーを非同期に追加します。

## 構文

```cpp theme={null}
HRESULT XUserAddAsync(  
         XUserAddOptions options,  
         XAsyncBlock* async  
)  
```

### パラメーター

*options*   \_In\_\
Type: [XUserAddOptions](/reference/system/xuser/enums/xuseraddoptions)

ゲーム セッションにユーザーを追加するためのオプションです。

*async*   \_Inout\_\
Type: [XAsyncBlock\*](/reference/system/xasync/structs/xasyncblock)

呼び出しの状態のポーリングおよび呼び出し結果の取得に使用する [XAsyncBlock](/reference/system/xasync/structs/xasyncblock)。

### 戻り値

Type: HRESULT

HRESULT の成功またはエラー コード。
エラー コードの一覧については、[エラー コード](/reference/errorcodes) を参照してください。

## 解説

**XUserAddAsync** は、ユーザーをゲームに追加するための非同期操作を開始します。操作の結果を取得するには、[XUserAddResult](/reference/system/xuser/functions/xuseraddresult) を使用します。

**XUserAddAsync** は、*options* パラメーターに [XUserAddOptions::AddDefaultUserSilently](/reference/system/xuser/enums/xuseraddoptions) または [XUserAddOptions::AddDefaultUserAllowingUI](/reference/system/xuser/enums/xuseraddoptions) のいずれかが渡されない限り、常にアカウント ピッカー UI を表示します。

**XUserAddOptions::AddDefaultUserSilently** を使用する場合、**XUserAddAsync** は UI を表示しません。

[簡易ユーザー モデル (NDA トピック)](/build/core-features/common/user/gamecore-user-models) を使用する際、この関数にはいくつかの考慮事項があります:

* 簡易ユーザー モデルでは、開発者は *options* が **XUserAddOptions::AddDefaultUserSilently** に設定されるようにしてください:
* 本体では、簡易ユーザー モデルを使用してルーズにデプロイされたゲームは、既定のユーザーが既にサインインしていなければ起動できません。
* PC では、簡易ユーザー モデルを使用してルーズにデプロイされたゲームは、ユーザーなしで起動できます。ただし、ゲームが **XUserAddAsync** を呼び出したときに誰もサインインしていない場合、ゲームは終了され、PC ブートストラッパーが起動してユーザーのサインインを支援します。以降の起動は、ユーザーが XBOX Live に完全にサインインしている限り正常に動作します。

*options* に **XUserAddOptions::AddDefaultUserSilently** を設定して **XUserAddAsync** を繰り返し呼び出す場合、開発者が知っておくべきエッジ ケースがいくつかあります:

* ゲームを起動した既定のユーザーが判明している状態でこれを繰り返し呼び出すと、同じユーザーが返されます。
* 以前に判明していた既定のユーザーがサインアウトしており、デバイスに 1 人のユーザーだけがサインインしている場合、そのユーザーが新しい「既定」のユーザーとしてマークされ、そのユーザーが返されます。
* 以前に判明していた既定のユーザーがサインアウトしており、デバイスに複数のユーザーがサインインしている場合、E\_GAMEUSER\_NO\_DEFAULT\_USER が返されます。

既定のユーザーが利用できない場合、[XUserAddResult](/reference/system/xuser/functions/xuseraddresult) は E\_GAMEUSER\_NO\_DEFAULT\_USER を返します。*options* に **XUserAddOptions::AddDefaultUserSilently** を設定せずに **XUserAddAsync** を呼び出す必要があります。

*options* に **XUserAddOptions::AddDefaultUserAllowingUI** を設定して **XUserAddAsync** を繰り返し呼び出す場合にも、開発者が知っておくべきエッジ ケースがいくつかあります。これらは、サイレント UI の場合と非常に似ています (ただし同一ではありません):

* ゲームを起動した既定のユーザーが判明している状態でこれを繰り返し呼び出すと、同じユーザーが返されます。
* 以前に判明していた既定のユーザーがサインアウトしており、デバイスに 1 人のユーザーだけがサインインしている場合、そのユーザーが新しい「既定」のユーザーとしてマークされ、そのユーザーが返されます。
* 最初にゲームを起動したユーザーがサインアウトしており、ユーザー数が 0 人または 2 人以上の場合、システムはユーザーを取得するために UI を表示し、そのユーザーを既定として設定します。

[XUserAddOptions::AllowGuests](/reference/system/xuser/enums/xuseraddoptions) を **XUserAddOptions::AddDefaultUserSilently** と一緒に使用することはできません。ゲストは既定のユーザーになれません。現在のプラットフォームがゲストをサポートしているかどうかに関係なく、**XUserAddOptions::AllowGuests** を安全に使用できます。

**XUsers** API から取得したそれぞれの **XUserHandle** ハンドルは、[XUserCloseHandle](/reference/system/xuser/functions/xuserclosehandle) を呼び出して 1 回だけ閉じる必要があります。

入力デバイスのペアリングは、**XUserAddAsync** の正常完了時に実行されます。**XUserAddOptions::AddDefaultUserSilently** または **XUserAddOptions::AddDefaultUserAllowingUI** オプションによって UI なしで自動的にサインインが行われた場合、システム内でユーザーに割り当てられている入力デバイスがタイトルに伝達されます。サインインのために UI が表示された場合、ユーザーを選択した入力デバイスがそのユーザーに割り当てられます。

デバイスの関連付けは、[XUserRegisterForDeviceAssociationChanged](/reference/system/xuser/functions/xuserregisterfordeviceassociationchanged) メソッドを介して追跡できます。

次の例では、ゲーム セッションにユーザーを非同期に追加する方法を示します。

```cpp theme={null}
HRESULT AddUserComplete(XAsyncBlock* ab)
{
    unique_user_handle user;
    RETURN_IF_FAILED(XUserAddResult(ab, &user));

    XUserLocalId userLocalId;
    XUserGetLocalId(user.get(), &userLocalId);

    auto iter = std::find_if(
        _users.begin(),
        _users.end(),
        [&userLocalId](const User& candidate)
    {
        XUserLocalId candidateUserLocalId;
        XUserGetLocalId(candidate.Handle(), &candidateUserLocalId);
        return candidateUserLocalId == userLocalId;
    });

    // User already known
    if (iter != _users.end())
    {
        appLog.AddLog("User already in list\n");
        return S_OK;
    }

    try
    {
        _users.emplace_back(user.get());
        _users.back().LoadGamerPicAsync(_queue);
    }
    CATCH_RETURN();

    return S_OK;
}

HRESULT AddUser(bool allowGuests, bool silent)
{
    auto asyncBlock = std::make_unique<XAsyncBlock>();
    ZeroMemory(asyncBlock.get(), sizeof(*asyncBlock));
    asyncBlock->queue = _queue;
    asyncBlock->context = this;
    asyncBlock->callback = [](XAsyncBlock* ab)
    {
        auto asyncBlock = std::unique_ptr<XAsyncBlock>(ab);
        LOG_IF_FAILED(static_cast<UserWindow*>(ab->context)->AddUserComplete(ab));
    };

    XUserAddOptions options = XUserAddOptions::None;

    if (allowGuests)
    {
        WI_SET_FLAG(options, XUserAddOptions::AllowGuests);
    }

    if (silent)
    {
        WI_SET_FLAG(options, XUserAddOptions::AddDefaultUserSilently);
    }

    if (SUCCEEDED_LOG(XUserAddAsync(
        options,
        asyncBlock.get())))
    {
        // The call succeeded, so release the std::unique_ptr ownership of XAsyncBlock* since the callback will take over ownership.
        // If the call fails, the std::unique_ptr will keep ownership and delete the XAsyncBlock*
        asyncBlock.release();
    }

    return S_OK;
}
```

## 要件

**ヘッダー:** XUser.h

**ライブラリ:** xgameruntime.lib

**サポートされているプラットフォーム:** Windows、Steam Deck、XBOX One 本体、XBOX Series 本体

## 概念ドキュメント

* [Microsoft Game Development Kit (GDK) API タスクを実行する](/build/core-features/common/async/async-libraries/async-library-xasync-example-run-gdk-task)
* [非同期プログラミングの設計目標と改善点](/build/core-features/common/async/async-whitepaper)
* [Implement player sign-in in your game](https://learn.microsoft.com/gaming/gdk/docs/gdk-dev/pc-dev/tutorials/pc-e2e-guide/e2e-services/e2e-user-sign-in)
* [Game Chat 2 の概要](/services/xbox-services/multiplayer/chat/game-chat2/game-chat-2-intro)
* [Game Chat 2 C++ API の使用](/services/xbox-services/multiplayer/chat/game-chat2/using-game-chat-2)
* [Implement player sign in](https://learn.microsoft.com/gaming/gdk/docs/services/playfab-integration/gdk-playfab-player-sign-in-steps)

## 関連項目

[XUser](/reference/system/xuser/xuser_members)

[XUserAddOptions](/reference/system/xuser/enums/xuseraddoptions)

[XUserCloseHandle](/reference/system/xuser/functions/xuserclosehandle)


## Related topics

- [XUserAddOptions](/ja-jp/reference/system/xuser/enums/xuseraddoptions.md)
- [XUserAddResult](/ja-jp/reference/system/xuser/functions/xuseraddresult.md)
- [GDK 向け Unity C# API ラッパー](/ja-jp/build/gdk-and-engines/unity/unity-api-wrappers.md)
- [Microsoft Game Development Kit API タスクの実行例](/ja-jp/build/core-features/common/async/async-libraries/async-library-xasync-example-run-gdk-task.md)
- [ユーザーとコントローラーの関連付けが発生するのはいつか?](/ja-jp/build/core-features/common/user/users-timing-of-user-to-device-association.md)
