async void DebuggingChanged(object sender, UIContextChangedEventArgs e) { if (e.Activated) { // We just started debugging, so publish the DebugAttacher class // and wait for a request. IChannel channel; EventWaitHandle notifyEvent; if (!TesterDebugAttacherShared.OpenChannel(10, out channel, out notifyEvent)) { return; } try { // Wait for the signal that we've either attached to our // client, or we've aborted the wait. All we do after this // is unregister the channel, so it doesn't really matter // which it is. var signaled = await Task.Run(() => notifyEvent.WaitOne(TimeSpan.FromSeconds(30))); } finally { notifyEvent.Dispose(); TesterDebugAttacherShared.CloseChannel(channel); } } else { // We were debugging, but now we've stopped // Abort waiting in case we stopped within the timeout TesterDebugAttacherShared.CancelWait(); } }
/// <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(); } } }