Exemple #1
0
        private static DTE GetDTE(int processId)
        {
            MessageFilter.Register();

            var prefix = Process.GetProcessById(processId).ProcessName;

            if ("devenv".Equals(prefix, StringComparison.OrdinalIgnoreCase))
            {
                prefix = "VisualStudio";
            }

            string progId        = string.Format("!{0}.DTE.{1}:{2}", prefix, AssemblyVersionInfo.VSVersion, processId);
            object runningObject = null;

            IBindCtx            bindCtx      = null;
            IRunningObjectTable rot          = null;
            IEnumMoniker        enumMonikers = null;

            try {
                Marshal.ThrowExceptionForHR(CreateBindCtx(reserved: 0, ppbc: out bindCtx));
                bindCtx.GetRunningObjectTable(out rot);
                rot.EnumRunning(out enumMonikers);

                IMoniker[] moniker       = new IMoniker[1];
                uint       numberFetched = 0;
                while (enumMonikers.Next(1, moniker, out numberFetched) == 0)
                {
                    IMoniker runningObjectMoniker = moniker[0];

                    string name = null;

                    try {
                        if (runningObjectMoniker != null)
                        {
                            runningObjectMoniker.GetDisplayName(bindCtx, null, out name);
                        }
                    } catch (UnauthorizedAccessException) {
                        // Do nothing, there is something in the ROT that we do not have access to.
                    }

                    if (!string.IsNullOrEmpty(name) && string.Equals(name, progId, StringComparison.Ordinal))
                    {
                        rot.GetObject(runningObjectMoniker, out runningObject);
                        break;
                    }
                }
            } finally {
                if (enumMonikers != null)
                {
                    Marshal.ReleaseComObject(enumMonikers);
                }

                if (rot != null)
                {
                    Marshal.ReleaseComObject(rot);
                }

                if (bindCtx != null)
                {
                    Marshal.ReleaseComObject(bindCtx);
                }
            }

            return((DTE)runningObject);
        }
        private static DTE GetDTE(int processId)
        {
#if DEV15
            // VS 2017 doesn't install some assemblies to the GAC that are needed to work with the
            // debugger, and as the tests don't execute in the devenv.exe process, those assemblies
            // fail to load - so load them manually from PublicAssemblies.

            // Use the executable name, as this is only needed for the out of proc test execution
            // that may interact with the debugger (vstest.executionengine.x86.exe).
            if (!DTELoaded)
            {
                string currentProc = Process.GetCurrentProcess().MainModule.FileName;
                if (StringComparer.OrdinalIgnoreCase.Equals(
                        Path.GetFileName(currentProc), "vstest.executionengine.x86.exe"))
                {
                    string baseDir          = Path.GetDirectoryName(currentProc);
                    string publicAssemblies = Path.Combine(baseDir, "..\\..\\..\\PublicAssemblies");

                    Assembly.LoadFrom(Path.Combine(publicAssemblies, "Microsoft.VisualStudio.OLE.Interop.dll"));
                    Assembly.LoadFrom(Path.Combine(publicAssemblies, "envdte90.dll"));
                    Assembly.LoadFrom(Path.Combine(publicAssemblies, "envdte80.dll"));
                    Assembly.LoadFrom(Path.Combine(publicAssemblies, "envdte.dll"));
                }
                DTELoaded = true;
            }
#endif
            MessageFilter.Register();

            var prefix = Process.GetProcessById(processId).ProcessName;
            if ("devenv".Equals(prefix, StringComparison.OrdinalIgnoreCase))
            {
                prefix = "VisualStudio";
            }

            string progId        = string.Format("!{0}.DTE.{1}:{2}", prefix, AssemblyVersionInfo.VSVersion, processId);
            object runningObject = null;

            IBindCtx            bindCtx      = null;
            IRunningObjectTable rot          = null;
            IEnumMoniker        enumMonikers = null;

            try {
                Marshal.ThrowExceptionForHR(CreateBindCtx(reserved: 0, ppbc: out bindCtx));
                bindCtx.GetRunningObjectTable(out rot);
                rot.EnumRunning(out enumMonikers);

                IMoniker[] moniker       = new IMoniker[1];
                uint       numberFetched = 0;
                while (enumMonikers.Next(1, moniker, out numberFetched) == 0)
                {
                    IMoniker runningObjectMoniker = moniker[0];

                    string name = null;

                    try {
                        if (runningObjectMoniker != null)
                        {
                            runningObjectMoniker.GetDisplayName(bindCtx, null, out name);
                        }
                    } catch (UnauthorizedAccessException) {
                        // Do nothing, there is something in the ROT that we do not have access to.
                    }

                    if (!string.IsNullOrEmpty(name) && string.Equals(name, progId, StringComparison.Ordinal))
                    {
                        rot.GetObject(runningObjectMoniker, out runningObject);
                        break;
                    }
                }
            } finally {
                if (enumMonikers != null)
                {
                    Marshal.ReleaseComObject(enumMonikers);
                }

                if (rot != null)
                {
                    Marshal.ReleaseComObject(rot);
                }

                if (bindCtx != null)
                {
                    Marshal.ReleaseComObject(bindCtx);
                }
            }

            return((DTE)runningObject);
        }