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.

Developer technologies | Visual Studio | Debugging
Developer technologies | Visual Studio | Setup
Developer technologies | Visual Studio | Other
Developer technologies | C#
{count} votes

1 answer

Sort by: Most helpful
  1. Castorix31 90,681 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);  
    

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.