Check if a particualar Visual Studio instance is open programatically

Soumabha Sarkar 41 Reputation points
2022-03-10T08:47:53.533+00:00

We are developing an extension and as a part of the extension, we need to find out if any particular VS instance is open with help of a standalone exe file. For VS2019, we used 32bit version of Restart Manager library that comes with VS2019 installation for developing this standalone exe. But for VS2022, we need 64bit version of this library and VS2022 installation does not come with a 64bit version of Restart Manager library.

We tried to use process list but it is error prone while it comes to software update.

In short, we need the functionality of Visual Studio Installer where it notify users about the open session of any Visual Studio Instance.

Visual Studio
Visual Studio
A family of Microsoft suites of integrated development tools for building applications for Windows, the web and mobile devices.
4,638 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,302 questions
Visual Studio Debugging
Visual Studio Debugging
Visual Studio: A family of Microsoft suites of integrated development tools for building applications for Windows, the web and mobile devices.Debugging: The act or process of detecting, locating, and correcting logical or syntactical errors in a program or malfunctions in hardware. In hardware contexts, the term troubleshoot is the term more frequently used, especially if the problem is major.
944 questions
Visual Studio Setup
Visual Studio Setup
Visual Studio: A family of Microsoft suites of integrated development tools for building applications for Windows, the web and mobile devices.Setup: The procedures involved in preparing a software program or application to operate within a computer or mobile device.
971 questions
{count} votes

1 answer

Sort by: Most helpful
  1. Castorix31 81,831 Reputation points
    2022-03-10T11:00:42.807+00:00

    You can get VS instances from the IRunningObjectTable

    This test works for me with VS2022 on Windows 10 21H1 =>

    // Add reference to : "C:\Program Files (x86)\Common Files\microsoft shared\MSEnv\PublicAssemblies\envdte.dll"
    using EnvDTE;
    

    Main loop :

    System.Runtime.InteropServices.ComTypes.IRunningObjectTable prot = null;
    HRESULT hr = GetRunningObjectTable(0, out prot);
    if (hr == HRESULT.S_OK)
    {
        System.Runtime.InteropServices.ComTypes.IBindCtx pbc = null;
        hr = CreateBindCtx(0, out pbc);
        System.Runtime.InteropServices.ComTypes.IEnumMoniker penumMk = null;
        prot.EnumRunning(out penumMk);
        System.Runtime.InteropServices.ComTypes.IMoniker[] pmk = new System.Runtime.InteropServices.ComTypes.IMoniker[1];
        IntPtr celt = IntPtr.Zero; 
        while (penumMk.Next(1, pmk, celt) == (int)HRESULT.S_OK)
        {
            string sDisplayName;
            pmk[0].GetDisplayName(pbc, null, out sDisplayName);
            if (sDisplayName.StartsWith("!VisualStudio"))
            {
                Console.WriteLine("Name : {0}", sDisplayName);
                object pUnk = null;
                hr = (HRESULT)prot.GetObject(pmk[0], out pUnk);
                if (hr == HRESULT.S_OK)
                {
                    _DTE pDTE = (_DTE)pUnk;
                    var mw = pDTE.MainWindow;
                    string sCaption = mw.Caption;
                    Console.WriteLine("Caption : {0}", sCaption);
                }
            }
        }
    }
    

    Declarations :

        public enum HRESULT : int
        {
            S_OK = 0,
            S_FALSE = 1,
            E_NOINTERFACE = unchecked((int)0x80004002),
            E_NOTIMPL = unchecked((int)0x80004001),
            E_FAIL = unchecked((int)0x80004005)
        }
    
        [DllImport("Ole32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern HRESULT GetRunningObjectTable(uint reserved, out System.Runtime.InteropServices.ComTypes.IRunningObjectTable pprot);
    
        [DllImport("Ole32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern HRESULT CreateBindCtx(uint reserved, out System.Runtime.InteropServices.ComTypes.IBindCtx ppbc);