简体   繁体   中英

How can I check if a process was started by Visual Studio > 2015

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?

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 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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM