void AddBreakpoint(BreakpointBookmark bookmark) { Breakpoint breakpoint = debugger.AddBreakpoint(bookmark.FileName, null, bookmark.LineNumber + 1, 0, bookmark.IsEnabled); MethodInvoker setBookmarkColor = delegate { if (debugger.Processes.Count == 0) { bookmark.IsHealthy = true; bookmark.Tooltip = null; } else if (!breakpoint.IsSet) { bookmark.IsHealthy = false; bookmark.Tooltip = "Breakpoint was not found in any loaded modules"; } else if (breakpoint.OriginalLocation.CheckSum == null) { bookmark.IsHealthy = true; bookmark.Tooltip = null; } else { byte[] fileMD5; TextEditorDisplayBindingWrapper file = FileService.GetOpenFile(bookmark.FileName) as TextEditorDisplayBindingWrapper; if (file != null) { byte[] fileContent = Encoding.UTF8.GetBytesWithPreamble(file.Text); fileMD5 = new MD5CryptoServiceProvider().ComputeHash(fileContent); } else { fileMD5 = new MD5CryptoServiceProvider().ComputeHash(File.ReadAllBytes(bookmark.FileName)); } if (Compare(fileMD5, breakpoint.OriginalLocation.CheckSum)) { bookmark.IsHealthy = true; bookmark.Tooltip = null; } else { bookmark.IsHealthy = false; bookmark.Tooltip = "Check sum or file does not match to the original"; } } }; // event handlers on bookmark and breakpoint don't need deregistration bookmark.IsEnabledChanged += delegate { breakpoint.Enabled = bookmark.IsEnabled; }; breakpoint.Set += delegate { setBookmarkColor(); }; setBookmarkColor(); EventHandler <ProcessEventArgs> bp_debugger_ProcessStarted = (sender, e) => { setBookmarkColor(); // User can change line number by inserting or deleting lines breakpoint.Line = bookmark.LineNumber + 1; }; EventHandler <ProcessEventArgs> bp_debugger_ProcessExited = (sender, e) => { setBookmarkColor(); }; EventHandler <BreakpointEventArgs> bp_debugger_BreakpointHit = new EventHandler <BreakpointEventArgs>( delegate(object sender, BreakpointEventArgs e) { LoggingService.Debug(bookmark.Action + " " + bookmark.ScriptLanguage + " " + bookmark.Condition); switch (bookmark.Action) { case BreakpointAction.Break: break; case BreakpointAction.Condition: if (Evaluate(bookmark.Condition, bookmark.ScriptLanguage)) { DebuggerService.PrintDebugMessage(string.Format(StringParser.Parse("${res:MainWindow.Windows.Debug.Conditional.Breakpoints.BreakpointHitAtBecause}") + "\n", bookmark.LineNumber + 1, bookmark.FileName, bookmark.Condition)); } else { this.debuggedProcess.AsyncContinue(); } break; case BreakpointAction.Trace: DebuggerService.PrintDebugMessage(string.Format(StringParser.Parse("${res:MainWindow.Windows.Debug.Conditional.Breakpoints.BreakpointHitAt}") + "\n", bookmark.LineNumber + 1, bookmark.FileName)); break; } }); BookmarkEventHandler bp_bookmarkManager_Removed = null; bp_bookmarkManager_Removed = (sender, e) => { if (bookmark == e.Bookmark) { debugger.RemoveBreakpoint(breakpoint); // unregister the events debugger.ProcessStarted -= bp_debugger_ProcessStarted; debugger.ProcessExited -= bp_debugger_ProcessExited; breakpoint.Hit -= bp_debugger_BreakpointHit; BookmarkManager.Removed -= bp_bookmarkManager_Removed; } }; // register the events debugger.ProcessStarted += bp_debugger_ProcessStarted; debugger.ProcessExited += bp_debugger_ProcessExited; breakpoint.Hit += bp_debugger_BreakpointHit; BookmarkManager.Removed += bp_bookmarkManager_Removed; }