将生成工具安装到容器

可以将 Visual Studio 生成工具安装到 Windows 容器,用于支持持续集成和持续交付 (CI/CD) 工作流。 本文将指导你完成所需的 Docker 配置更改以及可以在容器中安装的工作负荷和组件

对于包装不仅可以在 CI/CD 服务器环境中使用,而且可以用于开发环境的一致的生成系统,容器是一种好方法。 例如,可以将源代码装载到要由自定义环境生成的容器中,同时继续使用 Visual Studio 或其他工具编写代码。 如果 CI/CD 工作流使用相同容器映像,则可以确信代码会以一致的方式生成。 还可以使用容器来实现运行时一致性,这对于将多个容器与业务流程系统一起使用的微服务十分常见,但不在本文的讨论范围内。

如果 Visual Studio 生成工具没有生成源代码所需的内容,则可以将这些相同步骤用于其他 Visual Studio 产品。 但请务必注意,Windows 容器不支持交互式用户界面,因此所有命令必须自动执行。

开始之前

下面假定你对 Docker 比较熟悉。 如果你尚不熟悉在 Windows 上运行 Docker,请了解如何在 Windows 上安装和配置 Docker 引擎

下面的基础映像是一个示例,可能不适用于你的系统。 请阅读 Windows 容器版本兼容性,以确定应将哪个基础映像用于你的环境。

创建和生成 Dockerfile

将下面的示例 Dockerfile 保存为磁盘上的新文件。 如果该文件仅仅命名为“Dockerfile”,则默认情况下会识别它。

警告

此示例 Dockerfile 只排除无法安装到容器的旧版 Windows SDK。 较旧版本会导致生成命令失败。

  1. 打开命令提示。

  2. 创建新目录(推荐):

    mkdir C:\BuildTools
    
  3. 将目录更改为此新目录:

    cd C:\BuildTools
    
  4. 将以下内容保存到 C:\BuildTools\Dockerfile。

    # escape=`
    
    # Use the latest Windows Server Core 2019 image.
    FROM mcr.microsoft.com/windows/servercore:ltsc2019
    
    # Restore the default Windows shell for correct batch processing.
    SHELL ["cmd", "/S", "/C"]
    
    RUN `
        # Download the Build Tools bootstrapper.
        curl -SL --output vs_buildtools.exe https://aka.ms/vs/16/release/vs_buildtools.exe `
        `
        # Install Build Tools with the Microsoft.VisualStudio.Workload.AzureBuildTools workload, excluding workloads and components with known issues.
        && (start /w vs_buildtools.exe --quiet --wait --norestart --nocache `
            --installPath "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\BuildTools" `
            --add Microsoft.VisualStudio.Workload.AzureBuildTools `
            --remove Microsoft.VisualStudio.Component.Windows10SDK.10240 `
            --remove Microsoft.VisualStudio.Component.Windows10SDK.10586 `
            --remove Microsoft.VisualStudio.Component.Windows10SDK.14393 `
            --remove Microsoft.VisualStudio.Component.Windows81SDK `
            || IF "%ERRORLEVEL%"=="3010" EXIT 0) `
        `
        # Cleanup
        && del /q vs_buildtools.exe
    
    # Define the entry point for the docker container.
    # This entry point starts the developer command prompt and launches the PowerShell shell.
    ENTRYPOINT ["C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\Common7\\Tools\\VsDevCmd.bat", "&&", "powershell.exe", "-NoLogo", "-ExecutionPolicy", "Bypass"]
    

    提示

    若要面向 64 位,请在 ENTRYPOINT 命令中指定 -arch=amd64 选项,以启动 Visual Studio 的开发人员命令提示 (VSDevCmd.bat)。

    例如:ENTRYPOINT ["C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\Common7\\Tools\\VsDevCmd.bat", "-arch=amd64", "&&", "powershell.exe", "-NoLogo", "-ExecutionPolicy", "Bypass"]

    警告

    如果映像直接基于 microsoft/windowsservercore,可能无法正确安装 .NET Framework,且不会指示任何安装错误。 安装完成后,可能无法运行托管代码。 相反,你的映像应基于 microsoft/dotnet-framework:4.8] 或更高版本。 另请注意,标记为 4.8 或更高版本的映像可能使用 PowerShell 作为默认 SHELL,这将导致 RUNENTRYPOINT 指令失败。

    请参阅 Windows 容器版本兼容性,以了解哪些主机操作系统版本支持哪些容器操作系统版本,并请参阅Windows 和生成工具容器故障排除以解决已知问题。

    # escape=`
    
    # Use the latest Windows Server Core 2022 image.
    FROM mcr.microsoft.com/windows/servercore:ltsc2022
    
    # Restore the default Windows shell for correct batch processing.
    SHELL ["cmd", "/S", "/C"]
    
    RUN `
        # Download the Build Tools bootstrapper.
        curl -SL --output vs_buildtools.exe https://aka.ms/vs/17/release/vs_buildtools.exe `
        `
        # Install Build Tools with the Microsoft.VisualStudio.Workload.AzureBuildTools workload, excluding workloads and components with known issues.
        && (start /w vs_buildtools.exe --quiet --wait --norestart --nocache `
            --installPath "%ProgramFiles(x86)%\Microsoft Visual Studio\2022\BuildTools" `
            --add Microsoft.VisualStudio.Workload.AzureBuildTools `
            --remove Microsoft.VisualStudio.Component.Windows10SDK.10240 `
            --remove Microsoft.VisualStudio.Component.Windows10SDK.10586 `
            --remove Microsoft.VisualStudio.Component.Windows10SDK.14393 `
            --remove Microsoft.VisualStudio.Component.Windows81SDK `
            || IF "%ERRORLEVEL%"=="3010" EXIT 0) `
        `
        # Cleanup
        && del /q vs_buildtools.exe
    
    # Define the entry point for the docker container.
    # This entry point starts the developer command prompt and launches the PowerShell shell.
    ENTRYPOINT ["C:\\Program Files (x86)\\Microsoft Visual Studio\\2022\\BuildTools\\Common7\\Tools\\VsDevCmd.bat", "&&", "powershell.exe", "-NoLogo", "-ExecutionPolicy", "Bypass"]
    

    提示

    若要面向 64 位,请在 ENTRYPOINT 命令中指定 -arch=amd64 选项,以启动 Visual Studio 的开发人员命令提示 (VSDevCmd.bat)。

    例如:ENTRYPOINT ["C:\\Program Files (x86)\\Microsoft Visual Studio\\2022\\BuildTools\\Common7\\Tools\\VsDevCmd.bat", "-arch=amd64", "&&", "powershell.exe", "-NoLogo", "-ExecutionPolicy", "Bypass"]

    警告

    如果映像直接基于 microsoft/windowsservercore,可能无法正确安装 .NET Framework,且不会指示任何安装错误。 安装完成后,可能无法运行托管代码。 相反,可使映像以 microsoft/dotnet-framework:4.8 或更高版本为基础。 另请注意,标记为 4.8 或更高版本的映像可能使用 PowerShell 作为默认 SHELL,这将导致 RUNENTRYPOINT 指令失败。

    请参阅 Windows 容器版本兼容性,以了解哪些主机操作系统版本支持哪些容器操作系统版本,并请参阅Windows 和生成工具容器故障排除以解决已知问题。

    注意

    错误代码 3010 用于在需要重新启动时指示成功,请参阅 MsiExec.exe 错误消息了解详细信息。

  5. 从该目录处运行以下命令。

    docker build -t buildtools2019:latest -m 2GB .
    

    此命令使用 2 GB 内存在当前目录中生成 Dockerfile。 安装某些工作负载后,默认的 1 GB 内存会出现不足;但根据生成环境,你可能只需 1 GB 内存即可进行构建。

    最终映像会带有标记 buildtools2019:latest,因此可以在作为 buildtools2019 的容器中轻松运行它,因为如果未指定任何标记,默认情况下会使用“latest”标记。 如果要在更高级的方案中使用特定版本的 Visual Studio 生成工具 2019,则可以改用特定 Visual Studio 生成号以及“latest”来标记容器,因此容器可以按一致方式使用特定版本。

    docker build -t buildtools:latest -m 2GB .
    

    此命令使用 2 GB 内存在当前目录中生成 Dockerfile。 安装某些工作负载后,默认的 1 GB 会不够用;你有可能只使用 1 GB 内存进行生成,具体取决于生成环境。

    最终映像带有标记“buildtools:latest”,因此可以在作为“buildtools”的容器中轻松运行它,因为如果未指定任何标记,默认情况下会使用“latest”标记。 如果要在更高级的方案中使用特定版本的 Visual Studio 生成工具,则可以改用特定 Visual Studio 生成号以及“latest”来标记容器,因此容器可以按一致方式使用特定版本。

使用生成的映像

现在已创建了映像,可以在容器中运行它以进行交互式自动生成。 该示例使用开发人员命令提示,因此已配置了 PATH 和其他环境变量。

  1. 打开命令提示。

  2. 运行容器以启动 PowerShell 环境(设置了所有开发人员环境变量):

    docker run -it buildtools2019
    
    docker run -it buildtools
    

若要将此映像用于 CI/CD 工作流,可以将它发布到自己的 Azure 容器注册表或其他内部 Docker 注册表,这样服务器只需拉取它即可。

注意

如果 Docker 容器无法启动,则可能出现了 Visual Studio 安装问题。 可以更新 Dockerfile 以删除调用 Visual Studio 批处理命令的步骤。 这样,可以启动 Docker 容器并读取安装错误日志。

在 Dockerfile 文件中,删除 ENTRYPOINT 命令中的 C:\\BuildTools\\Common7\\Tools\\VsDevCmd.bat&& 参数。 现在,该命令应为 ENTRYPOINT ["powershell.exe", "-NoLogo", "-ExecutionPolicy", "Bypass"]。 接下来,重新生成 Dockerfile 并执行 run 命令以访问容器文件。 要找到安装错误日志,请转到 $env:TEMP 目录并找到 dd_setup_<timestamp>_errors.log 文件。

确定安装问题并进行修复后,可以将 C:\\BuildTools\\Common7\\Tools\\VsDevCmd.bat&& 参数添加回 ENTRYPOINT 命令并重新生成 Dockerfile。

有关详细信息,请参阅Windows 和生成工具容器故障排除

Windows 和生成工具容器故障排除

向 Docker 容器中安装 Visual Studio 时存在几个问题。

排除 Windows 容器故障

将 Visual Studio 生成工具安装到 Windows 容器时会出现以下已知问题。

  • 生成映像时传递 -m 2GB(或更多)。 某些工作负载安装时要求内存大于默认的 1 GB。

  • 将 Docker 配置为使用大于默认 20 GB 的磁盘。

  • 在命令行上传递 --norestart。 本文撰写之时,尝试从 Windows 容器内重新启动容器会向主机返回 ERROR_TOO_MANY_OPEN_FILES

  • 如果映像直接基于 mcr.microsoft.com/windows/servercore,可能无法正确安装 .NET Framework,且不会指示任何安装错误。 安装完成后,可能无法运行托管代码。 相反,可使映像以 microsoft/dotnet-framework:4.7.1 或更高版本为基础。 例如,使用 MSBuild 生成时可能会看到与以下类似的错误:

    C:\BuildTools\MSBuild\15.0\bin\Roslyn\Microsoft.CSharp.Core.targets(84,5):错误 MSB6003:无法运行指定的任务可执行文件“csc.exe”。 无法加载文件或程序集“System.IO.FileSystem, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a”或某个依赖项。 系统找不到指定的文件。

排除生成工具容器故障

使用生成工具容器时可能会出现以下已知问题。 若要查看问题是否已修复,或者是否有其他已知问题,请访问开发者社区

  • 某些情况下,IntelliTrace 在容器内可能无法正常工作。
  • 在用于 Windows 的 Docker 的较旧版本上,默认容器映像大小仅为 20 GB,因此不适用于生成工具。 按照说明将映像大小更改为 127 GB 或更多。 若要确认磁盘空间问题,请查看日志文件以了解详细信息。 如果磁盘空间不足,则 vslogs\dd_setup_<timestamp>_errors.log 文件将包括以下内容:
Pre-check verification: Visual Studio needs at least 91.99 GB of disk space. Try to free up space on C:\ or change your target drive.
Pre-check verification failed with error(s) :  SizePreCheckEvaluator.