90

I am having difficulty figuring out if and how I can use Visual Studio Code to develop and debug command-line/console/libraries of C# .NET programs which can not run on .NET Core, i.e. they require .NET Framework. I need to access Oracle which do not have a .NET Core provider but it does have a Managed .NET Framework provider. I use VS 2015/2017 for this task but would like to switch to VS Code if I could code, build and debug .NET Framework target C# programs. I have tried Google search and could not find anything.

6
  • Check out this question posted here stackoverflow.com/questions/29953743/… Commented Dec 8, 2017 at 3:10
  • 2
    I saw this, it does not answer my question. If you think it does, please cut and paste the relevant paragraph here. Thank you.
    – Acid Rider
    Commented Dec 8, 2017 at 3:29
  • have you tried using the oracle provider with .net core? Commented Dec 8, 2017 at 3:57
  • i tried using .net provider with core, got lots of exceptions with various dll dependencies, plus its not supported so i gave up..... the system.data.odbc works in Core but very slow.
    – Acid Rider
    Commented Dec 8, 2017 at 19:33
  • This question is currently referenced from the documentation for using VS Code with C#. I think the implication is not to try developing .NET Framework code with VS Code, and to use Visual Studio instead. Otherwise Microsoft/OmniSharp would make it work and document it properly.
    – Rich N
    Commented Oct 26, 2019 at 11:21

6 Answers 6

92

First thing, the more recent updates for Visual Studio Code do support building and debugging projects for the .NET Framework, but it is very limited.

The GitHub page for OmniSharp (responsible for the C# extension) says that:

The C# extension supports limited full .NET framework debugging. It can only debug 64-bit applications with portable PDBs.

But, even after reading many issues and discussions about this topic, it remained a little bit unclear for me what the necessary steps were, so I will expose here a little guide with the steps that I have followed and that worked for me, and hopefully, will also work for you.

  1. The necessary files/folders are:

    a. .vscode with launch.json and tasks.json.

    b. bin\Debug folder for your .exe application and the assemblies you might want to create a reference to.

    d. the <project>.csproj and Program.cs files.

    e. optionally a batch file, whose purpose I will describe later.

  2. Install MSBuild 15 (2017).

  3. In the <project>.csproj file:

    • change the Project Sdk="Microsoft.NET.Sdk" to Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003".

    • in the first PropertyGroup we must set the OutputType to Exe (the default may be dll), remove the TargetFramework property, replacing with TargetFrameworkVersion with value v4.6.1 (example for .NET Framwork 4.6.1, it may be 4.7 for instance), and finally put the runtimes win-x64 and win7-x64 (and any other that the compiler may complain). This first PropertyGroup should look like this:

      <PropertyGroup>
         <OutputType>Exe</OutputType>
         <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
         <RuntimeIdentifiers>win-x64;win7-x64</RuntimeIdentifiers>
      </PropertyGroup>
      
    • set another PropertyGroup` with the following items:

      <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
        <PlatformTarget>x64</PlatformTarget>
        <DebugSymbols>true</DebugSymbols>
        <DebugType>portable</DebugType>
        <Optimize>false</Optimize>
        <OutputPath>bin\Debug\</OutputPath>
        <DefineConstants>DEBUG;TRACE</DefineConstants>
        <ErrorReport>prompt</ErrorReport>
        <WarningLevel>4</WarningLevel>
      </PropertyGroup>
      

    Some comments: the condition used signals that these properties only apply when the configuration passed to the compiler is Debug and the Platform is "AnyCPU", you might want to insert other conditions with different values, or even don't use a condition at all; the most import values here are: The PlatformTarget property must be x64 and the DebugType must be portable; the output path is set to bin\Debug.

    • As we are not using the Microsoft SDK we must include the Program.cs, so that the compiler can find it:

      <ItemGroup>
        <Compile Include="Program.cs" />
      </ItemGroup>
      
    • create the necessary references to your project, for example:

      <ItemGroup>
        <Reference Include="mscorlib" />
        <Reference Include="System.Core" />
        <Reference Include="System.Windows" />
        <Reference Include="System.ServiceModel" />  
        <Reference Include="System.Net" />
        <Reference Include="System.Xml" />
        <Reference Include="System" />
        <Reference Include="System.Xml.Linq" />
        <Reference Include="System.Data.DataSetExtensions" />
        <Reference Include="Microsoft.CSharp" />
        <Reference Include="System.Data" />
        <Reference Include="System.Net.Http" />
      </ItemGroup>
      
    • finally import the following tools (make sure you follow the order exposed here, placing this in the beginning for instance you generate an error)

    The whole thing should look like this:

    <Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    
      <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
        <RuntimeIdentifiers>win-x64;win7-x64</RuntimeIdentifiers>
      </PropertyGroup>
    
      <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
        <PlatformTarget>x64</PlatformTarget>
        <DebugSymbols>true</DebugSymbols>
        <DebugType>portable</DebugType>
        <Optimize>false</Optimize>
        <OutputPath>bin\Debug\</OutputPath>
        <DefineConstants>DEBUG;TRACE</DefineConstants>
        <ErrorReport>prompt</ErrorReport>
        <WarningLevel>4</WarningLevel>
      </PropertyGroup>
    
      <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
        <PlatformTarget>x64</PlatformTarget>
        <DebugType>portable</DebugType>
        <Optimize>true</Optimize>
        <OutputPath>bin\Release\</OutputPath>
        <DefineConstants>TRACE</DefineConstants>
        <ErrorReport>prompt</ErrorReport>
        <WarningLevel>4</WarningLevel>
      </PropertyGroup>
    
      <ItemGroup>
        <Compile Include="Program.cs" />
      </ItemGroup>
    
      <ItemGroup>
        <Reference Include="mscorlib" />
        <Reference Include="System.Core" />
        <Reference Include="System.Windows" />
        <Reference Include="System.ServiceModel" />  
        <Reference Include="System.Net" />
        <Reference Include="System.Xml" />
        <Reference Include="System" />
        <Reference Include="System.Xml.Linq" />
        <Reference Include="System.Data.DataSetExtensions" />
        <Reference Include="Microsoft.CSharp" />
        <Reference Include="System.Data" />
        <Reference Include="System.Net.Http" />
      </ItemGroup>
    
      <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
    
    </Project>
    
  4. In the launch.json:

    • Create a new configuration(e.g. MyLauncher), whose type must be clr, and that points to your program; the preLaunchTask will be set to a manually configured one ("mybuild", for instance) that will be specified in the tasks.json; an example of the configuration is:

      {
         "version": "0.2.0",
         "configurations": [
              {
                  "name": "MyLauncher",
                  "type":"clr",
                  "request": "launch",
                  "preLaunchTask": "mybuild",
                  "program": "${workspaceFolder}/bin/Debug/<project>.exe",
                  "args":[],
                  "console": "internalConsole",
                  "stopAtEntry": false,
                  "internalConsoleOptions": "openOnSessionStart"
              },
              { other configurations...
              }
          ,]
      }
      
  5. In the tasks.json:

    • Create a task "mybuild" with the commands to build your project.

    • We will use the MSBuild 15 here (don't use the dotnet build - at least it has not worked for me).

    • You can directly point to the (path)\MSBuild.exe (or msbuild.exe, if it is in the %PATH%) file with the arguments to build the project. One example is shown below, note that I've set the Configuration to Debug and the platform to AnyCPU, matching the condition Ive set in the .csproj file, also note that the backslashes in \"AnyCPU\" are because of the use of the quotation marks.

      {
          "version": "2.0.0",
          "tasks": [
              {
                  "label": "mybuild",
                  "command":"<path to msbuild>\MSBuild.exe",
                  "type":"shell",
                  "args":[
                      "<project>.csproj",
                      "/t:Build",
                      "/p:Configuration=Debug",
                      "/p:Platform=\"AnyCPU\""
                  ]
              }
          ]
      }
      
    • but there is another way, using the .bat file; in my case the path to the MSBuild.exe had spaces and that was generating an error when the task run, so that I've put the following code in a .bat file (save notepad as name.bat):

      "(path)\MSBuild.exe" (project).csproj /t:Build /p:Configuration=Debug /p:Platform="AnyCPU"
      

      and then set the "mybuild" task to:

      {
          "label": "mybuild",
          "command":"build.bat",
          "type":"shell",
          "args":[]
      }
      

      Where build.bat is the batch file I have created with the previous code.

  6. After this, you might have to save, close and reopen the files (this many times fixes problems for me).

  7. Set your configuration in the debugger to MyLauncher:

    print

  8. Run your code with the green play button; it will call the MyLauncher, that first will build your project with MSBuild 15 and then run the exe file

So that was it.

Here are some references:

5
  • 11
    thanks for the long answer, however I thi I will go back to Visual Studio :'( I take less time than this :'(
    – Luke
    Commented Jun 10, 2018 at 10:23
  • I would like to use Visual Studio Code at work. What type of license does MSBuild 15 have? Also, where can I get MSBuild 15? Commented Jul 15, 2018 at 21:34
  • 1
    @user1164199 MSBuild is open source under the MIT license. Unfortunately, you have to build it yourself, or else download it with Visual Studio. The source is on GitHub. Commented Mar 6, 2019 at 17:49
  • tip for locating your bat file: your launch.json is at "./.vscode/lauch.json" Commented Jun 15, 2019 at 3:32
  • 2
    @Abr for 'just work' you have visual studio, not vs code Commented Sep 30, 2019 at 20:14
34

I just created a simple console application and customized the csproj file. Afterwards, I could attach the OmniSharp debugger to a full .NET framework application. The csproj file looks like this:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net47</TargetFramework>
    <PlatformTarget>x64</PlatformTarget>
    <DebugType>portable</DebugType>
  </PropertyGroup>

</Project>

I just followed the official documentation: I changed TargetFramework to run on .NET 4.7, the PlatformTarget to 64 bit and the DebugType to portable.

Furthermore, I updated 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": [
        {
            "name": ".NET Launch (console)",
            "type": "clr",
            "request": "launch",
            "preLaunchTask": "build",
            // If you have changed target frameworks, make sure to update the program path.
            "program": "${workspaceFolder}/bin/Debug/net47/FullNetInVsCode.exe",
            "args": [],
            "cwd": "${workspaceFolder}",
            // For more information about the 'console' field, see https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md#console-terminal-window
            "console": "internalConsole",
            "stopAtEntry": false,
            "internalConsoleOptions": "openOnSessionStart"
        },
        {
            "name": ".NET Attach",
            "type": "clr",
            "request": "attach",
            "processId": "${command:pickProcess}"
        }
    ,]
}

In this file, I just changed type to clr in both JSON objects, and targeted program to the exe file.

Afterwards, I could set a break point and simply press F5 to start debugging on full .NET framework:

Debugging full .NET framework in VS Code

2
  • Works also without DebugType. Commented Dec 3, 2021 at 19:13
  • Works also without PlatformTarget. For me the key thing was to change from coreclr to clr
    – gitsitgo
    Commented Dec 6, 2023 at 6:33
6

https://code.visualstudio.com/docs/languages/csharp

Quote:

Note: VS Code does not support debugging applications running on the Desktop .NET Framework.

It looks like Visual Studio 'full-fat' IDE remains a requirement for .Net Framework. Major pity.

1
4

There are plenty of solid answers at this point, but they can be simplified.

This answer is valid as of 28 JUN 2023.


Debugging a .NET Framework Project

Debugging a .NET Framework project in VS Code is as simple as creating a launch configuration and an optional build task.

Launch Configuration

The launch configuration specifies the application you wish to attach to, and is stored in a file named launch.json stored in a folder at the root of your workspace named .vscode. The following example can be used as a blanket template to adjust to your needs:

{
    "version": "0.2.0",
    "configurations": [
         {
             "name": "Sample Console",
             "type": "clr",
             "request": "launch",
             "preLaunchTask": "buildSampleConsole",
             "program": "pathToExecutable.exe",
             "args": [],
             "cwd": "pathToWorkingDirectory",
             "console": "internalConsole",
             "stopAtEntry": false,
             "internalConsoleOptions": "openOnSessionStart"
         }
    ]
 }

To learn more about launch configurations, please visit the OmniSharp documentation.

The name Property

The name property is self-explanatory, it simply names the configuration. I recommend specifying something distinct for more involved projects because this is how you'll identify the configuration to start your debugging process:

Screenshot showing the configuration dropdown menu.

The program Property

The program property is the path to the executable you wish to debug. It's recommended to use the ${workspaceFolder} lexicon to handle the path to the workspace itself:

"program": "${workspaceFolder}/src/SampleConsole/bin/Debug/net48/SampleConsole.exe"

The cwd Property

The cwd property is the current working directory. This is the working directory of the program being debugged:

"cwd": "${workspaceFolder}/src/SampleConsole"

The preLaunchTask Property

This property simply specifies the name of which task to run prior to launching. It's not technically required but is highly recommended to ensure you're debugging the latest state of your application.

Build Task

The build task is optional, but is stored in a file named tasks.json in that same .vscode folder at the root of your workspace:

{
    "label": "buildSampleConsole",
    "detail": "Builds the sample console.",
    "command": "dotnet",
    "type": "process",
    "args": [
        "build",
        "src/SampleConsole/SampleConsole.csproj"
    ],
    "problemMatcher": "$msCompile"
}

Disclaimer

I utilize two extensions for working with C#:

I do not know 100% without a doubt that this answer is valid without them, so please keep that in mind.

0

Unfortunately, it doesn't feature intellisense for C/C++, only syntax highlighting: code.visualstudio.com/docs/languages EDIT: no debugger integration for C/C++ either. The git integration is really nice though! Seems more designed for web applications, the debugger works for node.js

Whilst this does not specify C#, it stands to reason that the same standards apply (which is that there is no debugger and no compile functionality).

Quote taken from comment on first answer of What exactly is Visual Studio Code?

1
  • according to YouTube videos on VS Code, C/C++ is supported and has debugger support. In any case, I have the answer, .Net Framework C# and VS Code do not mix well as of Dec 2017. Pity. We move on.
    – Acid Rider
    Commented Dec 9, 2017 at 8:47
-1

To start with, install Build Tools for Visual Studio 2019

To your VS Code workspace add .vscode folder and add tasks.json to build your project. Use below a sample of tasks.json can be used mostly for any .Net Framework project.

{
  "version": "2.0.0",
  "command": "msbuild",
  "args": [ "/property:GenerateFullPaths=true" ],
  "tasks": [{
    "label": "build",
    "problemMatcher": "$msCompile"
  }] 
}

Next step to make F5 work with VS Code. In order to make it work add launch.json in .vscode folder

{
    "version": "0.2.0",
    "configurations": [
      {
        "name": ".NET Framework Launch",
        "type": "clr",
        "request": "launch",
        "preLaunchTask": "build",
        "program": "demo.console.exe",
        "args": [],
        "cwd": "${workspaceFolder}\\demo.console\\bin\\debug\\net461\\",
        "stopAtEntry": false
      },
      {
        "name": ".NET Framework",
        "type": "clr",
        "request": "attach",
        "processId": "${command:pickProcess}"
      }
    ]
  }

Note: Please change "program" and "cwd" for your application

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.