vscode-csharp
vscode-csharp copied to clipboard
Feature request: integrate debugging with `dotnet watch`
Issue Description
Hi, im currently trying to set-up vscode in such a way that I can use both the debugger and dotnet watch run. When running dotnet watch run it spawns a new process eg weather.exe which the debugger can attach to. When you trigger a recompile however, dotnet watch run terminates the process weather.exe causing the debugger to also exit. This means that we have to restart the debugger every time the app is recompiled, which defeats the purpose of using dotnet watch in the first place.
I would suggest a configurable timeout for the debugger to give time to reattach to the previous instance once it gets detached.
I've attached launch.json, tasks.json and the log of my terminal after reloads, I've also included a repository down below.
Launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Attach",
"type": "coreclr",
"preLaunchTask": "watch",
"request": "attach",
"processName": "weather.exe"
}
]
}
Tasks.json
{
"version": "2.0.0",
"tasks": [
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"${workspaceFolder}/weather.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile",
"isBackground": true
}
]
}
dotnet watch run log
Steps to Reproduce
Repository to reproduce: here
Launch the configuration: .NET Core Attach
Expected Behavior
Debugger stays attached
Actual Behavior
Debugger gets terminated as dotnet watch run terminates the process it is attached to.
Logs
OmniSharp log
OmniSharp server started. Path: c:\Users\Niels.vscode\extensions\ms-dotnettools.csharp-1.23.16.omnisharp\1.37.16\OmniSharp.exe PID: 12536
Starting OmniSharp on Windows 6.2.9200.0 (x64) info: OmniSharp.Services.DotNetCliService Checking the 'DOTNET_ROOT' environment variable to find a .NET SDK info: OmniSharp.Services.DotNetCliService Using the 'dotnet' on the PATH. info: OmniSharp.Services.DotNetCliService DotNetPath set to dotnet info: OmniSharp.MSBuild.Discovery.MSBuildLocator Located 2 MSBuild instance(s) 1: Visual Studio Enterprise 2019 16.10.31424.327 16.10.2 - "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin" 2: StandAlone 17.0.0 - "c:\Users\Niels.vscode\extensions\ms-dotnettools.csharp-1.23.16.omnisharp\1.37.16.msbuild\Current\Bin" info: OmniSharp.MSBuild.Discovery.MSBuildLocator Registered MSBuild instance: Visual Studio Enterprise 2019 16.10.31424.327 16.10.2 - "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin" info: OmniSharp.WorkspaceInitializer Invoking Workspace Options Provider: OmniSharp.Roslyn.CSharp.Services.CSharpFormattingWorkspaceOptionsProvider, Order: 0 info: OmniSharp.WorkspaceInitializer Invoking Workspace Options Provider: OmniSharp.Roslyn.CSharp.Services.Completion.CompletionOptionsProvider, Order: 0 info: OmniSharp.WorkspaceInitializer Invoking Workspace Options Provider: OmniSharp.Roslyn.CSharp.Services.RenameWorkspaceOptionsProvider, Order: 100 info: OmniSharp.WorkspaceInitializer Invoking Workspace Options Provider: OmniSharp.Roslyn.CSharp.Services.ImplementTypeWorkspaceOptionsProvider, Order: 110 info: OmniSharp.WorkspaceInitializer Invoking Workspace Options Provider: OmniSharp.Roslyn.CSharp.Services.BlockStructureWorkspaceOptionsProvider, Order: 140 info: OmniSharp.Cake.CakeProjectSystem Detecting Cake files in 'c:\Users\Niels\source\repos\dotnet-watch-attach'. info: OmniSharp.Cake.CakeProjectSystem Could not find any Cake files info: OmniSharp.MSBuild.ProjectSystem No solution files found in 'c:\Users\Niels\source\repos\dotnet-watch-attach' info: OmniSharp.MSBuild.ProjectManager Queue project update for 'c:\Users\Niels\source\repos\dotnet-watch-attach\weather.csproj' info: OmniSharp.Script.ScriptProjectSystem Detecting CSX files in 'c:\Users\Niels\source\repos\dotnet-watch-attach'. info: OmniSharp.Script.ScriptProjectSystem Could not find any CSX files info: OmniSharp.WorkspaceInitializer Configuration finished. info: OmniSharp.Stdio.Host Omnisharp server running using Stdio at location 'c:\Users\Niels\source\repos\dotnet-watch-attach' on host 15580. info: OmniSharp.MSBuild.ProjectManager Loading project: c:\Users\Niels\source\repos\dotnet-watch-attach\weather.csproj [warn]: OmniSharp.MSBuild.ProjectLoader Targeting .NET 6.0 in Visual Studio 2019 is not supported. info: OmniSharp.MSBuild.ProjectManager Successfully loaded project file 'c:\Users\Niels\source\repos\dotnet-watch-attach\weather.csproj'. c:\Users\Niels\source\repos\dotnet-watch-attach\weather.csproj C:\Program Files\dotnet\sdk\6.0.100-rc.2.21505.57\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.DefaultItems.targets(134,5): Error: Targeting .NET 6.0 in Visual Studio 2019 is not supported.
Adding project 'c:\Users\Niels\source\repos\dotnet-watch-attach\weather.csproj' info: OmniSharp.MSBuild.ProjectManager Update project: weather Received response for /v2/getcodeactions but could not find request.
C# log
VSCode version: 1.61.0 C# Extension: 1.23.16
Dotnet Information
.NET SDK (reflecting any global.json): Version: 6.0.100-rc.2.21505.57 Commit: ab39070116Runtime Environment: OS Name: Windows OS Version: 10.0.19043 OS Platform: Windows RID: win10-x64 Base Path: C:\Program Files\dotnet\sdk\6.0.100-rc.2.21505.57\
Host (useful for support): Version: 6.0.0-rc.2.21480.5 Commit: 6b11d64e7e
.NET SDKs installed: 2.0.2 [C:\Program Files\dotnet\sdk] 2.1.2 [C:\Program Files\dotnet\sdk] 2.1.201 [C:\Program Files\dotnet\sdk] 2.1.202 [C:\Program Files\dotnet\sdk] 2.1.300 [C:\Program Files\dotnet\sdk] 2.1.526 [C:\Program Files\dotnet\sdk] 3.1.120 [C:\Program Files\dotnet\sdk] 3.1.414 [C:\Program Files\dotnet\sdk] 5.0.104 [C:\Program Files\dotnet\sdk] 5.0.301 [C:\Program Files\dotnet\sdk] 5.0.303 [C:\Program Files\dotnet\sdk] 6.0.100-rc.1.21458.32 [C:\Program Files\dotnet\sdk] 6.0.100-rc.2.21505.57 [C:\Program Files\dotnet\sdk]
.NET runtimes installed: Microsoft.AspNetCore.All 2.1.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.All 2.1.28 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.All 2.1.30 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.App 2.1.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 2.1.28 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 2.1.30 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.1.16 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.1.20 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 5.0.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 5.0.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 5.0.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 5.0.11 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 6.0.0-rc.2.21480.10 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.NETCore.App 2.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.0.3 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.0.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.0.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.1.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.1.28 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.1.30 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 3.1.16 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 3.1.20 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 5.0.4 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 5.0.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 5.0.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 5.0.11 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 6.0.0-rc.2.21480.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.WindowsDesktop.App 3.1.16 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 3.1.20 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 5.0.4 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 5.0.7 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 5.0.9 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 5.0.11 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 6.0.0-rc.2.21501.6 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
To install additional .NET runtimes or SDKs: https://aka.ms/dotnet-download
Visual Studio Code Extensions
| Extension | Author | Version |
|---|---|---|
| azure-account | ms-vscode | 0.9.9 |
| azure-pipelines | ms-azure-devops | 1.191.0 |
| azurerm-vscode-tools | msazurermtools | 0.15.4 |
| azurite | Azurite | 3.14.2 |
| beautify | HookyQR | 1.5.0 |
| bracket-pair-colorizer-2 | CoenraadS | 0.2.1 |
| chat | karigari | 0.35.0 |
| clang-format | xaver | 1.9.0 |
| cpptools | ms-vscode | 1.7.0 |
| csharp | ms-dotnettools | 1.23.16 |
| debugger-for-edge | msjsdiag | 1.0.15 |
| discord-vscode | icrawl | 5.7.0 |
| EditorConfig | EditorConfig | 0.16.4 |
| gc-excelviewer | GrapeCity | 3.0.44 |
| githistory | donjayamanne | 0.6.18 |
| github-vscode-theme | GitHub | 5.0.0 |
| java | redhat | 0.82.0 |
| jupyter | ms-toolsai | 2021.9.1001312534 |
| jupyter-keymap | ms-toolsai | 1.0.0 |
| jupyter-renderers | ms-toolsai | 1.0.3 |
| ng-template | Angular | 12.2.1 |
| tomoki1207 | 1.1.0 | |
| powershell | ms-vscode | 2021.10.0 |
| prettier-vscode | esbenp | 9.0.0 |
| python | ms-python | 2021.10.1336267007 |
| rainbow-csv | mechatroner | 1.9.1 |
| remote-containers | ms-vscode-remote | 0.202.4 |
| remote-ssh | ms-vscode-remote | 0.65.8 |
| remote-ssh-edit | ms-vscode-remote | 0.65.8 |
| remote-wsl | ms-vscode-remote | 0.58.2 |
| shadered | dfranx | 0.0.5 |
| shaderlabformatter | litefeel | 0.4.1 |
| shaderlabvscodefree | amlovey | 1.2.8 |
| unity-debug | Unity | 3.0.2 |
| vetur | octref | 0.34.1 |
| vscode-azurefunctions | ms-azuretools | 1.5.2 |
| vscode-azureresourcegroups | ms-azuretools | 0.4.0 |
| vscode-commons | redhat | 0.0.6 |
| vscode-css-formatter | aeschli | 1.0.1 |
| vscode-dotnet-auto-attach | DennisMaxJung | 1.1.1 |
| vscode-dotnet-runtime | ms-dotnettools | 1.3.0 |
| vscode-eslint | dbaeumer | 2.2.1 |
| vscode-html-css | ecmel | 1.10.2 |
| vscode-java-debug | vscjava | 0.36.0 |
| vscode-java-dependency | vscjava | 0.18.8 |
| vscode-java-pack | vscjava | 0.18.5 |
| vscode-java-test | vscjava | 0.32.0 |
| vscode-maven | vscjava | 0.34.0 |
| vscode-nuget-gallery | patcx | 0.0.24 |
| vscode-peacock | johnpapa | 3.10.1 |
| vscode-proto3 | zxh404 | 0.5.4 |
| vscode-pylance | ms-python | 2021.10.0 |
| vscode-remote-extensionpack | ms-vscode-remote | 0.21.0 |
| vscode-xml | redhat | 0.18.0 |
| vscodeintellicode | VisualStudioExptTeam | 1.2.14 |
| vsliveshare | ms-vsliveshare | 1.0.4991 |
| vsliveshare-audio | ms-vsliveshare | 0.1.91 |
| vsliveshare-pack | ms-vsliveshare | 0.4.0 |
| wav-preview | sukumo28 | 1.8.0 |
My current thought is the best way to implement this would be to add a special command that ran dotnet watch and scraped the output. When it saw a line about starting up a new process it would ask VS Code to debug. This could be done in this extension, or even another extension.
@gregg-miskelly If with "ask VS Code to debug" you mean automatically attach a debugger to said process then yes, this is exactly what I'm looking for. If you mean that a box pops up asking the user to automatically attach to the newly spawned process then no, as this would still require user interaction every time a rebuild is done.
Regarding implementation, I'm okay with either. I know of the existence of DotNetAutoAttach But unfortunately I can't seem to get it to work. And it is also not really maintained right now.
By "ask VS Code to debug" I mean use the VS Code debugging API to start a debug session.
I've created a fairly crude extension which works for now. dotnet watch attach.
Would however still like to see this actually implemented :)
+1 here. Really would like to close this inner loop and be able to do hot reload with VS Code like VS.net.
+1 for this as I mostly use VS Code for Blazor dev.
+1 for this as I mostly use VS Code for Blazor dev.
I've created an extension dotnet-watch, comes with debug config provider (auto generate launch.json), doesn't require manually setting up task.json.
Also examples with compound tasks for microservices

@Trottero solution works for me with Orchard Core.
The only thing is that it seems to have an issue finding the proper $msCompile problemMatcher. I tried also @murugaratham extension but it seems to only launch in the console and I didn't find how to launch a browser automatically with it.
So, 2 questions :
Is there a plan to support this directly in VS Code? If not then ... Anyone has an idea for a solution to the problemMatcher issue there is with @trottero VS Code extension?
I tryed both extensions proposed on Mac.
- Liked support vscode 'inputs'
- Doesnot support Mac, breakpoints aren't hit.
- Simpler to use
- Very slow when re-compiling (had to uninstall it, it s faster running the whole project again)
I work out of a development container and it would be so nice to be able to avoid having to restart the debugger every time I make a change. Hopefully this gets added in the near future
@Skrypt @MarcoMedrano @loligans
The issues you have mentioned have since been solved for my plugin dotnet watch attach
I specifically tested Ubuntu 22.04 and development in WSL from windows (should be similar to the development container)
Another developer contributed support for the M1 Macs.
If you encounter any issues, please let me know by creating an issue in this repository
I've created a fairly crude extension which works for now. dotnet watch attach.
Would however still like to see this actually implemented :)
FYI, this didn't work for me. It launches the watch and the little debugging window (pause/step/stop/etc) appears. But doesn't show the list of threads and breakpoints don't trigger.
make sure that the "program" property in launch.json is only the name of the binary. It's looking for a process with that name to attach to. It's misleading that the request type is launch, it should really be attach. Here's my currently working configs for a web app, with both the in-box config (no watch) and one that works with dotnetwatchattach. launch.json
{
"version": "0.2.0",
"configurations": [
{
// Use IntelliSense to find out which attributes exist for C# debugging
// Use hover for the description of the existing attributes
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
"name": ".NET Core Launch (web)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/src/api-server/bin/Debug/net7.0/Server.dll",
"args": [],
"cwd": "${workspaceFolder}/src/api-server",
"stopAtEntry": false,
// Enable launching a web browser when ASP.NET Core starts. For more information: https://aka.ms/VSCode-CS-LaunchJson-WebBrowser
"serverReadyAction": {
"action": "openExternally",
"uriFormat": "%s/swagger",
"pattern": "\\bNow listening on:\\s+(https?://\\S+)"
},
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"sourceFileMap": {
"/Views": "${workspaceFolder}/Views"
}
},
{
"name": ".NET Core watch attach",
"type": "dotnetwatchattach",
"request": "launch",
"task": "watch",
"program": "Server.exe", // Process/binary name (no extension in linux)
"args": {
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
// Enable launching a web browser when ASP.NET Core starts. For more information: https://aka.ms/VSCode-CS-LaunchJson-WebBrowser
"serverReadyAction": {
"action": "openExternally",
"uriFormat": "%s/swagger",
"pattern": "\\bNow listening on:\\s+(https?://\\S+)"
}
}
}
tasks.json
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/src/api-server/Server.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"--project",
"${workspaceFolder}/src/api-server/Server.csproj"
],
"options": {
"env": {
"DOTNET_WATCH_RESTART_ON_RUDE_EDIT": "true" // Optional
}
},
"problemMatcher": "$msCompile"
}
]
}
That worked! The dotnet watch does still seem a bit buggy and weird, but now it seems to be properly re-attaching to the process after rebuild. Thanks! :)
How would the developed extensions work with remote debugging over SSH?
Below is one of our launch configurations:
{
// ...
"configurations": [
// ...
{
"name": "Okteto: .NET Core SSH Attach",
"type": "coreclr",
"request": "attach",
// "processId": "${command:pickRemoteProcess}",
// "processName": "my-Pwa.Server",
"processName": "/okteto/Server/bin/Debug/net7.0/my-pwa.Server",
// π // π // π Need something simple like this
"restart": true, // Waiting for: https://github.com/OmniSharp/omnisharp-vscode/issues/4822
// π // π // π Such that it can work with any existing remote debugger
"pipeTransport": {
"pipeProgram": "ssh",
"debuggerPath": "~/vsdbg/vsdbg",
"pipeCwd": "${workspaceRoot}",
"pipeArgs": [
"-q",
"-T",
"my-webapp.okteto"
],
"quoteArgs": true,
"justMyCode": false,
},
"sourceFileMap": {
"/okteto": "${workspaceRoot}"
}
},
// ...
],
"compounds": [
// ...
]
}
@rrmistry
The plugin I developed dotnetwatchattach should work for you, just pass your pipeTransport object to the args object of dotnetwatchattach, everything in the args object is copied to the new configuration.
As in, the plugin literally creates a debugging session of "type": "coreclr" whenever it detects that the specified program is running - which should be exactly the same as your current configuration.
@Trottero ,
Thank you for the tip! It works well by passing the pipeTransport into args.
But I noticed that it doesn't handle the scenario of multiple tasks with the same name but in different workspaces.
To reproduce the issue we can start with a workspace file called multiple-git-repos.code-workspace with the contents:
{
"folders": [
{
// Create dotnet sample in /.../parentFolder with name "webapp1"
"name": "Web App One",
"path": "/.../parentFolder/webapp1"
},
{
// Create dotnet sample in /.../parentFolder with name "webapp2"
"name": "Web App Two",
"path": "/.../parentFolder/webapp2"
},
],
"settings": {
}
}
Then create two different tasks with the same name in both webapp1 and webapp2
Then open the multi-workspace session in VS Code via this workspace file.
Now if you try to debug dotnetwatchattach type launch config from webapp2 using the dotnetwatchattach extension then it starts the task from webapp1 instead of webapp2.
This behavior seems to be limited to only multi-workspace sessions within VS Code.
My workaround, for now, is to make the target task globally unique for the duration of debugging. But it is an inconvenience.
Should I file a separate issue under Trottero/dotnet-watch-attach?
@rrmistry That would be great - Thank you!
I develop wpf app I found that we can change the cs code and hot reload is ok But after hot reloadοΌ we can not attach Unless recompiled and restart(This is not what we all want),
so, may be EnC is the most feature we want ->Debugger: Support Edit and Continue/Hot Reload #490
Now that Microsoft/Dotnet team has officially absorbed the VSCode C# extension. Is this feature on the roadmap somewhere? It would be great to get official word on this functionality considering it's popularity. It's in the top 20 most highly requested features for this repo.