How can I prevent VS Code from waiting for a preLaunchTask to finish?
Asked Answered
T

5

66

I have a debug setup in Visual Studio code where I run an external binary which can execute my JS files (using duktape). The debug adapter currently only supports attach requests (not launch) so I have to run the binary before I can debug the JS scripts.

In order to avoid having to start the application manually I created a task for it and set that in my launch.json file:

{
    "version": "0.2.0",
    "configurations": [{
        "name": "Attach MGA",
        "type": "duk",
        "preLaunchTask": "debug mga",
        "request": "attach",

        "address": "localhost",
        "port": 9091,

        "localRoot": "${workspaceRoot}",

        "stopOnEntry": false,
        "debugLog": true
    }]
}

The task is defined so:

{
    "version": "0.1.0",
    "command": "<absolute path to>/mga",
    "isShellCommand": false,
    "showOutput": "always",
    "suppressTaskName": true,
    "tasks": [{
        "taskName": "debug mga",
        "args": ["--debugger", "main.json"]
    }]
}

The problem is now that vscode waits for the pre launch task to finish, while the application waits for a debugger to attach. Catch 22.

How can I avoid that vscode waits for the pre launch task to finish?

Update:

Meanwhile I have read up on the vscode task page and came up with this task configuration. Still, it doesn't work for me

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "launch-mga",
            "type": "shell",
            "command": "<absolute path to>/mga",
            "args": [
                "config/main.json",
                "--debugger"
            ],
            "isBackground": true,
            "problemMatcher": {
                "owner": "custom",
                "pattern": {
                    "regexp": "_____"
                },
                "background": {
                    "activeOnStart": true,
                    "beginsPattern": "^.*Waiting for debug connection.*$",
                    "endsPattern": "^.*blah.*$"
                },
            },
        }
    ]
}

The launched application prints the wait message and then waits endlessly for a debug connection. Maybe the problem has to do with the application (which is kinda Node.js like terminal app), written in C++?

Telekinesis answered 29/5, 2017 at 12:3 Comment(0)
R
69

This worked for me.

Note all these are required, even though none are important:

  • problemMatcher.pattern.regexp
  • problemMatcher.pattern.file
  • problemMatcher.pattern.location
  • problemMatcher.pattern.message
  • problemMatcher.background.activeOnStart
  • problemMatcher.background.beginsPattern
  • problemMatcher.background.endsPattern
{
  // See https://go.microsoft.com/fwlink/?LinkId=733558
  // for the documentation about the tasks.json format
  "version": "2.0.0",
  "tasks": [
    {
      "label": "build-extras",
      "type": "shell",
      "isBackground": true,
      "command": "./script/build-extras",

      // This task is run before some debug tasks.
      // Problem is, it's a watch script, and since it never exits, VSCode
      // complains. All this is needed so VSCode just lets it run.
      "problemMatcher": [
        {
          "pattern": [
            {
              "regexp": ".",
              "file": 1,
              "location": 2,
              "message": 3
            }
          ],
          "background": {
            "activeOnStart": true,
            "beginsPattern": ".",
            "endsPattern": ".",
          }
        }
      ]
    }
  ]
}
Raspberry answered 3/1, 2019 at 6:26 Comment(10)
It's true! You have to specify the pattern stuff even though it doesn't matter. UrghArio
This works perfectly with Angular, although chrome start too early, the hot module reloading makes sure the page is automatically refreshed when the "ng serve" is readyJaponica
Has this changed recently? I feel like this was working, but only for like a day for me, and now it's not working .... I posted my own question on https://mcmap.net/q/297643/-stuck-waiting-for-prelaunch-task/1877527 but since you're my baseline here I figured I'd comment :-)Fixed
Today's VSCode update seems to have broken this again.Mic
It's broken again, it used to work perfectlyChampollion
I had added problemMatcher as suggested above. But had missed to enable isBackground. So setting both of these fields worked for me.Amazement
For me, VSCode triggers an error when the pre-launch task starts (there is an option to continue debugging). This seems to be caused by the regexp: "." pattern. If you use an empty string it works as others have described with no error message pop-up from VSCode.Theiss
The problemMatcher did the job for me on windowsEuphorbiaceous
I was trying to tunnel some ssh ports in the background, my command didnt output anything so the problemMatched didnt kick in, had to add an echo before my commandWandering
I had a problem with the problem matcher trying to find text that was no longer in the terminal, so this helped. Just wanted to note that if you want to test this by clearing the terminal where your task lives, it won't start the launch configuration until there's something in the terminal, so you can simply click it, enter a character and press Enter, which will make the launch configuration start.Turnip
B
18

Background / watching tasks

Some tools support running in the background while watching the file system for changes and then triggering an action when a file changes on disk. With Gulp such functionality is provided through the npm module gulp-watch. The TypeScript compiler tsc has built in support for this via the --watch command line option.

To provide feedback that a background task is active in VS Code and producing problem results, a problem matcher has to use additional information to detect these state changes in the output. Let's take the tsc compiler as an example. When the compiler is started in watch mode, it prints the following additional information to the console:

> tsc --watch
12:30:36 PM - Compilation complete. Watching for file changes.

When a file changes on disk which contains a problem, the following output appears:

12:32:35 PM - File change detected. Starting incremental compilation...
src/messages.ts(276,9): error TS2304: Cannot find name 'candidate'.
12:32:35 PM - Compilation complete. Watching for file changes.

Looking at the output shows the following pattern:

  • The compiler runs when File change detected. Starting incremental compilation... is printed to the console.
  • The compiler stops when Compilation complete. Watching for file changes. is printed to the console.
  • Between those two strings problems are reported.
  • The compiler also runs once the initial start (without printing File change detected. Starting incremental compilation... to the console).

To capture this information, a problem matcher can provide a background property.

For the tsc compiler, an appropriate background property looks like this:

"background": {
    "activeOnStart": true,
    "beginsPattern": "^\\s*\\d{1,2}:\\d{1,2}:\\d{1,2}(?: AM| PM)? - File change detected\\. Starting incremental compilation\\.\\.\\.",
    "endsPattern": "^\\s*\\d{1,2}:\\d{1,2}:\\d{1,2}(?: AM| PM)? - Compilation complete\\. Watching for file changes\\."
}

In addition to the background property on the problem matcher, the task itself has to be marked as isBackground so that the task keeps running in the background.

A full handcrafted tasks.json for a tsc task running in watch mode looks like this:

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "watch",
            "command": "tsc",
            "args": ["--watch"],
            "isBackground": true,
            "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": "^\\s*\\d{1,2}:\\d{1,2}:\\d{1,2}(?: AM| PM)? - File change detected\\. Starting incremental compilation\\.\\.\\.",
                    "endsPattern": "^\\s*\\d{1,2}:\\d{1,2}:\\d{1,2}(?: AM| PM)? - Compilation complete\\. Watching for file changes\\."
                }
            }
        }
    ]
}

PS: Content taken from https://code.visualstudio.com/docs/editor/tasks

Edit-1

The task needs to be launched as a daemon then only isBackground is going to help. So you will have something like

"isShellCommand": true,
"command": "<absolute path to>/mga --config xyz abc &",
Budget answered 28/2, 2018 at 16:58 Comment(11)
Unfortunately, isBackground doesn't help. vscode is still waiting for the prelaunch task to finish.Telekinesis
@MikeLischke, please check the edit and see if it helpsBudget
Stil no luck. After changing to what you recommended in your edit I get just error messages: Failed to launch external program <absolut path to>/mga --debugger config/main.json & . spawn <absolute path to>/mga --debugger config/main.json & ENOENT. Very weird.Telekinesis
Which OS are you using?Budget
I'm on macOS. However, I'd need a solution that works on Linux, Windows and macOS.Telekinesis
I used this json and it had worked for me { "version": "2.0.0", "tasks": [ { "label": "sleep100", "type": "shell", "command": "echo sleeping for 100 && sleep 10 &", "isBackground": true } ] }Budget
I tried that too, only to get the error that the preLaunchTask cannot be tracked (whatever that means), after the 10 seconds. I used the exact content you wrote in your previous comment. The commands worked however in a terminal, so it must be a vscode problem.Telekinesis
Try this please { "version": "2.0.0", "tasks": [ { "label": "sleep100", "type": "shell", "command": "echo sleeping for 10 && sleep 20 &", "isBackground": false, "promptOnClose": false, } ] }Budget
Hmm, this seem indeed not to wait, but goes pretty far off the original idea. I want the task itself not to wait, not use some OS specific tooling to accomplish that (as it is not portable).Telekinesis
@MikeLischke, have you checked it on windows? I can't check on windows but Linux and MacOS it would work and I have checked VS Code source code, there doesn't seems to be any config that I could obviously see which would allow us to just launch and forget about the taskBudget
The Window command line doesn't support setting a task to backround with the trailing &. And somehow it really makes no sense to even use that. After all, vscode claims to have support for background tasks and even has special properties for that, but still fails without such a hack.Telekinesis
V
3

I wanted to start a watch task after I launched firefox, and I ran into the same issue: my watch task blocked firefox from launching (or vice versa, if I switched the order). Since I kept on landing on this question whenever I googled for a solution, I want to share the way I solved my problem, because I think it'll help others:

Launch configurations have a concept called Compounds. Basically, it groups other launch configurations and they will start and run in parallel. In my case, that's all I needed. Here's the relevant documentation:


Compound launch configurations

An alternative way to start multiple debug sessions is by using a compound launch configuration. A compound launch configuration lists the names of two or more launch configurations that should be launched in parallel. Optionally a preLaunchTask can be specified that is run before the individual debug sessions are started. The boolean flag stopAll controls whether manually terminating one session will stop all of the compound sessions.

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "Server",
      "program": "${workspaceFolder}/server.js"
    },
    {
      "type": "node",
      "request": "launch",
      "name": "Client",
      "program": "${workspaceFolder}/client.js"
    }
  ],
  "compounds": [
    {
      "name": "Server/Client",
      "configurations": ["Server", "Client"],
      "preLaunchTask": "${defaultBuildTask}",
      "stopAll": true
    }
  ]
}

Compound launch configurations are displayed in the launch configuration dropdown menu.


I used this for my "compounds": { "configurations" } value: ["Launch Firefox", "npm run watch"],

Vikiviking answered 7/3, 2023 at 22:23 Comment(0)
D
1

As of Nov 2022, the accepted and upvoted solutions to this question did not work.

I essentially needed a way to run Jacoco report after Junit tests finished running inside vscode java test runner. I managed to hack a way using bash and nohup, it may not be the solution for everybody but it works in my case.

tasks.json:

    "tasks": [
        {
            "label": "runJacocoReport",
            "type": "shell",
            "command": "./delayTheReport.sh"
        }
    ]

delayTheReport.sh

echo "Starting"
coproc nohup ./report.sh > nohupout.txt
sleep 1
echo "Report started in background"

report.sh

echo "Sleeping"
# This is magic number, you can replace it with a loop that checks for a certain file to exist or similar
sleep 15
echo "Starting"
# Do the thing you need to do
....
Disarray answered 10/11, 2022 at 10:30 Comment(0)
S
1

July 2023. VSCODE Version: 1.81.0-insider (user setup) Worked for me (tasks.json):

    "problemMatcher": [
        {
          "pattern": [
            {
              "regexp": ".",
              "file": 1,
              "line": 1,
              "column": 1,
              "message": 1
            }
          ],
          "background": {
            "activeOnStart": true,
            "beginsPattern": { "regexp": "." },
            "endsPattern": { "regexp": "^.*$" } // <-- right here
          }
        }
      ]

So my explanation: I'm using "command"

Get-Content C:\\xampp\\php\\logs\\xdebug.log -Wait -Tail 10

Before Debug logs got cleaned up. So basically you need to find a pattern that will work for you. As "endsPattern": { "regexp": "^.*$" } basically means end signal whatever content it might be...

Selfdefense answered 26/7, 2023 at 18:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.