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

# XtfGetAvailableSpaceForAppInstallation

> XtfGetAvailableSpaceForAppInstallation

# XtfGetAvailableSpaceForAppInstallation

获取开发主机上指定存储设备的可用总字节数。

<a id="syntaxSection" />

## 语法

```cpp theme={null}
HRESULT XtfGetAvailableSpaceForAppInstallation(
         LPCWSTR address,
         LPCWSTR storageName,
         UINT64 *bytes
)  
```

<a id="parametersSection" />

### 参数

*address*\
类型：LPCWSTR

\[in] 要检查的开发主机的地址。

*storageName*\
类型：LPCWSTR

\[in] 要检查的存储设备的名称。允许使用以下值：

| 值         | 说明      |
| --------- | ------- |
| `nullptr` | 默认存储设备。 |
| internal  | 内部存储设备。 |

*bytes*\
类型：UINT64\*

\[out] *address* 中指定的开发主机上，*storageName* 中指定的存储设备上的可用总字节数。

<a id="retvalSection" />

### 返回值

类型：HRESULT

如果成功，则返回 `S_OK`；否则返回 HRESULT 错误代码。

<a id="remarksSection" />

## 备注

此函数获取开发主机上指定存储设备的可用总字节数，允许为主机编写自定义部署工具的工具开发人员在开始安装过程之前检查是否有足够空间来安装应用包。有关 XBOX Tools Framework (XTF) 工具的详细信息，请参阅 [命令行工具 (NDA 主题)](/tools/tools-console/commandlinetools/commandlinetools)。

以下代码示例演示如何计算应用包所需的空间。

```cpp theme={null}
#include <stdio.h>
#include <conio.h>
#include <Windows.h>
#include <xtfapi.h>

//Round up file sizes to the nearest 4K boundary to get a better estimate of the actual size of disk
#define ESTIMATED_FILE_SIZE_ON_DISK(fileSize) ((fileSize + ((4UI64 * 1024UI64) - 1)) & ~((4UI64 * 1024UI64) - 1))

//Size of the buffer (string) that we use to contain file/directory names - MAX_PATH + 1 for the terminating null
#define DIR_BUFFER_LENGTH (MAX_PATH + 1)

//Forward declaration of the function that figures out the game size on disk
UINT64 EstimateRequiredSpace(LPWSTR targetDir) ;

//Calculates whether there is enough disk space to deploy the game
//Returns an ERRORLEVEL:
//   0 - OK - Enough space
//   1 - ERROR - Not enough space
//   2 - ERROR - Other error
int wmain(int argc, wchar_t **argv)
{
    HRESULT hr              = S_OK;
    UINT64  availableBytes  = 0;
    UINT64  requiredBytes   = 0;
    LPWSTR  consoleAddress  = nullptr;
    LPWSTR  targetDir       = nullptr;

    if (argc != 3)
    {
        wprintf(L"\nUsage: %s <consoleAddress> <directory name>\n", argv[0]);
        return 2;
    }

    consoleAddress = argv[1];
    targetDir = argv[2];

    wprintf(L"\nTarget console is %s\n", consoleAddress);
    wprintf(L"\nTarget directory is %s\n\n",targetDir);

    hr = XtfGetAvailableSpaceForAppInstallation(consoleAddress, L"Internal", &availableBytes);
    if (hr != S_OK)
    {
        wprintf(L"\n\n*** Error %d", hr);
        return 2;
    }

    requiredBytes = EstimateRequiredSpace(targetDir);
    if (hr != S_OK)
    {
        wprintf(L"\n\n*** Error calculating size");
        return 2;
    }

    wprintf(L"*** Space available on console is %I64u \n", availableBytes);
    wprintf(L"*** Space required is %I64u \n", requiredBytes);

    if (requiredBytes > availableBytes)
    {
        wprintf(L"*** DO NOT DEPLOY \n");
        return 1;
    }

    wprintf(L"*** OK TO DEPLOY \n");
    return 0;

}

//Function that figures out the game size on disk
UINT64 EstimateRequiredSpace(LPWSTR targetDir)
{
    WIN32_FIND_DATA  ffd;
    LARGE_INTEGER    filesize;
    TCHAR            szDir[DIR_BUFFER_LENGTH];
    size_t           targetDirLength    = 0;
    HANDLE           hFind              = INVALID_HANDLE_VALUE;
    DWORD            dwError            = 0;
    UINT64           requiredBytes      = 0;

    // Check that the input path plus 3 is not longer than the size of szDir.
    // Three characters are for the "\*" plus NULL appended below.
    targetDirLength = wcsnlen_s(targetDir, DIR_BUFFER_LENGTH);

    if (targetDirLength + 3 > DIR_BUFFER_LENGTH)
    {
        wprintf(L"\nDirectory path is too long.\n");
        return -1;
    }

    // Create the search string for FindFile functions.
    wcscpy_s(szDir, DIR_BUFFER_LENGTH, targetDir);
    wcscat_s(szDir, DIR_BUFFER_LENGTH, L"\\*");

    // Find the first file in the directory.
    hFind = FindFirstFile(szDir, &ffd);
    if (INVALID_HANDLE_VALUE == hFind)
    {
        dwError = GetLastError();
        wprintf(L"\nError: FindFirstFile failed %d.\n", dwError);
        return -1;
    }

    // Iterate over all the files in the game collecting file size information
    do
    {
        //If is a directory drill into it
        if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
        {
            if (wcscmp(ffd.cFileName, L".") != 0 && wcscmp(ffd.cFileName, L"..") != 0) //There is probably a better way to do this...
            {
                size_t newDirLength = wcsnlen_s(ffd.cFileName, DIR_BUFFER_LENGTH);
                if (targetDirLength + 1 + newDirLength + 1 > DIR_BUFFER_LENGTH)
                {
                    wprintf(L"\nDirectory path is too long.\n");
                    return -1;
                }

                wcscpy_s(szDir, DIR_BUFFER_LENGTH, targetDir);
                wcscat_s(szDir, DIR_BUFFER_LENGTH, L"\\");
                wcscat_s(szDir, DIR_BUFFER_LENGTH, ffd.cFileName);
                UINT64 result = EstimateRequiredSpace(szDir);
                if (result == -1)
                {
                    return -1;
                }
                requiredBytes += result;
            }
        }
        else
        {
            filesize.LowPart = ffd.nFileSizeLow;
            filesize.HighPart = ffd.nFileSizeHigh;

            //Round up file sizes to the nearest 4K boundary to get a better estimate of the actual size of disk
            requiredBytes += ESTIMATED_FILE_SIZE_ON_DISK(filesize.QuadPart);
        }
    }
    while (FindNextFile(hFind, &ffd) != 0);

    dwError = GetLastError();
    if (dwError != ERROR_NO_MORE_FILES)
    {
        wprintf(L"\nError: FindNextFile failed %d.\n", dwError);
        return -1;
    }

    FindClose(hFind);
    return requiredBytes;
}  
```

<a id="requirementsSection" />

## 要求

**头文件：** xtfapi.h

**库：** XtfApi.lib

**支持的平台：** Windows（适用于 XBOX 主机工具）

<a id="seealsoSection" />

## 另请参阅

[XtfConsoleControl](/reference/tools/xtf/xtfconsolecontrol/xtfconsolecontrol_members)\
[XBOX Tools Framework 原生 API 参考](/reference/tools/xtf/atoc-xtf-native)


## Related topics

- [XtfGetCountofAppUserModelIds](/zh-CN/reference/tools/xtf/xtfapi/functions/xtfgetcountofappusermodelids-xtfapi-xbox-windows-m.md)
- [XPersistentLocalStorageSpaceInfo](/zh-CN/reference/system/xpersistentlocalstorage/structs/xpersistentlocalstoragespaceinfo.md)
- [IXtfApplicationClient::GetDlc](/zh-CN/reference/tools/xtf/xtfapplication/classes/IXtfApplicationClient/methods/getdlc-ixtfapplicationclient-xtfapplication-xbox-microsoft-m.md)
- [IXtfApplicationClient::GetInstalled](/zh-CN/reference/tools/xtf/xtfapplication/classes/IXtfApplicationClient/methods/getinstalled-ixtfapplicationclient-xtfapplication-xbox-microsoft-m.md)
- [XtfGetAumid](/zh-CN/reference/tools/xtf/xtfapi/functions/xtfgetaumid-xtfapi-xbox-windows-m.md)
