在postDebugTask中终止另一个任务 - VS Code

12

我有一个类似下面的调试启动配置 (launch.json)。

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Current TS File",
            "type": "node",
            "request": "launch",
            "preLaunchTask": "Pre Debug Task",
            "postDebugTask": "Stop Watch Styles",
            "args": ["${relativeFile}"],
            "runtimeArgs": ["--nolazy", "-r", "ts-node/register"],
            "sourceMaps": true,
            "cwd": "${workspaceRoot}",
            "protocol": "inspector",
        }
    ]
}

我任务的配置(tasks.json)如下:

{
    "version": "2.0.0",
    "tasks": [
        {
            "type": "npm",
            "script": "next:copy",
            "label": "Copy Files",
            "problemMatcher": []
        },
        {
            "type": "npm",
            "script": "styles:tsw",
            "label": "Watch Styles",
            "problemMatcher": [],
        },
        {
            "label": "Pre Debug Task",
            "isBackground": true,
            "dependsOn" :[
                "Copy Files",
                "Watch Styles"
            ]
        },
        {
            "label": "Stop Watch Styles",
            // No sure what should come here
        }
    ]
}
尝试在 postDebugTask 中停止监视进程,是否有一种方法可以通过在tasks.json中提供名称( Watch Styles )作为参数来终止任务。观察样式是一个持续运行的进程,请建议如果有任何其他方法在调试完成后终止任务。
5个回答

24

这将在调试停止后终止所有任务

或者在这种情况下,只需 build_runner watch...

launch.json

{
  // Use IntelliSense to learn about possible attributes.
  // Hover to view descriptions of existing attributes.
  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Flutter",
      "request": "launch",
      "type": "dart",
      "flutterMode": "debug",
      "preLaunchTask": "flutter: build_runner watch",
      "postDebugTask": "Terminate All Tasks"
    }
  ]
}

任务配置文件 tasks.json

{
  // See https://go.microsoft.com/fwlink/?LinkId=733558
  // for the documentation about the tasks.json format
  "version": "2.0.0",
  "tasks": [
    {
      "label": "Terminate All Tasks",
      "command": "echo ${input:terminate}",
      "type": "shell",
      "problemMatcher": []
    }
  ],
  "inputs": [
    {
      "id": "terminate",
      "type": "command",
      "command": "workbench.action.tasks.terminate",
      "args": "terminateAll"
    }
  ]
}

更多信息请查看:https://code.visualstudio.com/docs/editor/variables-reference#_command-variables


1
这样可以工作,但是在终止任务后没有关闭相关联的终端。有什么想法吗?顺便说一下,我正在任务中运行php artisan serve命令。 - dotNET

4
这对我有用:
{
   "label": "postdebugKill",
   "type": "process",
   "command":[
      "${command:workbench.action.tasks.terminate}",
      "${command:workbench.action.acceptSelectedQuickOpenItem}",
   ],
},

第一个"${command:workbench.action.tasks.terminate}"将弹出面板,要求您选择要终止的任务。因此,如果您有多个正在运行的任务并且想要选择其中一个,只需使用此命令即可。
第二个"${command:workbench.action.acceptSelectedQuickOpenItem}"将在上述面板中终止所选任务。(因此,您甚至不会看到终止面板。)如果您在调用postdebugKill任务时只有一个正在运行的任务,它将自动被选择并因此终止。否则,列出的第一个任务将被终止。同样,如果您有多个其他正在运行的任务并且想要选择要终止的任务,请不要包含此第二个命令。
我不知道是否有任何方法可以通过args选项列出要终止的任务的标签名称(如果正在运行)。拥有这种功能将是很好的。
[postdebugKill名称可以随意更改。]
要调用后调试任务,您的launch.json配置可能如下所示:
{
   "type": "node",
   "request": "launch",
   "name": "Gulp: serve",
   "program": "${workspaceFolder}/node_modules/gulp/bin/gulp.js",
   "args": [
     "serve"
   ],

   //  "preLaunchTask": "someTask",

   "postDebugTask": "postdebugKill"
},

在停止"Gulp: serve"调试会话时,将触发任务"postdebugKill"。因此,如果我使用了"preLaunchTask"来启动任务或者在启动"Gulp: serve"调试会话之前简单地启动了一个任务运行 - 那么preLaunchTask将被终止。
最近在VSCode中添加了在任务中运行VSCode命令的功能。有一些最小的信息在这里:使用命令在任务文档中

感谢您的回复。您使用的VS Code版本是多少?我的版本是1.29.1,我尝试在后调试部分添加命令,但它没有提示要求终止任务。我在终端中看到了语句。我通过Shift+F5或使用调试“停止”图标来停止调试任务> 在my-app-folder文件夹中执行任务:C:\Users\sandeep\Codebase\my-app-folder\${command:workbench.action.tasks.terminate} ${command:workbench.action.acceptSelectedQuickOpenItem} - Sandeep Kumar
我正在使用1.30.2版本。我已经做了一些研究,并将其放入一个单独的答案中。 - Mark
当我尝试手动运行此任务时,VS Code只会打开一个终端并记录“终端shell路径“${command:workbench.action.tasks.terminate} ${command:workbench.action.acceptSelectedQuickOpenItem}”不存在”。我正在使用VS Code版本1.42.1。 - knee-cola
2
第二个命令${command:workbench.action.acceptSelectedQuickOpenItem}似乎没有效果。停止调试后,vscode会要求我确认选择哪个正在运行的脚本来执行第一个命令。 - maninak

2
如果在Linux或macOS上,一个较为简单的解决方案是使用pkill。如果在Windows上,请参见下文。
首先运行任务并使用$ ps -af查找vscode运行该任务的完整命令。
然后在postDebugTask中使用pkill和完整命令。
我在tasks.json中有这样一个条目:
{
    "label": "stop npm:watch",
    "type": "shell",
    "command": "pkill -f 'sh -c node ./scripts/watch.js'",
    "presentation": {
        "reveal": "silent",
        "panel": "dedicated",
        "close": true,
    }
}

"'sh -c node ./scripts/watch.js' 是 vscode 运行 npm:watch 任务的方式。

presentation 属性可以防止该任务在成功完成后获取焦点或占用终端空间。

然后你可以在 launch.json 配置文件中引用该任务:

"
{
    ...
    "preLaunchTask": "npm:watch",
    "postDebugTask": "stop npm:watch",
    ...
}

如果完整命令包含可变参数(路径、端口号等),您可以使用命令的一部分或正则表达式。
例如:我可能会匹配 './scripts/watch.js''node.*watch'
对于Windows系统:您可以将 pkill 替换为 taskkill 以使其工作。
如果您想要同时支持Unix和Windows系统,您可以编写一个脚本,根据底层操作系统执行其中之一。

2
我会再添加一个答案,因为新的补充信息非常详细。似乎在运行preLaunchTask然后启动调试会出现问题。请看debugging does not work on first try。不过,在Insiders版中已经修复了这个问题,并可能在2019年2月初发布。terminal not sending onLineData
与此同时,在其中一个问题中有一个建议的解决方法,我已经找不到链接了,那就是使用problemMatcher,它将向调试器发出依赖任务已完成的信号。
在我的监视任务中,我使用了以下内容:
"problemMatcher": [
   {
     "base": "$tsc-watch",
     "background": {
       "activeOnStart": true,
       "beginsPattern": "Using gulpfile ~\\OneDrive\\experimental\\gulpfile.js",
       "endsPattern": "Starting 'watch'..."
     }
   }
],

我选择这个是因为当我手动启动gulp:watch任务时,终端会显示以下内容:
[22:27:48] Using gulpfile ~\OneDrive\experimental\gulpfile.js
[22:27:48] Starting 'watch'...
[22:27:48] Starting 'watch'...

所以你看到了我复制的开始和结束模式(带有额外的转义)。

我建议你单独运行你的“Pre Debug Task”,并将开始和结束的输出复制到你的“Pre Debug Task” problemMatcher 中,看看它是否现在可以工作。

我相信第一个答案中的代码是正确的,只是我没有像你一样使用“isBackground”和“dependsOn”。但我已经在我的代码中添加了“isBackground”选项和“problemMatcher”选项,现在它可以完美地工作。

希望这个问题会在2019年2月的下一个版本中得到解决,届时就不需要这个解决方法了。


谢谢马克抽出时间来。我需要检查我的看表任务,试图识别可以放入problemMatcher中的模式。我希望这更简单一些 :). 可能我会等待你建议的单独答案。 - Sandeep Kumar
那是第二个答案。这个问题“可能”会在2019年2月6日发布下一个vscode更新时得到解决。 - Mark

0
这是我为我的Vite+React+Typescript项目所想到的解决方案;我希望在停止调试器时自动关闭开发服务器。
tasks.json -
{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "npm dev", // the name of the task to be executed when I press'F5'. The 'terminate' command terminates this task.
      "isBackground": true,
      "type": "npm",
      "script": "dev",
      "problemMatcher": {
        "owner": "typescript",
        "fileLocation": "relative",
        "pattern": {
          "regexp": "^([^\\s].*)\\((\\d+|\\,\\d+|\\d+,\\d+,\\d+,\\d+)\\):\\s+(error|warning|info)\\s+(TS\\d+)\\s*:\\s*(.*)$",
          "file": 1,
          "location": 2,
          "severity": 3,
          "code": 4,
          "message": 5
        },
        "background": {
          "activeOnStart": true,
          "beginsPattern": "^.*env-management-ui@0.0.0 dev.*",
          "endsPattern": "^.*VITE v4.4.7  ready in.*",
        },
      },
    },
    {
      "label": "terminate dev server",
      "command": "echo ${input:terminate}", // the 'terminate' command that's defined in the inputs list
      "type": "shell",
      "problemMatcher": []
    }
  ],
  "inputs": [
    {
      "id": "terminate",
      "type": "command",
      "command": "workbench.action.tasks.terminate",
      "args": "npm dev" // the name of the task to be terminated when the 'terminate' command is executed.
    }
  ]
}

launch.json -

{
    "configurations": [
        {
            "type": "msedge",
            "request": "launch",
            "name": "Launch Edge against localhost",
            "url": "http://localhost:5173",
            "webRoot": "${workspaceFolder}",
            "skipFiles": [
                "${workspaceFolder}/node_modules/**/*.js"
            ],
            "preLaunchTask": "npm dev",
            "postDebugTask": "terminate dev server",
        },
    ],
}

解释: 在 tasks.json 文件中,我定义了以下任务 "terminate dev server"。
{
      "label": "terminate dev server",
      "command": "echo ${input:terminate}",
      "type": "shell",
      "problemMatcher": []
}

任务接收名为terminate的输入,该输入在inputs列表中定义:

"inputs": [
    {
      "id": "terminate",
      "type": "command",
      "command": "workbench.action.tasks.terminate",
      "args": "npm dev"
    }
]

输入的terminate命令使用args参数获取要终止的任务的名称;在我的情况下,名称是npm dev,它是我tasks列表中第一个任务的label。要查看所有当前运行的任务,请在VS Code中按下CTRL+SHIT+P,然后搜索Tasks: Terminate Task。点击它将显示一个下拉菜单,其中包含所有当前运行的任务。

launch.json中,我将npm dev任务定义为我的preLaunchTask,并将terminate dev server任务定义为我的postDebugTask。因此,当我按下F5时,将执行preLaunchTask,运行开发服务器并打开带有调试器的浏览器。然后,当我停止调试器时,将执行postDebugTask,终止我的preLaunchTask


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接