1

In Visual Studio 2015 it was possible to check whether a running application had been started from Visual Studio by checking if a debugger is active and if the process was vshost.exe like this:

bool isInVisualStudio = Debugger.IsAttached && AppDomain.CurrentDomain.FriendlyName.EndsWith("vshost.exe");

Since Visual Studio 2017 this is no longer possible as the current domain is always the application executable name regardless of how it was started.

I have been trying without success to do the same thing in VS2019. The closest I can get is to check if a debugger is attached and if Visual Studio is running at the same time:

bool devEnvIsRunning = Process.GetProcessesByName("devenv").Length > 0;
bool isInVisualStudio = Debugger.IsAttached && devEnvIsRunning;

The problem with this for my purposes is that I want to skip some code when it is running from source in my copy of VS on my machine, but I definitely do NOT want to skip that code just because another debugger is installed.

I have been trying to find a way to get the name of the attached debugger which would solve the problem, but have been unable to do so.

Anyone got any suggestions on how to achieve in VS2019 that which was so easy in VS2015 and earlier?

oldcoder
  • 342
  • 2
  • 12
  • check https://stackoverflow.com/questions/2188201/is-there-a-way-to-detect-if-a-debugger-is-attached-to-another-process-from-c – Clint Feb 16 '20 at 15:55
  • Regrettably that does not answer the question. Debugger.IsAttached is already being used, so we already have that information. What we do not know is whether that debugger is VisualStudio which previously we knew. The problem is that if we only use Debugger.IsAttached and skip code in that scenario we have an obvious security hole as you could avoid that code by simply attaching a debugger... – oldcoder Feb 17 '20 at 14:01
  • https://stackoverflow.com/a/2533287/17034 – Hans Passant Feb 17 '20 at 17:43
  • In VS 2022, bool isInVisualStudio = Debugger.IsAttached works just fine. – Chris Patterson May 15 '23 at 15:31
  • @ChrisPatterson: What you propose would have worked in 2019 as well. Unfortunately it does not achieve the required result as stated in the question for very obvious reasons. The requirement was to obtain the name of the attached debugger, thus a string. IsInVisualStudio is a boolean, Debugger.IsAttached returns a boolean. If you can get the name of the debugger from a boolean you will be remarkably clever! The solution is in the accepted answer and the link proposed by Hans Passant which does return the required value. – oldcoder May 16 '23 at 17:49

2 Answers2

0

I think the easiest ways for you to achieve this is with Command line arguments or environment variables.

Command line arguments can be configured in the project's debug tab in the project properties, and then you can check to see what arguments have been passed through by checking Environment. GetCommandLineArgs for any values you may be expecting. You can do that at any time and you should be good.

If setting a command line variable isn't what you want to do, using an environment variable can also work. The basic idea is the same, you can configure environment variables in the debug tab (some projects have VS specific variables by default) and check for them. I'm not sure exactly how to do that one from memory and I'm typing on mobile at the moment, but one of those options should cover you.

I personally would go for the command line arguments option. It allows you to skip whatever task it is you want to skip whenever, not just when VS launching the program.

Captain Obvious
  • 608
  • 5
  • 14
  • Thanks for the suggestion. Unfortunately it does not help me identify the debugger, and has its own issues because we already check command line arguments for other things and of course you can add in or leave out command line arguments at runtime making it trivial to impersonate the situtation where Visual Studio is running the application from code when in fact VS is not even installed on the PC - I don't believe that either proposal works for this reason. – oldcoder Feb 17 '20 at 14:07
  • Can you provide more information regarding your test scenarios when you want the code executed and when you do not? If it is simply a matter of whether or not you are executing code compiled under your debug configuration, using the preprocessor #if DEBUG might suffice. – Jack Whipnert Feb 17 '20 at 20:33
  • Hi Jack, I am not really sure how to make it any clearer but I will try. When this particular application starts, in Progam.cs, we perform various checks and initialisations. One of those requires us to know if the application is running in Visual Studio because when doing so some checks are not valid e.g. comparing digital certificates which do not exist at that point in VS but do exist in the wild. In VS2015 and below this was possible by checking whether a debugger is attached and whether it is VS - the question has code. That is no longer possible so I am looking for an alternative... – oldcoder Feb 18 '20 at 10:09
0

The answer turned out to be in the comment provided by Hans Passant referencing his answer to another question: stackoverflow.com/a/2533287/17034

Using WMI as suggested by Hans, and checking for the new remote debugger MSVSMON rather than DEVENV as before, we get the answer we need:

using System.Management;

var myId = Process.GetCurrentProcess().Id;
var query = $"SELECT ParentProcessId FROM Win32_Process WHERE ProcessId = {myId}";
var search = new ManagementObjectSearcher("root\\CIMV2", query);
var results = search.Get().GetEnumerator();
results.MoveNext();
var queryObj = results.Current;
var parentId = (uint)queryObj["ParentProcessId"];
var parent = Process.GetProcessById((int)parentId);
bool isInVisualStudio = parent.ProcessName.ToLower() == "msvsmon";

This even allows us to dispense with call to Debugger.IsAttached, since if the parent process is the debugger than it must be attached.

I would have been more than happy to accept Hans' answer but he made it only as a comment. Therefore I am posting the answer in case someone else needs it but freely and very gratefully acknowledge that the answer came almost entirely from Hans Passant.

oldcoder
  • 342
  • 2
  • 12