/// <summary>
        /// Called by the EXECUTION ENGINE to attach this TESTER to the newly
        /// started TESTEE.
        /// </summary>
        /// <returns>True if the attach occurred; otherwise, false.</returns>
        public bool AttachToProcess(int processId, bool mixedMode)
        {
            using (var evt = TesterDebugAttacherShared.GetNotifyEvent()) {
                if (evt == null)
                {
                    return(false);
                }

                var debug = ServiceProvider.GlobalProvider.GetService(typeof(SVsShellDebugger)) as IVsDebugger3;

                var targets = new VsDebugTargetInfo3[1];
                var results = new VsDebugTargetProcessInfo[1];

                targets[0].bstrExe = string.Format("\0{0:X}", processId);
                targets[0].dlo     = (uint)DEBUG_LAUNCH_OPERATION.DLO_AlreadyRunning;
                targets[0].guidLaunchDebugEngine = Guid.Empty;
                targets[0].dwDebugEngineCount    = 1;

                var engine = mixedMode ?
                             VSConstants.DebugEnginesGuids.ManagedAndNative_guid :
                             VSConstants.DebugEnginesGuids.ManagedOnly_guid;

                var pGuids = Marshal.AllocCoTaskMem(Marshal.SizeOf(engine));
                try {
                    Marshal.StructureToPtr(engine, pGuids, false);
                    targets[0].pDebugEngines = pGuids;

                    ErrorHandler.ThrowOnFailure(debug.LaunchDebugTargets3((uint)targets.Length, targets, results));
                } finally {
                    Marshal.FreeCoTaskMem(pGuids);
                }
                evt.Set();
            }
            return(true);
        }
        /// <summary>
        /// Called by the EXECUTION ENGINE to attach this TESTER to the newly
        /// started TESTEE.
        /// </summary>
        /// <returns>True if the attach occurred; otherwise, false.</returns>
        public bool AttachToProcess(int processId, bool mixedMode)
        {
            using (var evt = TesterDebugAttacherShared.GetNotifyEvent()) {
                if (evt == null) {
                    return false;
                }

                var debug = ServiceProvider.GlobalProvider.GetService(typeof(SVsShellDebugger)) as IVsDebugger3;

                var targets = new VsDebugTargetInfo3[1];
                var results = new VsDebugTargetProcessInfo[1];

                targets[0].bstrExe = string.Format("\0{0:X}", processId);
                targets[0].dlo = (uint)DEBUG_LAUNCH_OPERATION.DLO_AlreadyRunning;
                targets[0].guidLaunchDebugEngine = Guid.Empty;
                targets[0].dwDebugEngineCount = 1;

                var engine = mixedMode ?
                    VSConstants.DebugEnginesGuids.ManagedAndNative_guid :
                    VSConstants.DebugEnginesGuids.ManagedOnly_guid;

                var pGuids = Marshal.AllocCoTaskMem(Marshal.SizeOf(engine));
                try {
                    Marshal.StructureToPtr(engine, pGuids, false);
                    targets[0].pDebugEngines = pGuids;

                    ErrorHandler.ThrowOnFailure(debug.LaunchDebugTargets3((uint)targets.Length, targets, results));
                } finally {
                    Marshal.FreeCoTaskMem(pGuids);
                }
                evt.Set();
            }
            return true;
        }
        private void AttachToRemoteProcess(string machineName, string processName)
        {
            IVsDebugger3 vsDebugger = Package.GetGlobalService(typeof(IVsDebugger)) as IVsDebugger3;

            VsDebugTargetInfo3[]       arrDebugTargetInfo   = new VsDebugTargetInfo3[1];
            VsDebugTargetProcessInfo[] arrTargetProcessInfo = new VsDebugTargetProcessInfo[1];

            arrDebugTargetInfo[0].bstrExe           = processName;
            arrDebugTargetInfo[0].bstrRemoteMachine = machineName;

            arrDebugTargetInfo[0].dlo = (uint)DEBUG_LAUNCH_OPERATION.DLO_AlreadyRunning;
            arrDebugTargetInfo[0].guidLaunchDebugEngine = Guid.Empty;
            arrDebugTargetInfo[0].dwDebugEngineCount    = 1;

            Guid   guidDbgEngine = VSConstants.DebugEnginesGuids.ManagedAndNative_guid;
            IntPtr pGuids        = Marshal.AllocCoTaskMem(Marshal.SizeOf(guidDbgEngine));

            Marshal.StructureToPtr(guidDbgEngine, pGuids, false);
            arrDebugTargetInfo[0].pDebugEngines = pGuids;
            int hr = vsDebugger.LaunchDebugTargets3(1, arrDebugTargetInfo, arrTargetProcessInfo);

            // cleanup
            if (pGuids != IntPtr.Zero)
            {
                Marshal.FreeCoTaskMem(pGuids);
            }
        }