/// <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 another TESTER to close the IPC channel so it can use it.
 /// </summary>
 public void Abort()
 {
     using (var evt = TesterDebugAttacherShared.GetNotifyEvent()) {
         if (evt != null)
         {
             evt.Set();
         }
     }
 }