创建“打开文件夹”开发的生成和调试任务

Visual Studio 可以自动运行许多不同的编程语言和代码库。 使用打开文件夹选项,无需特殊说明且不创建项目,即可立即为已识别的代码库运行代码。 开发人员通常使用这种方法进行快速测试。

某些代码库需要 Visual Studio 无法识别或无法使用打开文件夹选项立即处理的自定义生成工具。 对于这些方案,可以定义生成任务,以指示 Visual Studio 如何生成和调试代码。 生成任务指定语言生成和运行代码所需的所有项,并可用于完成几乎任何必需的操作。

本文介绍如何定义生成任务,以在 Visual Studio 中为无法识别的无项目代码库配置生成和调试设置。

浏览 JSON 配置文件

为了自定义无项目代码库,Visual Studio 为配置设置提供了两个 JSON (.json) 文件:任务启动。 当在 Visual Studio 解决方案资源管理器中选择特定选项时,Visual Studio 会根据需要创建(或打开)这些文件。

下表介绍了 JSON 文件以及如何在解决方案资源管理器中创建它们。

JSON 文件 配置目的 文件访问
tasks.vs.json 定义自定义生成命令、自定义编译器开关,以及任意(与非生成相关)任务。 解决方案资源管理器中,右键单击文件或文件夹以打开上下文菜单,然后选择配置任务
launch.vs.json 指定用于调试的命令行参数。 解决方案资源管理器中,右键单击文件或文件夹以打开上下文菜单,然后选择添加调试配置

将 JSON 文件添加到源代码管理中

默认情况下,任务启动 JSON 文件在解决方案资源管理器中不可见。 这些文件位于代码库根 (\) 文件夹中一个名为 .vs 的隐藏文件夹中。 这些文件是隐藏的,因为它们通常不会添加到源代码管理中。 可以通过在解决方案资源管理器中选择显示所有文件选项来查看 Visual Studio 中的隐藏文件。

如果要将 JSON 文件添加到源代码管理中,请将文件拖动到文件系统中代码库的根 (\) 文件夹。 这些文件在解决方案资源管理器中可见,并可用于源代码管理。

使用 tasks.vs.json 定义任务

可以通过直接在 Visual Studio 中将操作作为任务运行,来自动化当前工作区中文件的生成脚本和外部操作。 若要配置新任务,请在解决方案资源管理器中右键单击文件或文件夹,然后选择配置任务

显示如何配置任务以自动执行对解决方案资源管理器中的文件的生成脚本和外部操作的屏幕截图。

此操作将创建(或打开).vs 文件夹中的 tasks.vs.json 文件。 可以在此文件中定义一个生成任务或任意任务,Visual Studio 会将任务的名称作为命令添加到解决方案资源管理器右键单击菜单。 可以通过在解决方案资源管理器中选择相应的命令来调用任务。

可以将自定义任务添加到单个文件,也可以将其添加到某个特定类型的所有文件。 例如,可以将 NuGet 包文件配置为具有“还原包”任务,也可以将所有源文件配置为具有静态分析任务,例如所有 JavaScript (.js) 文件的 linter。

为无法识别的工具创建任务

如果代码库使用 Visual Studio 无法识别的自定义生成工具,则在完成一些额外的配置步骤前,将无法在 Visual Studio 中运行和调试代码。

可以定义生成任务,以指示 Visual Studio 如何生成、重新生成和清理代码。 tasks.vs.json 文件将 Visual Studio 内部开发循环与你为代码库定义的自定义生成工具相结合。

假设代码库有一个名为 hello.cs 的 C# 文件。 此类代码库的 makefile 可能如此示例所示:

build: directory hello.exe

hello.exe: hello.cs
    csc -debug hello.cs /out:bin\hello.exe

clean:
    del bin\hello.exe bin\hello.pdb

rebuild: clean build

directory: bin

bin:
    md bin

对于包含生成、清理和重新生成目标的类似 makefile,可以使用 makefile配置任务选项,并定义以下 tasks.vs.json 文件。 JSON 文件定义使用 NMAKE 作为生成工具生成、重新生成和清理代码库的任务:

{
  "version": "0.2.1",
  "outDir": "\"${workspaceRoot}\\bin\"",
  "tasks": [
    {
      "taskName": "makefile-build",
      "appliesTo": "makefile",
      "type": "launch",
      "contextType": "build",
      "command": "nmake",
      "args": [ "build" ],
      "envVars": {
        "VSCMD_START_DIR": "\"${workspaceRoot}\""
      }
    },
    {
      "taskName": "makefile-clean",
      "appliesTo": "makefile",
      "type": "launch",
      "contextType": "clean",
      "command": "nmake",
      "args": [ "clean" ],
      "envVars": {
        "VSCMD_START_DIR": "\"${workspaceRoot}\""
      }
    },
    {
      "taskName": "makefile-rebuild",
      "appliesTo": "makefile",
      "type": "launch",
      "contextType": "rebuild",
      "command": "nmake",
      "args": [ "rebuild" ],
      "envVars": {
        "VSCMD_START_DIR": "\"${workspaceRoot}\""
      }
    }
  ]
}

tasks.vs.json 文件中定义生成任务后,Visual Studio 会将相应的任务命令添加到解决方案资源管理器的右键单击菜单中。 在此示例中,代码库中 makefile 实例的右键单击菜单中添加了生成重新生成清理选项:

显示添加到解决方案资源管理器中右键单击菜单中的生成、重新生成和清理任务的屏幕截图。

Visual Studio 根据其 contextType 设置在配置任务命令后,在右键单击菜单上列出新命令。 “生成”、“重新生成”和“清理”是生成命令,并列在右键单击菜单的“生成”部分中。

当在右键菜单上选择自定义任务命令时,操作将执行。 Visual Studio 在输出窗口中显示命令输出,在错误列表中显示任何生成错误。

为任意操作创建任务

可以在 tasks.vs.json 文件中为任意操作定义自定义任务。 你可以定义一个任务,在输出窗口中显示当前选定文件的名称,或列出指定文件夹中的文件。

示例:当前选定文件的显示名称

以下示例显示定义单个任意任务的 tasks.vs.json 文件。 调用此任务时,该操作将显示当前选定的 JavaScript (.js) 文件的文件名。

{
  "version": "0.2.1",
  "tasks": [
    {
      "taskName": "Echo filename",
      "appliesTo": "*.js",
      "type": "default",
      "command": "${env.COMSPEC}",
      "args": [ "echo ${file}" ]
    }
  ]
}

此任务的代码定义了以下属性:

  • taskName:Visual Studio 要在右键单击菜单中显示的任务命令名称。 在本例中为 Echo 文件名
  • appliesTo:要对其执行的任务命令的文件。 在本例中为 JavaScript (.js) 文件。
  • command:要调用的命令。 此任务使用 COMSPEC 环境变量来标识命令行解释器(通常为 cmd.exe)。
  • args:Visual Studio 调用命令时要传递的任何参数。
  • ${file}:此任务的参数包括一个宏,该宏检索当前在解决方案资源管理器中选择的文件。

保存 tasks.vs.json 文件后,可以右键单击文件夹中的任何 JavaScript (.js) 文件,然后选择 Echo 文件名。 Visual Studio 在输出窗口中显示所选文件名。

示例:列出文件和子文件夹

以下示例显示了一个 tasks.vs.json 文件,该文件定义了一个任务,用于列出 bin 文件夹的文件和子文件夹:

{
  "version": "0.2.1",
  "outDir": "\"${workspaceRoot}\\bin\"",
  "tasks": [
    {
      "taskName": "List Outputs",
      "appliesTo": "*",
      "type": "default",
      "command": "${env.COMSPEC}",
      "args": [ "dir ${outDir}" ]
    }
  ]
}

此任务的代码定义了以下属性:

  • taskName:右键单击菜单列表输出的任务命令名称。
  • appliesTo:此任务作用于指定文件夹中的所有项目,如使用通配符 (*) 所示。
  • command:与前面的示例类似,该任务使用 COMSPEC 环境变量来标识命令行解释器 (cmd.exe)。
  • args:当 Visual Studio 调用任务时,它会向 dir 命令传递调用,其中列出了目录(文件夹)项。
  • ${outDir}{outDir} 宏在 tasks 块之前定义。 它将 bin 文件夹标识为要对其执行操作的目录。

此任务适用于代码库中的所有文件。 当 Visual Studio 将任意任务的命令名称添加到右键单击菜单中时,它会在命令前加上运行>,如运行列表输出中所示。

如果在解决方案资源管理器中打开任何文件的右键单击菜单,任务命令运行列表输出将作为菜单“生成”部分的最后一个命令出现。 选择运行列表输出时,Visual Studio 在输出窗口中列出代码库的 bin 文件夹的内容:

显示添加到 Visual Studio 解决方案资源管理器中右键单击菜单的任意任务的屏幕截图。

使用多个 task.vs.json 文件

可以在代码库的根 (\) 文件夹和子文件夹中有多个 tasks.vs.json 文件。 此方法使你可以灵活地为代码库中的特定子文件夹或文件定义不同的行为。

Visual Studio 在代码库中聚集或覆盖设置,按照以下顺序排列文件:

  1. 根 (\) 文件夹中 .vs 文件夹中的设置文件。
  2. 计算设置的文件夹。
  3. 当前文件夹的父文件夹,最多包含根 (\) 文件夹。
  4. 根 (\) 文件夹中的设置文件。

这些聚合规则仅适用于 tasks.vs.json 文件的实例。

tasks.vs.json 的示例属性

以下各节介绍可以在 tasks.vs.json 文件中指定的一些属性。

设置 appliesTo 属性

通过使用 appliesTo 属性指定文件或文件夹名称,例如 "appliesTo": "hello.js" ,可以为任何文件或文件夹创建任务。

下表总结了可以与 appliesTo 属性一起使用以生成特定任务行为的文件掩码值:

值(文件掩码) 任务适用于
"*" 工作区中的所有文件和文件夹
"*/" 工作区中的所有文件夹
"*.js" 工作区中具有 JavaScript (.js) 扩展的所有文件
"/*.js" 工作区根 (\) 文件夹中具有 JavaScript (.js) 扩展的所有文件
"src/*/" src 文件夹的所有子文件夹
"makefile" 工作区中名为 makefile 的所有文件
"/makefile" 仅工作区根 (\) 文件夹中名为 makefile 的文件

在任务参数中使用宏

可以将宏作为任务的参数传递,以便在 Visual Studio 调用命令时增强任务行为。

下表列出了一些宏示例:

说明 示例
${env.<VARIABLE>} 指定开发人员命令提示符中可用的任何环境变量。 有关详细信息,请参阅开发人员命令提示和开发人员 PowerShell ${env.PATH}, ${env.COMSPEC}
${workspaceRoot} 提供工作区文件夹的完整路径。 C:\sources\hello, C:\sources\hello\bin
${file} 提供文件或文件夹的完整路径。 C:\sources\hello\src\hello.js*, C:\sources\hello\src\test.js*
${relativeFile} 提供文件或文件夹的相对路径。 src\hello.js*, bin\hello.exe
${fileBasename} 提供文件的名称,不包括路径或扩展名。 hello, test
${fileDirname} 提供文件的完整路径,不包括文件名。 C:\sources\hello\src*, C:\sources\hello\bin\test\*
${fileExtname} 提供所选文件的扩展名。 .js, .cs, .exe

使用 launch.vs.json 配置调试

Visual Studio 提供了一个 launch.vs.json 文件,你可以使用该文件为代码库配置调试。

注意

若要配置 CMake 项目以进行调试,请参阅配置 CMake 调试会话

  1. 解决方案资源管理器中,右键单击可执行文件 (.exe) ,然后选择添加调试配置

    显示如何在解决方案资源管理器右键单击菜单上选择“添加调试配置”选项的屏幕截图。

  2. 选择调试器对话框中,从列表中选择调试配置选项,然后选择选择

    显示如何在解决方案资源管理器中为启动配置选择调试器的屏幕截图。

    如果 launch.vs.json 文件尚不存在,Visual Studio 将创建该文件。 下面是为 hello.exe 可执行文件创建的文件的示例:

    {
      "version": "0.2.1",
      "defaults": {},
      "configurations": [
        {
          "type": "default",
          "project": "bin\\hello.exe",
          "projectTarget": "",
          "name": "hello.exe"
        }
      ]
    }
    
  3. 有了启动文件后,在解决方案资源管理器中右键单击代码库的可执行文件,然后选择设置为启动项

    可执行文件被指定为代码库的启动项,Visual Studio 为调试开始按钮设置标签,以反映可执行文件的名称。

    显示 Visual Studio 中启动操作的自定义标签的屏幕截图。

    使用 F5 启动调试器时,Visual Studio 将开始调试代码,并在任何设置断点处停止。 所有熟悉的调试程序窗口都是可用的,且具备功能性。

    有关 C++ 打开文件夹项目中自定义生成和调试任务的详细信息,请参阅 Visual Studio 中 C++ 生成系统的打开文件夹支持

指定调试参数

可以在 launch.vs.json 文件中指定要传递给调试器的命令行参数。 在 args 数组中添加参数,如以下示例所示:

{
  "version": "0.2.1",
  "defaults": {},
  "configurations": [
    {
      "type": "default",
      "project": "bin\\hello.exe",
      "name": "hello.exe"
    },
    {
      "type": "default",
      "project": "bin\\hello.exe",
      "name": "hello.exe a1",
      "args": [ "a1" ]
    }
  ]
}

启动调试配置

可以根据需要创建任意数量的调试配置。 保存启动文件时,配置名称将添加到调试目标下拉列表中。 可以选择一个特定的目标来启动调试器:

显示 Visual Studio 解决方案资源管理器中“调试目标”下拉列表中可用配置的屏幕截图。

如果未在菜单上看到额外的目标,请选择显示/隐藏调试目标,并配置可见目标。

了解配置的优先级

Visual Studio 扫描 launch.vs.json 文件中 configurations 数组属性中指定的项的两个位置:

  • 代码库的根 (\) 文件夹
  • .vs 文件夹

如果两个位置都有launch.vs.json文件,并且配置的定义存在冲突,则 .vs\launch.vs.json 文件中的值优先。

使用其他设置文件

除了任务启动 JSON 文件之外,Visual Studio 还会从代码库中定义的其他配置文件读取设置。 两个常用的文件包括 settings.json.gitignore

使用 .vscode\settings.json 定义代码设置

当名为 settings.json 的文件位于名为 .vscode 的文件夹中时,Visual Studio 会从该文件中读取有限的设置。

此功能用于先前已在 Visual Studio Code 中开发的代码库。 目前,从 .vscode\settings.json 文件中读取的唯一设置是 files.exclude。 此设置用于在解决方案资源管理器和某些搜索工具中直观地筛选文件。

代码库中可以有多个 .vscode\settings.json 文件。 从文件中读取的设置适用于 .vscode 的父文件夹及其所有子文件夹。

使用 .gitignore 配置 Git 文件

可以使用 .gitignore 文件让 Git 知道在应用源代码管理时要忽略哪些文件。 .gitignore 文件通常是代码库的一部分,以便设置可与代码库的所有开发人员共享。 Visual Studio 读取 .gitignore 文件中的模式,以目视筛选项目或者通过一些搜索工具进行筛选。

.gitignore 文件中读取的设置适用于其父文件夹和所有子文件夹。