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

# タイトルから wd ツールを呼び出す

> タイトルから wd ツールを呼び出す

このセクションでは、コンソール上に存在する wd ツールをタイトル コードから呼び出すための詳細とサンプル コードを提供します。たとえば、マルチプレイヤーのレイテンシの問題をデバッグするために、タイトル コードから wdtrace.exe を呼び出してネットワーク トレースを有効にする例があります。

## wd ツールを呼び出すサンプル タイトル コード

このサンプル コードでは、wdtrace プロセスを起動するヘルパー メソッドの詳細を説明します。この例の wdtrace は、任意の wd ツールに置き換えることができます。2 つ目のパラメーターは、そのツールを起動する際の引数です。

```c++ theme={null}
CreateAndRunRedirectedStdoutProcess(L"C:\\Windows\\System32\\wdtrace.exe", const_cast<wchar_t*>(L" start advancedmp"));
```

wdconfig.exe を使用した CreateAndRunRedirectedStdoutProcess メソッドのもう 1 つの例を以下に示します。

```c++ theme={null}
CreateAndRunRedirectedStdoutProcess(L"C:\\Windows\\System32\\wdconfig.exe", const_cast<wchar_t*>(L" query consolemode"));
```

これは、プロセスを作成し、Stdout からの出力を OutputDebugString にリダイレクトするヘルパー コードのサンプルです。これにより、Visual Studio または XbWatson に出力を表示できるようになります。代わりに、出力をファイルに保存するファイル書き込みに置き換えることもできます。

```c++ theme={null}
void
ReadAndHandleOutput(
    _In_ HANDLE hPipeRead)
{
    CHAR lpBuffer[256];
    DWORD nBytesRead;
    BOOL  result = TRUE;

    while (result)
    {
        ZeroMemory(lpBuffer, sizeof(lpBuffer));
        result = ReadFile(hPipeRead, lpBuffer, (sizeof(lpBuffer) - 1), &nBytesRead, NULL);
        if (!result || !nBytesRead)
        {
            if (GetLastError() == ERROR_BROKEN_PIPE)
            {
                break;
            }
            else
            {
                break;
            }
        }
        
        // Instead of outputting this via OutputDebugStringA, it could instead be written to a log file.
        
        try
        {
            OutputDebugStringA(lpBuffer);
        }
        catch (...)
        {
            return;
        }
    }
}

HRESULT
WINAPI
CreateAndRunRedirectedStdoutProcess(
    _In_ LPCWSTR mainExe,
    _In_ LPWSTR lpCommandLine)
{
    HRESULT hr = S_OK;

    HANDLE hOutputReadTmp = INVALID_HANDLE_VALUE;
    HANDLE hOutputRead = INVALID_HANDLE_VALUE;
    HANDLE hOutputWrite = INVALID_HANDLE_VALUE;
    HANDLE hErrorWrite = INVALID_HANDLE_VALUE;

    STARTUPINFO si = { 0 };
    PROCESS_INFORMATION pi = { 0 };
    si.cb = sizeof(si);

    SECURITY_ATTRIBUTES sa = { 0 };

    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = TRUE;

    if (!CreatePipe(&hOutputReadTmp, &hOutputWrite, &sa, 0))
    {
        OutputDebugString(L"Failed to create pipe");
        hr = HRESULT_FROM_WIN32(GetLastError());
        goto Exit;
    }

    if (!DuplicateHandle(GetCurrentProcess(), hOutputWrite, GetCurrentProcess(), &hErrorWrite, 0, TRUE, DUPLICATE_SAME_ACCESS))
    {
        OutputDebugString(L"Failed to dupicate handle");
        hr = HRESULT_FROM_WIN32(GetLastError());
        goto Exit;
    }

    if (!DuplicateHandle(GetCurrentProcess(), hOutputReadTmp, GetCurrentProcess(), &hOutputRead, 0, FALSE /*no inheritable*/, DUPLICATE_SAME_ACCESS))
    {
        OutputDebugString(L"Failed to duplicate handle");
        hr = HRESULT_FROM_WIN32(GetLastError());
        goto Exit;
    }

    // All redirection handles are created, set them and create the process
    si.dwFlags = 0x00000100; // STARTF_USESTDHANDLES;
    si.hStdOutput = hOutputWrite;
    si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
    si.hStdError = hErrorWrite;

    if (!CreateProcess(
        mainExe, lpCommandLine,
        nullptr, nullptr,
        true, CREATE_NO_WINDOW,
        nullptr, nullptr,
        &si, &pi))
    {
        OutputDebugString(L"Failed to create process");
        hr = HRESULT_FROM_WIN32(GetLastError());
        goto Exit;
    }

    // pThread is unneeded, so close it now.
    if (pi.hThread && pi.hThread != INVALID_HANDLE_VALUE)
    {
        CloseHandle(pi.hThread);
    }

Exit:

    // Close output and error handles
    if (hOutputReadTmp != INVALID_HANDLE_VALUE)
    {
        CloseHandle(hOutputReadTmp);
        hOutputReadTmp = INVALID_HANDLE_VALUE;
    }
    if (hOutputWrite != INVALID_HANDLE_VALUE)
    {
        CloseHandle(hOutputWrite);
        hOutputWrite = INVALID_HANDLE_VALUE;
    }
    if (hErrorWrite != INVALID_HANDLE_VALUE)
    {
        CloseHandle(hErrorWrite);
        hErrorWrite = INVALID_HANDLE_VALUE;
    }

    // Read output if present.  This method will block until the process
    // has exited.  Then close the handle.
    if (hOutputRead != INVALID_HANDLE_VALUE)
    {
        ReadAndHandleOutput(hOutputRead);
        CloseHandle(hOutputRead);
        hErrorWrite = INVALID_HANDLE_VALUE;
    }

    // Check the return code from the process
    if (pi.hProcess && pi.hProcess != INVALID_HANDLE_VALUE)
    {
        DWORD exitCode = WaitForSingleObject(pi.hProcess, INFINITE);

        if (exitCode != WAIT_OBJECT_0)
        {
            hr = HRESULT_FROM_WIN32(GetLastError());
        }
        else if (!GetExitCodeProcess(pi.hProcess, &exitCode))
        {
            hr = HRESULT_FROM_WIN32(GetLastError());
        }
        else
        {
            if (exitCode)
            {
                hr = E_FAIL;
            }
        }

        CloseHandle(pi.hProcess);
        pi.hProcess = INVALID_HANDLE_VALUE;
    }

    return hr;
}
```

## 関連項目

[コンソール コマンドライン ツール](/tools/tools-console/console_commandlinetools/consolecommandlinetools)

[XTF トランスポート エラー](/tools/tools-console/commandlinetools/xtf-transport-errors)


## Related topics

- [コンソール ベースのコマンドライン ツール](/ja-jp/tools/tools-console/console_commandlinetools/consolecommandlinetools.md)
- [XBOX のコンソール ベースのコマンドライン ツール](/ja-jp/tools/tools-console/console_commandlinetools/index.md)
- [Azure Functions を利用した PlayFab CloudScript のクイックスタート ガイド](/ja-jp/services/playfab/live-service-management/service-gateway/automation/cloudscript-af/quickstart.md)
- [タイトルからのレピュテーション フィードバックの送信](/ja-jp/services/xbox-services/community/reputation/concepts/live-sending-reputation-feedback.md)
- [Game Saves ツール](/ja-jp/build/core-features/common/game-save/game-saves-tools.md)
