Scott Hanselman

Remote Debugging a .NET Core Linux app in WSL2 from Visual Studio on Windows

December 04, 2019 Comment on this post [7] Posted in Linux | VS2019
Sponsored By

With Visual Studio Code and WSL (Windows Subsystem for Linux) you can be in a real Linux environment and run "code ." from the Linux prompt and Visual Studio Code will launch in Windows and effectively split in half. A VSCode-Server will run in Linux and manage the Language Services, Debugger, etc, while Windows runs your VS Code instance. You can use VS Code to develop on remote machines over SSH as well and it works great. In fact there's a whole series of Remote Tutorials to check out here.

VS Code is a great Code Editor but it's not a full IDE (Integrated Development Environment) so there's still lots of reasons for me to use and enjoy Visual Studio on Windows (or Mac).

I wanted to see if it's possible to do 'remote' debugging with WSL and Visual Studio (not Code) and if so, is it something YOU are interested in, Dear Reader.

  • To start, I've got WSL (specifically WSL2) on my Windows 10 machine. You can get WSL1 today on Windows from "windows features" just by adding it. You can get WSL2 today in the Windows Insiders "Slow Ring."
  • Then I've got the new Windows Terminal. Not needed for this, but it's awesome if you like the command line.
  • I've got Visual Studio 2019 Community

I'm also using .NET Core with C# for my platform and language of choice. I've installed from https://dot.net/ inside Ubuntu 18.04, under Windows. I've got a web app (dotnet new razor) that runs great in Linux now.

RemoteWebApp in the Terminal

From the WSL prompt within terminal, I can run "explorer.exe ." and it will launch Windows Explorer at the path \\wsl$\Ubuntu-18.04\home\scott\remotewebapp, but VS currently has some issues opening projects across this network boundary. I'll instead put my stuff at c:\temp\remotewebapp and access it from Linux as /mnt/c/temp/remotewebapp.

RemoteWebApp in Explorer

In a perfect world - this is future speculation/brainstorming, Visual Studio would detect when you opened a project from a Linux path and "Do The Right Thing(tm)."

I'll need to make sure the VSDbg is installed in WSL/Linux first. That's done automatically with VS Code but I'll do it manually in one line like this:

curl -sSL https://aka.ms/getvsdbgsh | /bin/sh /dev/stdin -v latest -l ~/vsdbg

We'll need a launch.json file with enough information to launch the project, attach to it with the debugger, and notice when things have started. VS Code will make this for you. In some theoretical future Visual Studio would also detect the context and generate this file for you. Here's mine, I put it in .vs/launch.json in the project folder.

VS will make a launch.json also but you'll need to add the two most important parts, the $adapter and $adapterArgs part as I have here.

{
// 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
"version": "0.2.0",
"configurations": [
{
"$adapter": "C:\\windows\\sysnative\\bash.exe",
"$adapterArgs": "-c ~/vsdbg/vsdbg",
"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": "/mnt/c/temp/remotewebapp/bin/Debug/netcoreapp3.0/remotewebapp.dll",
"args": [],
"cwd": "/mnt/c/temp/remotewebapp",
"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",
"pattern": "^\\s*Now listening on:\\s+(https?://\\S+)"
},
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"sourceFileMap": {
"/Views": "${workspaceFolder}/Views"
},
"pipeTransport": {
"pipeCwd": "${workspaceRoot}",
"pipeProgram": "bash.exe",
"pipeArgs": [ "-c" ],
"debuggerPath": "~/vsdbg/vsdbg"
},
"logging": { "engineLogging": true }
}
]
}

These launch.json files are used by VS and VS Code and other stuff and give the system and debugger enough to go on. There's no way I know of to automate this next step and attach it to a button like "Start Debugging" - that would be new work in VS - but you can start it like this by calling a VS2019 automation command from the "Command Window" you can access with View | Other Windows | Command Window, or Ctrl-Alt-A.

Once I've typed this once in the Command Window, I can start the next Debug session by just pressing Up Arrow to get the command from history and hitting enter. Again, not perfect, but a start.

DebugAdapterHost.Launch /LaunchJson:C:\temp\remotewebapp\.vs\launch.json  

Here's a screenshot of me debugging a .NET Core app running in Linux under WSL from Windows Visual Studio 2019.

VS 2019

Thanks to Andy Sterland for helping me get this working.

So, it's possible, but it's not falling-off-a-log automatic. Should this setup and prep be automatic? Is development in WSL from Visual Studio (not Code) something you want? There is great support for Docker development within a container including interactive debugging already, so where do you see this fitting in...if at all? Does this add something or is it more convenient? Would you like "F5" debugging for WSL apps within VS like you can in VS Code?


Sponsor: Like C#? We do too! That’s why we've developed a fast, smart, cross-platform .NET IDE which gives you even more coding power. Clever code analysis, rich code completion, instant search and navigation, an advanced debugger... With JetBrains Rider, everything you need is at your fingertips. Code C# at the speed of thought on Linux, Mac, or Windows. Try JetBrains Rider today!

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Hosting By
Hosted in an Azure App Service
December 07, 2019 23:57
Very cool. I'm not a WSL power-user, but have already used it successfully (along with Windows Terminal!) to quickly identify Linux-vs-Windows issues in an open-source scientific computational project I'm involved in. Could definitely see using this VS integration for app development of Linux-hosted server-side Blazor.
December 09, 2019 2:26
Followed along with this and ended up with:

Failed to launch debug adapter 'coreclr'.
The system cannot find the file specified


I have no C:\windows\sysnative directory so I pointed the adapter at C:\Windows\System32\bash.exe.

I can launch the app from Ubuntu (18.04) running under WSL 2 and connect to it from Windows.

I'm also running with .NET Core 3.1.

Here is my .vs\launch.json:

{
// 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
"version": "0.2.0",
"configurations": [
{
"$adapter": "C:\\Windows\\System32\\bash.exe",
"$adapterArgs": "-c ~/vsdbg/vsdbg",
"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": "/mnt/c/temp/remotewebapp/bin/Debug/netcoreapp3.1/remotewebapp.dll",
"args": [],
"cwd": "/mnt/c/temp/remotewebapp",
"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",
"pattern": "^\\s*Now listening on:\\s+(https?://\\S+)"
},
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"sourceFileMap": {
"/Views": "${workspaceFolder}/Views"
},
"pipeTransport": {
"pipeCwd": "${workspaceRoot}",
"pipeProgram": "bash.exe",
"pipeArgs": [ "-c" ],
"debuggerPath": "~/vsdbg/vsdbg"
},
"logging": { "engineLogging": true }
}
]
}

It seems like a head-smack kind of error: The system cannot find the file specified!

Has anyone seen this? What did I miss?
Ray
December 10, 2019 10:07
Ray,

The folder C:\Windows\Sysnative\ is a special folder. If you run a 32bit WoW cmd prompt (C:\Windows\SysWOW64\cmd.exe) you can use it to launch a 64bit process e.g. C:\Windows\Sysnative\notepad.exe. Which is what VS needs to do.

Anyhow, try the path above "C:\\windows\\sysnative\\bash.exe" and see if it works.

There's some more info on this behavior over in the docs for the feature on github.
December 12, 2019 13:59
I'm learning WSL2, it's quiet difficult for me. I just installed my Linux distribution, do you have some advices please? Thanks
December 13, 2019 9:34
Yes!!!!! This is one of my top requests. Currently jumping through hoops trying to use VS on local machine for refactoring and IntelliSense then VSCode to copy, compile, and debug on Linux. Also need SSH support as well. Maybe the people working on the VSCode extension can build one for VS.
Guy
December 13, 2019 11:00
Hey, Thank you for sharing this great post. Hope you are having a great day. Keep it up and keep share such valuable information.
December 18, 2019 22:17
I started a new .net Core 3.1 Worker Service project but I don't have a launch.json. The closest in name I have is a launchSettings.json which isn't similar enough for me to see if this is the right place and what I would set. It looks like it was originally stubbed for docker, which was a choice I made when creating the project.

Any tips for

{
"profiles": {
"MyWorkerService": {
"commandName": "Project",
"environmentVariables": {
"DOTNET_ENVIRONMENT": "Development"
}
},
"Docker": {
"commandName": "Docker"
}
}
}

Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.