2

I am using VSCode 0.10.6 for C++ programming. I am trying to launch a program prior to debugging. The program, OpenOCD, is what GDB connects to. If I manually open and close it through a terminal, it works fine, but it seems like there should be an easy way to get VSCode to just start it for me.

I have played with tasks.json and it appears you need to use some ugly bat/sh files to accomplish this in combination with preLaunchTasks in launch.json.

Brent Arias
  • 29,277
  • 40
  • 133
  • 234
user1758663
  • 121
  • 2
  • 8

1 Answers1

0

Currently the answer is that you must indeed use preLaunchTasks to have a chance of making this work. I would have been happy to use an ugly script, if that indeed would work - but it doesn't. In my case, I needed one or more executables to be ran in the background, allowing VSCode to continue into debugging.

Unfortunately, each executable I tried to launch (via start) was not actually running as a "detached" process, and so VSCode would wait for each executable to finish running before it would finish the preLaunchTasks and start debugging. Not what I wanted.

I found an article by someone having a similar "detached process" problem with subversion, and I used his C++ code to solve this same issue with Visual Studio Code. I found a bug or two in that code, which I fixed. Here is what I'm currently using:

// dstart.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <windows.h> 
#include <stdio.h> 
#include <tchar.h> 

//http://stackoverflow.com/questions/1536205/running-another-program-in-windows-bat-file-and-not-create-child-process
//http://svn.haxx.se/users/archive-2008-11/0301.shtml
int _tmain()
{
    //https://msdn.microsoft.com/en-us/library/windows/desktop/ms683156(v=vs.85).aspx
    LPWSTR pCmd = ::GetCommandLine();
    // skip the executable 
    if (*pCmd++ == L'"') 
        while (*pCmd++ != L'"');
    else 
        while (*pCmd != NULL && *pCmd != L' ') ++pCmd;
    while (*pCmd == L' ') pCmd++;
    STARTUPINFO si;
    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    PROCESS_INFORMATION pi;
    ZeroMemory(&pi, sizeof(pi));
    // Start the child process. 
    BOOL result = CreateProcess
        (
            NULL, // No module name (use command line) 
            pCmd, // Command line 
            NULL, // Process handle not inheritable 
            NULL, // Thread handle not inheritable 
            FALSE, // Set bInheritHandles to FALSE 
            CREATE_NEW_CONSOLE, // Detach process 
            NULL, // Use parent's environment block 
            NULL, // Use parent's starting directory 
            &si, // Pointer to STARTUPINFO structure 
            &pi // Pointer to PROCESS_INFORMATION structure (returned)
            );
    if (result) return 0;
    wchar_t msg[2048];
    FormatMessage
        (
            FORMAT_MESSAGE_FROM_SYSTEM,
            NULL,
            ::GetLastError(),
            MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT),
            msg, sizeof(msg),
            NULL
            );
    fputws(msg, stderr);
    _flushall();
    return -1;
}

Once compiled, you can use it similarly to how the start command works at a DOS prompt. Place that in the script you attach to your preLaunchTasks in Visual Studio Code.

Community
  • 1
  • 1
Brent Arias
  • 29,277
  • 40
  • 133
  • 234