{"id":392,"date":"2011-01-31T09:00:00","date_gmt":"2011-01-31T16:00:00","guid":{"rendered":"http:\/\/jameskovacs.com\/2011\/01\/28\/easier-debugging-with-resharper-and-the-clipboard\/"},"modified":"2011-01-31T09:00:00","modified_gmt":"2011-01-31T16:00:00","slug":"easier-debugging-with-resharper-and-the-clipboard","status":"publish","type":"post","link":"https:\/\/www.jameskovacs.com\/index.php\/2011\/01\/31\/easier-debugging-with-resharper-and-the-clipboard\/","title":{"rendered":"Easier Debugging with ReSharper and the Clipboard"},"content":{"rendered":"<p>We\u2019ve all done it at one point or another. Our application throws an exception and we start wading through a standard Windows error dialog or a log file to examine the exception and stack trace. If you\u2019re a ReSharper Jedi, you\u2019ve probably copied the exception and stack trace to the clipboard and hit CTRL-SHIFT-E (IDEA) or CTRL-E, T (VS) in Visual Studio to launch ReSharper\u2019s Stack Trace Explorer. (If you have\u2019t, you\u2019ll see the Stack Trace Explorer in just a second.)<\/p>\n<p>Let me show you an easier way that works well on desktop or Silverlight apps. I\u2019ll use Silverlight for demo purposes, but the same technique works with WPF and WinForms. First we need to hook up a global error handler:<\/p>\n<pre class=\"brush: csharp;\">public MainPage() {\n    InitializeComponent();\n    Application.Current.UnhandledException += HandleApplicationUnhandledException;\n}\n\nprivate static void HandleApplicationUnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e) {\n    if(Debugger.IsAttached) {\n        Clipboard.SetText(e.ExceptionObject.ToString());\n    }\n    e.Handled = false;\n}<\/pre>\n<p>Please note that this is demo code and I\u2019m simply hooking this up in the code behind. In a larger application, I would typically publish an ErrorOccurred message to my application\u2019s message bus and register a listener that would contain the code in HandleApplicationUnhandledException.<\/p>\n<p>Notice that I\u2019m checking whether a debugger is attached. If so, I place the contents of the System.Exception (or derived exception) on the clipboard. (Clipboard is in the System.Windows namespace for Silverlight and WPF apps, but there is an identically-named class in System.Windows.Forms.) The reason that I\u2019m checking whether a debugger is attached is so that end-users don\u2019t get the clipboards spammed with exception text. You could conditionally compile the code so that production builds don\u2019t contain it, but personally I like having the code in production too. It means that I can grab an old build, attach a debugger, and get the same exceptions that the end users are getting.<\/p>\n<p>Now that the exception and stack trace is on the clipboard, I jump over to Visual Studio and press CTRL-SHIFT-E (IDEA) or CTRL-E, T (VS). I am immediately presented with ReSharper\u2019s Stack Trace Explorer as ReSharper is smart enough to grab the current clipboard contents to display:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px\" title=\"StackTraceExplorer\" border=\"0\" alt=\"StackTraceExplorer\" src=\"https:\/\/www.jameskovacs.com\/wp-content\/uploads\/2011\/01\/StackTraceExplorer.png\" width=\"480\" height=\"481\" \/><\/p>\n<p>The advantage here is fictionless debugging as you no longer have to find, select, and copy the exception and stack trace to the clipboard. It\u2019s there for you automatically. As soon as you hit an exception, simply jump to Visual Studio and press CTRL-SHIFT-E (IDEA) or CTRL-E, T (VS) and you\u2019re ready to find the problem. Also note that all the method names in the ReSharper\u2019s Stack Trace Explorer are hot links to the appropriate code file allowing for easy navigation of your code base, the .NET Framework, and third-party libraries.<\/p>\n<p>One quick note regarding Silverlight\u2026 Many modern browsers (e.g. FF4, IE8+, Chrome, \u2026) will run Silverlight in a separate process. So even when you launch with debugging (F5), you\u2019ll be attached to the browser process itself and not the child process that is hosting Silverlight. To correct this, simply go to Debug\u2026 Attach to Process\u2026 and find the hosting process where the type is Silverlight. (For FireFox 4, the hosting process is called plugin-container.exe. For IE8+ and Chrome, the hosting process is called iexplore.exe or chrome.exe, respectively. Just look for the one hosting Silverlight as noted under the \u201cType\u201d column.)<\/p>\n<p><a href=\"https:\/\/www.jameskovacs.com\/wp-content\/uploads\/2011\/01\/AttachToProcess.png\"><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px\" title=\"AttachToProcess\" border=\"0\" alt=\"AttachToProcess\" src=\"https:\/\/www.jameskovacs.com\/wp-content\/uploads\/2011\/01\/AttachToProcess_thumb.png\" width=\"640\" height=\"439\" \/><\/a><\/p>\n<p>Happy Debugging!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>We\u2019ve all done it at one point or another. Our application throws an exception and we start wading through a standard Windows error dialog or a log file to examine the exception and stack trace. If you\u2019re a ReSharper Jedi, you\u2019ve probably copied the exception and stack trace to the clipboard and hit CTRL-SHIFT-E (IDEA) [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,3],"tags":[],"class_list":["post-392","post","type-post","status-publish","format-standard","hentry","category-dotnetgeneral","category-dotnettools"],"_links":{"self":[{"href":"https:\/\/www.jameskovacs.com\/index.php\/wp-json\/wp\/v2\/posts\/392","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.jameskovacs.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.jameskovacs.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.jameskovacs.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.jameskovacs.com\/index.php\/wp-json\/wp\/v2\/comments?post=392"}],"version-history":[{"count":0,"href":"https:\/\/www.jameskovacs.com\/index.php\/wp-json\/wp\/v2\/posts\/392\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.jameskovacs.com\/index.php\/wp-json\/wp\/v2\/media?parent=392"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.jameskovacs.com\/index.php\/wp-json\/wp\/v2\/categories?post=392"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.jameskovacs.com\/index.php\/wp-json\/wp\/v2\/tags?post=392"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}