尝试以扩展 VS Code 中的代理模式!

配置 VS Code 以使用 Microsoft C++

在本教程中,你将配置 Visual Studio Code 以在 Windows 上使用 Microsoft Visual C++ 编译器和调试器。

配置 VS Code 后,你将在 VS Code 中编译和调试一个简单的 Hello World 程序。本教程不涉及 Microsoft C++ 工具集或 C++ 语言的详细信息。对于这些主题,网上有许多好的资源。

如果你遇到任何问题,请随时在 VS Code 文档存储库中为此教程提交问题。

先决条件

要成功完成本教程,你必须执行以下操作:

  1. 安装 Visual Studio Code

  2. 安装 VS Code 的 C/C++ 扩展。你可以通过在“扩展”视图 (⇧⌘X (Windows、Linux Ctrl+Shift+X)) 中搜索“c++”来安装 C/C++ 扩展。

    C/C++ extension

  3. 安装 Microsoft Visual C++ (MSVC) 编译器工具集。

    如果你安装了最新版本的 Visual Studio,请从 Windows“开始”菜单打开 Visual Studio 安装程序,并验证是否已选中 C++ 工作负载。如果未安装,请选中该复选框,然后在安装程序中选择修改按钮。

    你也可以在不完全安装 Visual Studio IDE 的情况下安装使用 C++ 的桌面开发工作负载。在 Visual Studio 下载页面,向下滚动直到在所有下载部分下看到Visual Studio 工具,然后选择适用于 Visual Studio 2022 的生成工具的下载。

    Build Tools for Visual Studio download

    这将启动 Visual Studio 安装程序,它会显示一个对话框,其中包含可用的 Visual Studio 生成工具工作负载。选中使用 C++ 的桌面开发工作负载,然后选择安装

    Cpp build tools workload

注意:只要你拥有有效的 Visual Studio 许可证(无论是 Community、Pro 还是 Enterprise 版本),你就可以将 Visual Studio 生成工具中的 C++ 工具集与 Visual Studio Code 一起使用,以开发、生成和测试任何 C++ 代码。

检查 Microsoft Visual C++ 安装

要从命令行或 VS Code 使用 MSVC,你必须从 Visual Studio 的开发者命令提示符运行。普通的 shell(如 PowerShell、Bash 或 Windows 命令提示符)未设置必要的路径环境变量。

要打开 Visual Studio 的开发者命令提示符,请在 Windows“开始”菜单中开始键入“developer”,你应该会在建议列表中看到它。确切的名称取决于你安装的 Visual Studio 或 Visual Studio 生成工具的版本。选择该项以打开提示符。

Developer Command Prompt

你可以通过键入“cl”来测试 C++ 编译器 cl.exe 是否正确安装,你应该会看到一个包含版本和基本用法描述的版权信息。

Checking cl.exe installation

如果开发者命令提示符使用 BuildTools 位置作为起始目录(你不会希望将项目放在那里),请在开始创建新项目之前导航到你的用户文件夹 (C:\users\{你的用户名}\)。

注意:如果由于某种原因你无法从开发者命令提示符运行 VS Code,你可以在在开发者命令提示符外部运行 VS Code中找到使用 VS Code 生成 C++ 项目的解决方法。

创建 Hello World

在开发者命令提示符中,创建一个名为“projects”的空文件夹,你可以在其中存储所有 VS Code 项目,然后创建一个名为“helloworld”的子文件夹,进入该文件夹,并通过输入以下命令在该文件夹 (.) 中打开 VS Code (code):

mkdir projects
cd projects
mkdir helloworld
cd helloworld
code .

“code .”命令在当前工作文件夹中打开 VS Code,该文件夹成为你的“工作区”。完成本教程后,你将在工作区的 .vscode 文件夹中看到创建的三个文件:

  • tasks.json(生成说明)
  • launch.json(调试器设置)
  • c_cpp_properties.json(编译器路径和 IntelliSense 设置)

添加源文件

在“文件资源管理器”标题栏中,选择新建文件按钮并将文件命名为 helloworld.cpp

New File title bar button

添加 Hello World 源代码

现在粘贴以下源代码

#include <iostream>
#include <vector>
#include <string>

using namespace std;

int main()
{
    vector<string> msg {"Hello", "C++", "World", "from", "VS Code", "and the C++ extension!"};

    for (const string& word : msg)
    {
        cout << word << " ";
    }
    cout << endl;
}

现在按 ⌘S (Windows、Linux Ctrl+S) 保存文件。请注意,你刚刚添加的文件是如何在 VS Code 侧边栏的文件资源管理器视图 (⇧⌘E (Windows、Linux Ctrl+Shift+E)) 中显示的。

File Explorer

你还可以通过在主文件菜单中勾选自动保存来启用自动保存,以自动保存你的文件更改。

最左侧的活动栏允许你打开不同的视图,例如搜索源代码管理运行。你将在本教程的后面部分查看运行视图。你可以在 VS Code 用户界面文档中找到有关其他视图的更多信息。

注意:当你保存或打开 C++ 文件时,你可能会看到来自 C/C++ 扩展的关于 Insiders 版本可用性的通知,该版本允许你测试新功能和修复。你可以通过选择 X清除通知)来忽略此通知。

探索 IntelliSense

在你新的 helloworld.cpp 文件中,将鼠标悬停在 vectorstring 上以查看类型信息。在声明 msg 变量后,开始输入 msg.,就像调用成员函数一样。你应该立即看到一个显示所有成员函数的完成列表,以及一个显示 msg 对象类型信息的窗口。

Statement completion IntelliSense

你可以按 Tab 键插入选定的成员;然后,当你添加左括号时,你将看到有关函数所需的任何参数的信息。

运行 helloworld.cpp

请记住,C++ 扩展使用你机器上安装的 C++ 编译器来生成程序。在尝试在 VS Code 中运行和调试 helloworld.cpp 之前,请确保已安装 C++ 编译器。

  1. 打开 helloworld.cpp,使其成为活动文件。

  2. 单击编辑器右上角的播放按钮。

    Screenshot of helloworld.cpp and play button

  3. 从系统上检测到的编译器列表中选择 C/C++: cl.exe 生成并调试活动文件

    C++ debug configuration dropdown

你只会在第一次运行 helloworld.cpp 时被要求选择一个编译器。此编译器将被设置为 tasks.json 文件中的“默认”编译器。

  1. 生成成功后,你的程序输出将显示在集成终端中。

    screenshot of program output

如果你在使用 cl.exe 进行生成和调试时遇到错误,请确保你已使用 code . 快捷方式从 Visual Studio 的开发者命令提示符启动 VS Code

Error notification when trying to use MSVC without running VS Code from the Developer Command Prompt for VS

第一次运行程序时,C++ 扩展会创建 tasks.json,你会在项目中的 .vscode 文件夹中找到它。tasks.json 存储生成配置。

你的新 tasks.json 文件应类似于下面的 JSON

{
  "version": "2.0.0",
  "tasks": [
    {
      "type": "shell",
      "label": "C/C++: cl.exe build active file",
      "command": "cl.exe",
      "args": [
        "/Zi",
        "/EHsc",
        "/Fe:",
        "${fileDirname}\\${fileBasenameNoExtension}.exe",
        "${file}"
      ],
      "problemMatcher": ["$msCompile"],
      "group": {
        "kind": "build",
        "isDefault": true
      },
      "detail": "Task generated by Debugger."
    }
  ]
}

注意:你可以在变量参考中了解有关 tasks.json 变量的更多信息。

command 设置指定要运行的程序;在本例中是“cl.exe”。args 数组指定将传递给 cl.exe 的命令行参数。这些参数必须按照编译器期望的顺序指定。

此任务告诉 C++ 编译器获取活动文件 (${file}),编译它,并在当前目录 (${fileDirname}) 中创建一个可执行文件 (/Fe: 开关),该可执行文件与活动文件同名,但扩展名为 .exe (${fileBasenameNoExtension}.exe),在我们的示例中生成 helloworld.exe

label 值是你在任务列表中将看到的内容;你可以随意命名。

detail 值是你在任务列表中看到的任务描述。强烈建议重命名此值,以区别于类似的任务。

problemMatcher 值选择用于在编译器输出中查找错误和警告的输出解析器。对于 cl.exe,如果你使用 $msCompile 问题匹配器,你将获得最佳结果。

从现在开始,播放按钮将从 tasks.json 读取,以确定如何生成和运行程序。你可以在 tasks.json 中定义多个生成任务,并且任何被标记为默认的任务都将被播放按钮使用。如果需要更改默认编译器,可以运行任务: 配置默认生成任务。或者,你可以修改 tasks.json 文件并通过替换此段来删除默认值

    "group": {
        "kind": "build",
        "isDefault": true
    },

替换为

    "group": "build",

修改 tasks.json

你可以通过使用 "${workspaceFolder}/*.cpp" 等参数而不是 "${file}" 来修改 tasks.json 以生成多个 C++ 文件。这将生成当前文件夹中的所有 .cpp 文件。你还可以通过将 "${fileDirname}\\${fileBasenameNoExtension}.exe" 替换为硬编码文件名(例如 "${workspaceFolder}\\myProgram.exe")来修改输出文件名。

调试 helloworld.cpp

要调试你的代码,

  1. 回到 helloworld.cpp,使其成为活动文件。
  2. 通过单击编辑器边距或在当前行使用 F9 设置断点。helloworld.cpp 中断点的屏幕截图
  3. 从播放按钮旁边的下拉菜单中,选择调试 C/C++ 文件播放按钮下拉菜单的屏幕截图
  4. 从系统上检测到的编译器列表中选择 C/C++: cl.exe 生成并调试活动文件(你只会在第一次运行或调试 helloworld.cpp 时被要求选择一个编译器)。C++ 调试配置下拉菜单

播放按钮有两种模式:运行 C/C++ 文件调试 C/C++ 文件。它将默认为上次使用的模式。如果你在播放按钮中看到调试图标,你可以选择播放按钮进行调试,而不是选择下拉菜单项。

如果你在使用 cl.exe 进行生成和调试时遇到错误,请确保你已使用 code . 快捷方式从 Visual Studio 的开发者命令提示符启动 VS Code

Error notification when trying to use MSVC without running VS Code from the Developer Command Prompt for VS

探索调试器

在开始单步调试代码之前,我们花点时间注意用户界面中的几处变化

  • 集成终端出现在源代码编辑器的底部。在调试输出选项卡中,你将看到指示调试器已启动并正在运行的输出。

  • 编辑器会高亮显示你在启动调试器之前设置断点的行

    Initial breakpoint

  • 左侧的运行和调试视图显示调试信息。你将在本教程的后面看到一个示例。

  • 代码编辑器顶部会出现一个调试控制面板。你可以通过抓取左侧的点来在屏幕上移动它。

    Debugging controls

单步调试代码

现在你已准备好开始单步调试代码。

  1. 单击或按下调试控制面板中的跳过图标。

    Step over button

    这将把程序执行推进到 for 循环的第一行,并跳过在创建和初始化 msg 变量时调用的 vectorstring 类中的所有内部函数调用。请注意左侧变量窗口中的变化。

    Debugging windows

    在这种情况下,错误是预期内的,因为尽管循环的变量名现在对调试器可见,但语句尚未执行,因此此时没有什么可读取的。然而,msg 的内容是可见的,因为该语句已完成。

  2. 再次按跳过以推进到此程序中的下一个语句(跳过用于初始化循环的所有内部代码)。现在,变量窗口显示有关循环变量的信息。

  3. 再次按跳过以执行 cout 语句。(请注意,C++ 扩展在循环退出之前不会向调试控制台打印任何输出。)

  4. 如果你愿意,可以继续按跳过,直到向量中的所有单词都打印到控制台。但如果你好奇,可以尝试按步入按钮,在 C++ 标准库中单步执行源代码!

    Breakpoint in gcc standard library header

    要返回你自己的代码,一种方法是继续按跳过。另一种方法是在代码编辑器中切换到 helloworld.cpp 选项卡,将插入点放在循环内 cout 语句的某个位置,然后按 F9 来设置断点。左侧的行号区域会出现一个红点,表示在此行已设置断点。

    Breakpoint in main

    然后按 F5 以从标准库头文件中的当前行开始执行。执行将在 cout 处中断。如果你愿意,可以再次按 F9 以关闭断点。

设置监视

有时你可能希望在程序执行时跟踪变量的值。你可以通过对变量设置监视来做到这一点。

  1. 将插入点放在循环内。在监视窗口中,选择加号并在文本框中键入 word,这是循环变量的名称。现在,在你单步执行循环时查看监视窗口。

    Watch window

  2. 通过在循环前添加此语句来添加另一个监视:int i = 0;。然后,在循环内部添加此语句:++i;。现在,像上一步一样为 i 添加监视。

  3. 要在执行暂停在断点处时快速查看任何变量的值,你可以将鼠标指针悬停在其上方。

    Mouse hover

使用 launch.json 自定义调试

当你使用播放按钮或 F5 进行调试时,C++ 扩展会即时创建动态调试配置。

在某些情况下,你可能希望自定义调试配置,例如指定在运行时传递给程序的参数。你可以在 launch.json 文件中定义自定义调试配置。

要创建 launch.json,请从播放按钮下拉菜单中选择添加调试配置

Add debug configuration play button menu

然后你将看到一个包含各种预定义调试配置的下拉菜单。选择 C/C++: cl.exe 生成并调试活动文件

C++ debug configuration dropdown

VS Code 创建一个 launch.json 文件,它看起来像这样

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "C/C++: cl.exe build and debug active file",
      "type": "cppvsdbg",
      "request": "launch",
      "program": "${fileDirname}\\${fileBasenameNoExtension}.exe",
      "args": [],
      "stopAtEntry": false,
      "cwd": "${workspaceFolder}",
      "environment": [],
      "externalConsole": false,
      "preLaunchTask": "C/C++: cl.exe build active file"
    }
  ]
}

在上面的 JSON 中,program 指定了你想要调试的程序。在这里,它被设置为活动文件所在的文件夹 (${fileDirname}) 和带有 .exe 扩展名的活动文件名 (${fileBasenameNoExtension}.exe),如果 helloworld.cpp 是活动文件,则将是 helloworld.exeargs 属性是一个在运行时传递给程序的参数数组。

默认情况下,C++ 扩展不会向你的源代码添加任何断点,并且 stopAtEntry 值设置为 false

stopAtEntry 值更改为 true,以便在开始调试时让调试器在 main 方法处停止。

从现在开始,播放按钮和 F5 在启动程序进行调试时将读取你的 launch.json 文件。

C/C++ 配置

如果你想对 C/C++ 扩展进行更多控制,可以创建一个 c_cpp_properties.json 文件,它将允许你更改编译器路径、包含路径、C++ 标准(默认为 C++17)等设置。

你可以通过从命令面板 (⇧⌘P (Windows、Linux Ctrl+Shift+P)) 运行命令 C/C++: 编辑配置 (UI) 来查看 C/C++ 配置 UI。

Command Palette

这将打开C/C++ 配置页面。当你在此处进行更改时,VS Code 会将它们写入 .vscode 文件夹中名为 c_cpp_properties.json 的文件。

Command Palette

Visual Studio Code 将这些设置放在 .vscode\c_cpp_properties.json 中。如果你直接打开该文件,它应该看起来像这样

{
  "configurations": [
    {
      "name": "Win32",
      "includePath": ["${workspaceFolder}/**"],
      "defines": ["_DEBUG", "UNICODE", "_UNICODE"],
      "windowsSdkVersion": "10.0.18362.0",
      "compilerPath": "C:/Program Files (x86)/Microsoft Visual Studio/2019/BuildTools/VC/Tools/MSVC/14.24.28314/bin/Hostx64/x64/cl.exe",
      "cStandard": "c11",
      "cppStandard": "c++17",
      "intelliSenseMode": "msvc-x64"
    }
  ],
  "version": 4
}

只有当你的程序包含不在你的工作区或标准库路径中的头文件时,你才需要添加到包含路径数组设置中。

编译器路径

compilerPath 设置是配置中的一个重要设置。扩展使用它来推断 C++ 标准库头文件的路径。当扩展知道在哪里找到这些文件时,它可以提供有用的功能,如智能完成和转到定义导航。

C/C++ 扩展会尝试根据它在你的系统上找到的内容,用默认的编译器位置填充 compilerPath。该扩展会在几个常见的编译器位置查找。

compilerPath 搜索顺序为

  • 首先检查 Microsoft Visual C++ 编译器
  • 然后查找适用于 Linux 的 Windows 子系统 (WSL) 上的 g++
  • 然后是 Mingw-w64 的 g++。

如果你安装了 g++ 或 WSL,你可能需要更改 compilerPath 以匹配你的项目首选编译器。对于 Microsoft C++,路径应类似于这样,具体取决于你安装的特定版本:“C:/Program Files (x86)/Microsoft Visual Studio/2017/BuildTools/VC/Tools/MSVC/14.16.27023/bin/Hostx64/x64/cl.exe”。

复用 C++ 配置

VS Code 现在已配置为使用 Microsoft C++ 编译器。该配置适用于当前工作区。要复用此配置,只需将 JSON 文件复制到新项目文件夹(工作区)中的 .vscode 文件夹,并根据需要更改源文件和可执行文件的名称。

在开发者命令提示符外部运行 VS Code

在某些情况下,无法从Visual Studio 的开发者命令提示符运行 VS Code(例如,在通过 SSH 进行远程开发的场景中)。在这种情况下,你可以使用以下 tasks.json 配置在生成期间自动化Visual Studio 的开发者命令提示符的初始化:

{
  "version": "2.0.0",
  "windows": {
    "options": {
      "shell": {
        "executable": "cmd.exe",
        "args": [
          "/C",
          // The path to VsDevCmd.bat depends on the version of Visual Studio you have installed.
          "\"C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/Common7/Tools/VsDevCmd.bat\"",
          "&&"
        ]
      }
    }
  },
  "tasks": [
    {
      "type": "shell",
      "label": "cl.exe build active file",
      "command": "cl.exe",
      "args": [
        "/Zi",
        "/EHsc",
        "/Fe:",
        "${fileDirname}\\${fileBasenameNoExtension}.exe",
        "${file}"
      ],
      "problemMatcher": ["$msCompile"],
      "group": {
        "kind": "build",
        "isDefault": true
      }
    }
  ]
}

注意VsDevCmd.bat 的路径可能因 Visual Studio 版本或安装路径而异。你可以通过打开命令提示符并运行 dir "\VsDevCmd*" /s 来查找 VsDevCmd.bat 的路径。

故障排除

术语“cl.exe”无法识别

如果你看到错误“术语‘cl.exe’未被识别为 cmdlet、函数、脚本文件或可操作程序的名称。”,这通常意味着你正在Visual Studio 的开发者命令提示符之外运行 VS Code,并且 VS Code 不知道 cl.exe 编译器的路径。

VS Code 必须从 Visual Studio 的开发者命令提示符启动,或者任务必须配置为在开发者命令提示符外部运行

你始终可以通过打开新终端 (⌃⇧` (Windows、Linux Ctrl+Shift+`)) 并键入“cl”来验证 cl.exe 是否可供 VS Code 使用,从而检查你是否正在开发者命令提示符的上下文中运行 VS Code。

致命错误 C1034: assert.h: 未设置包含路径

在这种情况下,cl.exe 可通过 PATH 环境变量供 VS Code 使用,但 VS Code 仍需要从Visual Studio 的开发者命令提示符启动,或者配置为在开发者命令提示符外部运行。否则,cl.exe 将无法访问重要的环境变量,例如 INCLUDE

后续步骤

  • 探索 VS Code 用户指南
  • 查看 C++ 扩展概述
  • 创建一个新工作区,将你的 .vscode JSON 文件复制到其中,调整新工作区路径、程序名称等所需的设置,然后开始编码!