<?xml version='1.0' encoding='UTF-8'?><rss xmlns:atom='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0' version='2.0'><channel><atom:id>tag:blogger.com,1999:blog-2180987757847974648</atom:id><lastBuildDate>Fri, 16 Mar 2012 08:10:26 +0000</lastBuildDate><category>C#</category><category>Visual Studio</category><category>Architecture</category><category>Ruby</category><category>ORM</category><category>NHibernate</category><category>Project Euler</category><category>F#</category><category>Windows</category><category>Christian</category><category>WinForms</category><category>Rake</category><category>.NET</category><title>blog.adamjcooper.com</title><description>Mostly on Software Development</description><link>http://blog.adamjcooper.com/</link><managingEditor>noreply@blogger.com (Adam Cooper)</managingEditor><generator>Blogger</generator><openSearch:totalResults>14</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-2180987757847974648.post-7589364475951464536</guid><pubDate>Wed, 04 May 2011 21:29:00 +0000</pubDate><atom:updated>2011-05-04T17:31:54.108-04:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>.NET</category><category domain='http://www.blogger.com/atom/ns#'>WinForms</category><category domain='http://www.blogger.com/atom/ns#'>Windows</category><category domain='http://www.blogger.com/atom/ns#'>C#</category><category domain='http://www.blogger.com/atom/ns#'>Visual Studio</category><title>Why is my exception being swallowed in my Form’s Load handler?</title><description>&lt;p&gt;So, you’ve got a WinForms app and you expect an exception to be thrown within your Form’s Load handler. Maybe you even deliberately throw one yourself. But when you start debugging, &lt;em&gt;the execution of your Load handler terminates at the point where the exception was thrown, but no exception is reported and your application keeps running!&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;This issue was baffling me for several hours today when a colleague of mine pointed me to &lt;a href="http://stackoverflow.com/questions/1583351/silent-failures-in-c-seemingly-unhandled-exceptions-that-does-not-crash-the-pro" target="_blank"&gt;a helpful post at StackOverflow that explains the problem&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;If these conditions are met:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;strong&gt;You are running on a 64-bit version of Windows &lt;/strong&gt;(whether your application is built for 32-bit or 64-bit doesn’t matter; only the bit depth of the OS) &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;You are building a WinForms app&lt;/strong&gt; &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;You are debugging the application with Visual Studio &lt;/strong&gt;(using default options for Exception catching) &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Your main form has a Load event handler&lt;/strong&gt; &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;During the execution of your Load handler, an exception occurs&lt;/strong&gt; &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Then:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;The exception will be silently swallowed by the system and, while your handler will not continue execution, your application will continue running&lt;/strong&gt;.If you wrap your handler code in a try/catch block, you can still explicitly catch any thrown exceptions. But if you don’t, &lt;strong&gt;you’ll never know anything went wrong&lt;/strong&gt;.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Note that &lt;em&gt;all &lt;/em&gt;of the conditions must be met. If, for instance, you run the application without debugging, then an unhandled exception still be correctly thrown.&lt;/p&gt;  &lt;p&gt;According to &lt;a href="http://connect.microsoft.com/VisualStudio/feedback/details/325742/exception-assistant-dialog-box-doesnt-appear-when-debugging-in-vb2008-express" target="_blank"&gt;this Microsoft Connect post&lt;/a&gt;, this has been a known issue with 64-bit Windows since 2008:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;This is a known issue on 64-bit OS platform. The reason is that the 64bit OS core does not allow user mode exception through kernal mode stacks. The exception is swallowed by OS sliently. That happens in FormLoad handler, because it is called in an OS callback. 32bits OS doesn't do this, so it doesn't repro there. &lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Paul Betts sheds &lt;a href="http://blog.paulbetts.org/index.php/2010/07/20/the-case-of-the-disappearing-onload-exception-user-mode-callback-exceptions-in-x64/" target="_blank"&gt;more technical light on what’s going on&lt;/a&gt;, although I believe his post addresses the swallowing of such exceptions even &lt;em&gt;without &lt;/em&gt;debugging, something that is supposed to have been resolved for Windows 7 SP1.&lt;/p&gt;  &lt;h2&gt;Workarounds&lt;/h2&gt;  &lt;p&gt;If you need the debugger to break during your load method, there are a few things you can do:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Break whenever a CLR Exception is thrown&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;You can optionally tell Visual Studio to break &lt;em&gt;whenever&lt;/em&gt; a CLR exception is thrown, even if it normally would have later been caught (via Debug… Exceptions… or Ctrl+Alt+E).&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_Frh-z7iin4w/TcHFLdrwjQI/AAAAAAAAA3A/6lm29j6iiSc/s1600-h/image%5B11%5D.png"&gt;&lt;img 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="image" border="0" alt="image" src="http://lh5.ggpht.com/_Frh-z7iin4w/TcHFLkIxGfI/AAAAAAAAA3E/D_otbL6KCRI/image_thumb%5B11%5D.png?imgmax=800" width="725" height="362" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The downside to this approach is that you may see a lot of “noise” about thrown exceptions that are eventually handled (although in some circumstances this is an invaluable tool to discover exceptions that are being thrown that shouldn’t be).&lt;/p&gt;  &lt;p&gt;You can catch exceptions in the other categories as well, but typically it’s the CLR exceptions you’ll be interested in.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Use the Application.ThreadException Handler as a Breakpoint&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;You can attach a handler to the Application.ThreadException event before running your app, and you can set a breakpoint within it to inspect the original exception that was thrown.&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:43c6e00c-2465-414b-8683-b32c8a15f905" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background-color: #000000; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap"&gt;&lt;span style="color:#cc7832"&gt;static&lt;/span&gt;&lt;span style="color:#ffffff"&gt; &lt;/span&gt;&lt;span style="color:#cc7832"&gt;class&lt;/span&gt;&lt;span style="color:#ffffff"&gt; &lt;/span&gt;&lt;span style="color:#ffc66d"&gt;Program&lt;/span&gt;&lt;br&gt;     &lt;span style="color:#ffffff"&gt;{&lt;/span&gt;&lt;br&gt;         &lt;span style="color:#ffffff"&gt;&lt;/span&gt;&lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br&gt;         &lt;span style="color:#ffffff"&gt;&lt;/span&gt;&lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; The main entry point for the application.&lt;/span&gt;&lt;br&gt;         &lt;span style="color:#ffffff"&gt;&lt;/span&gt;&lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br&gt;         &lt;span style="color:#ffffff"&gt;[&lt;/span&gt;&lt;span style="color:#ffc66d"&gt;STAThread&lt;/span&gt;&lt;span style="color:#ffffff"&gt;]&lt;/span&gt;&lt;br&gt;         &lt;span style="color:#ffffff"&gt;&lt;/span&gt;&lt;span style="color:#cc7832"&gt;static&lt;/span&gt;&lt;span style="color:#ffffff"&gt; &lt;/span&gt;&lt;span style="color:#cc7832"&gt;void&lt;/span&gt;&lt;span style="color:#ffffff"&gt; Main()&lt;/span&gt;&lt;br&gt;         &lt;span style="color:#ffffff"&gt;{&lt;/span&gt;&lt;br&gt;             &lt;span style="color:#ffffff"&gt;&lt;/span&gt;&lt;span style="color:#ffc66d"&gt;Application&lt;/span&gt;&lt;span style="color:#ffffff"&gt;.ThreadException += (o, args) =&amp;gt;&lt;/span&gt;&lt;br&gt;                 &lt;span style="color:#ffffff"&gt;{&lt;/span&gt;&lt;br&gt;                     &lt;span style="color:#ffffff"&gt;&lt;/span&gt;&lt;span style="color:#cc7832"&gt;var&lt;/span&gt;&lt;span style="color:#ffffff"&gt; x = args.Exception; &lt;/span&gt;&lt;span style="color:#808080"&gt;//Set breakpoint here to inspect args.Exception&lt;/span&gt;&lt;br&gt;                 &lt;span style="color:#ffffff"&gt;};&lt;/span&gt;&lt;br&gt; &lt;br&gt;             &lt;span style="color:#ffffff"&gt;&lt;/span&gt;&lt;span style="color:#ffc66d"&gt;Application&lt;/span&gt;&lt;span style="color:#ffffff"&gt;.EnableVisualStyles();&lt;/span&gt;&lt;br&gt;             &lt;span style="color:#ffffff"&gt;&lt;/span&gt;&lt;span style="color:#ffc66d"&gt;Application&lt;/span&gt;&lt;span style="color:#ffffff"&gt;.SetCompatibleTextRenderingDefault(&lt;/span&gt;&lt;span style="color:#cc7832"&gt;false&lt;/span&gt;&lt;span style="color:#ffffff"&gt;);&lt;/span&gt;&lt;br&gt;             &lt;span style="color:#ffffff"&gt;&lt;/span&gt;&lt;span style="color:#ffc66d"&gt;Application&lt;/span&gt;&lt;span style="color:#ffffff"&gt;.Run(&lt;/span&gt;&lt;span style="color:#cc7832"&gt;new&lt;/span&gt;&lt;span style="color:#ffffff"&gt; &lt;/span&gt;&lt;span style="color:#ffc66d"&gt;Form1&lt;/span&gt;&lt;span style="color:#ffffff"&gt;());&lt;/span&gt;&lt;br&gt;         &lt;span style="color:#ffffff"&gt;}&lt;/span&gt;&lt;br&gt;     &lt;span style="color:#ffffff"&gt;}&lt;/span&gt;&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;The downside to this approach is that you can get into this handler for all sorts of other things as well. But if you’re just trying to see what’s being thrown during startup, this will do it.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Use a 32-bit Version of Windows&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Yeah, it’s drastic, but if you’ve got VMs or other machines available, you can always debug on a 32-bit version of Windows.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2180987757847974648-7589364475951464536?l=blog.adamjcooper.com' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.adamjcooper.com/2011/05/why-is-my-exception-being-swallowed-in.html</link><author>noreply@blogger.com (Adam Cooper)</author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_Frh-z7iin4w/TcHFLkIxGfI/AAAAAAAAA3E/D_otbL6KCRI/s72-c/image_thumb%5B11%5D.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-2180987757847974648.post-6814331974130183764</guid><pubDate>Thu, 28 Apr 2011 03:54:00 +0000</pubDate><atom:updated>2011-04-28T00:03:01.459-04:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>.NET</category><category domain='http://www.blogger.com/atom/ns#'>Ruby</category><category domain='http://www.blogger.com/atom/ns#'>Rake</category><title>Rake for .NET in 5 Minutes</title><description>&lt;p&gt;There’s no question—when it comes to writing build scripts, I’ll take rake over just about anything. Especially anything that requires defining a &lt;em&gt;script &lt;/em&gt;using declarative markup (I’m looking at you, MSBuild and NAnt).&lt;/p&gt;  &lt;p&gt;If you want to build .NET projects with Rake, here’s the fastest way to get started with Ruby and Rake on a Windows machine (you can skip to the end for an even shorter list).&lt;/p&gt;  &lt;h2&gt;Install Ruby 1.9&lt;/h2&gt;  &lt;p&gt;Visit &lt;a href="http://rubyinstaller.org/downloads/"&gt;http://rubyinstaller.org/downloads/&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://rubyinstaller.org/downloads/"&gt;&lt;img 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="image" border="0" alt="image" src="http://lh6.ggpht.com/_Frh-z7iin4w/TbjlBtCrwUI/AAAAAAAAA2c/AqMmnmjhqmo/image%5B19%5D.png?imgmax=800" width="240" height="161" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Download the latest Ruby 1.9 installer:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_Frh-z7iin4w/TbjlBtRJO9I/AAAAAAAAA2g/03vNoFsLu2U/s1600-h/image%5B14%5D.png"&gt;&lt;img 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="image" border="0" alt="image" src="http://lh6.ggpht.com/_Frh-z7iin4w/TbjlB49iNkI/AAAAAAAAA2k/K0U0-oO0TYk/image_thumb%5B8%5D.png?imgmax=800" width="188" height="128" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Run the installer.&lt;/p&gt;  &lt;p&gt;&lt;font style="background-color: #ffff00"&gt;I recommend checking the option to add Ruby executables to your PATH.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_Frh-z7iin4w/TbjlCI7bPRI/AAAAAAAAA2o/omjzHor8UGM/s1600-h/image%5B25%5D.png"&gt;&lt;img 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="image" border="0" alt="image" src="http://lh3.ggpht.com/_Frh-z7iin4w/TbjlCUZ5FlI/AAAAAAAAA2s/jOcXhH473rU/image_thumb%5B14%5D.png?imgmax=800" width="503" height="388" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h2&gt;&lt;/h2&gt;  &lt;h2&gt;Install DevKit&lt;/h2&gt;  &lt;p&gt;Ruby libraries are called gems. They can be installed and uninstalled from your system as easily as adding and removing an app from an iPhone. Usually.&lt;/p&gt;  &lt;p&gt;Some gems come with source code in a language other than Ruby, such as C or C++, and they assume that they’ll be installed on a Unix or Linux style machine system where tools like make, gcc, and sh are present. Naturally, these gems don’t install so well on Windows. DevKit fixes that.&lt;/p&gt;  &lt;p&gt;Download the DevKit self-extracting archive from the same page you downloaded the Ruby installer: &lt;a href="http://rubyinstaller.org/downloads/"&gt;http://rubyinstaller.org/downloads/&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_Frh-z7iin4w/TbjlCupYUsI/AAAAAAAAA2w/fQ3cw67VjtI/s1600-h/image%5B24%5D.png"&gt;&lt;img 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="image" border="0" alt="image" src="http://lh5.ggpht.com/_Frh-z7iin4w/TbjlC2zdTWI/AAAAAAAAA20/8PmbqxMn0zQ/image_thumb%5B13%5D.png?imgmax=800" width="324" height="76" /&gt;&lt;/a&gt;&lt;/p&gt;          &lt;p&gt;Run the DevKit executable.&lt;/p&gt;  &lt;p&gt;When the dialog asks where to extract to, &lt;font style="background-color: #ffff00"&gt;change the folder to &lt;strong&gt;C:\DevKit &lt;/strong&gt;&lt;/font&gt;(just consider this the DevKit installation directory).&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_Frh-z7iin4w/TbjlDNo-W4I/AAAAAAAAA24/wM9n3E08Uos/s1600-h/image%5B31%5D.png"&gt;&lt;img 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="image" border="0" alt="image" src="http://lh5.ggpht.com/_Frh-z7iin4w/TbjlDavPAKI/AAAAAAAAA28/Ri83OXemUkk/image_thumb%5B21%5D.png?imgmax=800" width="361" height="167" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Open a command prompt and do the following:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font face="Courier New"&gt;cd \DevKit&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font face="Courier New"&gt;ruby dk.rb init&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font face="Courier New"&gt;ruby dk.rb install&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Then, to make sure it installed correctly, do:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&lt;strong&gt;gem install rdiscount --platform=ruby&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;If all is well, you should see the following line while rdiscount is being installed:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;Temporarily enhancing PATH to include DevKit...&lt;/font&gt;&lt;/p&gt;  &lt;h2&gt;Update the Gem System&lt;/h2&gt;  &lt;p&gt;At the command prompt:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font face="Courier New"&gt;gem update --system&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This will update the gem system to the latest available version.&lt;/p&gt;  &lt;h2&gt;Install Gems&lt;/h2&gt;  &lt;h3&gt;faster_require&lt;/h3&gt;  &lt;p&gt;&lt;strong&gt;&lt;font face="Courier New"&gt;gem install faster_require&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This little gem speeds up the performance of the ruby “require” statement on Windows. In some cases, quite a lot. I always include it on any Windows machine I use.&lt;/p&gt;  &lt;h3&gt;rake&lt;/h3&gt;  &lt;p&gt;&lt;strong&gt;&lt;font face="Courier New"&gt;gem install rake&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This is what we’re after, after all.&lt;/p&gt;  &lt;h3&gt;albacore&lt;/h3&gt;  &lt;p&gt;&lt;strong&gt;&lt;font face="Courier New"&gt;gem install albacore&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;h2&gt;&lt;/h2&gt;  &lt;p&gt;&lt;a href="https://github.com/derickbailey/Albacore/wiki"&gt;Albacore&lt;/a&gt; is a gem with a set of rake tasks that help with building .NET projects, including a task for executing msbuild which you can use to easily build a Visual Studio .sln file.&lt;/p&gt;  &lt;h2&gt;&lt;/h2&gt;  &lt;h2&gt;Done!&lt;/h2&gt;  &lt;p&gt;That’s it. You’re ready to start building your .NET projects with rake on Windows.&lt;/p&gt;  &lt;h2&gt;Recap: The Short List&lt;/h2&gt;  &lt;p&gt;Here’s the shorter list:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Download and install the latest Ruby from &lt;a href="http://rubyinstaller.org/downloads"&gt;http://rubyinstaller.org/downloads&lt;/a&gt;. Include Ruby executables in PATH.&lt;/li&gt;    &lt;li&gt;Download DevKit from &lt;a href="http://rubyinstaller.org/downloads"&gt;http://rubyinstaller.org/downloads&lt;/a&gt;. Extract to C:\DevKit&lt;/li&gt;    &lt;li&gt;Install DevKit&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;&lt;strong&gt;&lt;font face="Courier New"&gt;cd \DevKit&lt;/font&gt;&lt;/strong&gt;&lt;/li&gt;      &lt;li&gt;&lt;strong&gt;&lt;font face="Courier New"&gt;ruby dk.rb init&lt;/font&gt;&lt;/strong&gt;&lt;/li&gt;      &lt;li&gt;&lt;strong&gt;&lt;font face="Courier New"&gt;ruby dk.rb install&lt;/font&gt;&lt;/strong&gt;&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;Verify DevKit install&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;&lt;strong&gt;&lt;font face="Courier New"&gt;gem install rdiscount --platform=ruby&lt;/font&gt;&lt;/strong&gt;&lt;/li&gt;      &lt;li&gt;&lt;font face="Courier New"&gt;&lt;font face="Trebuchet MS"&gt;Should see: &lt;/font&gt;&lt;font face="Courier New"&gt;Temporarily enhancing PATH to include DevKit...&lt;/font&gt;&lt;/font&gt;&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;Update gem system&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;&lt;font face="Courier New"&gt;&lt;strong&gt;gem update --system&lt;/strong&gt;&lt;/font&gt;&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;Install gems&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;&lt;font face="Courier New"&gt;&lt;strong&gt;gem install faster_require&lt;/strong&gt;&lt;/font&gt;&lt;/li&gt;      &lt;li&gt;&lt;font face="Courier New"&gt;&lt;strong&gt;gem install rake&lt;/strong&gt;&lt;/font&gt;&lt;/li&gt;      &lt;li&gt;&lt;font face="Courier New"&gt;&lt;strong&gt;gem install albacore&lt;/strong&gt;&lt;/font&gt;&lt;/li&gt;   &lt;/ul&gt; &lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2180987757847974648-6814331974130183764?l=blog.adamjcooper.com' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.adamjcooper.com/2011/04/rake-for-net-in-5-minutes.html</link><author>noreply@blogger.com (Adam Cooper)</author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_Frh-z7iin4w/TbjlBtCrwUI/AAAAAAAAA2c/AqMmnmjhqmo/s72-c/image%5B19%5D.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-2180987757847974648.post-7541175110513075470</guid><pubDate>Wed, 09 Mar 2011 16:48:00 +0000</pubDate><atom:updated>2011-03-09T11:48:32.801-05:00</atom:updated><title>Bad Programmers Will Doom Your Company</title><description>&lt;p&gt;In technology, once you have bad programmers, you’re doomed. I can’t think of an instance where a company has sunk into technical mediocrity and recovered. Good programmers want to work with other good programmers. So once the quality of programmers at your company starts to drop, you enter a death spiral from which there is no recovery.&lt;/p&gt;  &lt;p&gt;- Paul Graham, &lt;em&gt;&lt;a href="http://www.paulgraham.com/yahoo.html" target="_blank"&gt;What Happened to Yahoo&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2180987757847974648-7541175110513075470?l=blog.adamjcooper.com' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.adamjcooper.com/2011/03/bad-programmers-will-doom-your-company.html</link><author>noreply@blogger.com (Adam Cooper)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-2180987757847974648.post-1866355394248665646</guid><pubDate>Sat, 29 Jan 2011 11:43:00 +0000</pubDate><atom:updated>2011-01-29T06:43:57.991-05:00</atom:updated><title>How to Open the Classic Logon Screen from XP’s Welcome Screen</title><description>&lt;p&gt;So, &lt;a href="http://support.microsoft.com/kb/917556" target="_blank"&gt;there’s this wonderful “feature” for Windows XP that, when you logoff, the password boxes on the Welcome screen don’t actually accept keyboard input&lt;/a&gt; (this was affecting me with a clean install of XP with SP3, 32-bit).&lt;/p&gt;  &lt;p&gt;Did you know there’s a backdoor to bypass the Welcome screen and use the Classic logon dialog instead? &lt;/p&gt;  &lt;p&gt;Just &lt;strong&gt;press Ctrl+Alt+Delete twice&lt;/strong&gt;, and you’re in business:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_Frh-z7iin4w/TUP9ek1zX4I/AAAAAAAAA2Q/StXdcFXoyP0/s1600-h/logon%5B6%5D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="logon" border="0" alt="logon" src="http://lh4.ggpht.com/_Frh-z7iin4w/TUP9fK0wQoI/AAAAAAAAA2U/ecwYnd9kti4/logon_thumb%5B9%5D.png?imgmax=800" width="421" height="246" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2180987757847974648-1866355394248665646?l=blog.adamjcooper.com' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.adamjcooper.com/2011/01/how-to-open-classic-logon-screen-from.html</link><author>noreply@blogger.com (Adam Cooper)</author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_Frh-z7iin4w/TUP9fK0wQoI/AAAAAAAAA2U/ecwYnd9kti4/s72-c/logon_thumb%5B9%5D.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-2180987757847974648.post-4437130178503588009</guid><pubDate>Sat, 29 Jan 2011 11:29:00 +0000</pubDate><atom:updated>2011-01-29T06:29:45.006-05:00</atom:updated><title>How to Check that Windows XP is Activated</title><description>&lt;p&gt;In the process of installing a bunch of VMs for our test lab, I couldn’t remember if I’d activated the XP machines or not. Normally you go to &lt;em&gt;Start… All Programs… Accessories… System Tools… Activate Windows&lt;/em&gt;, but &lt;em&gt;Activate Windows&lt;/em&gt; wasn’t there--which I now know means that activation has (likely) already happened.&lt;/p&gt;  &lt;p&gt;But if a missing &lt;em&gt;Activate Windows&lt;/em&gt; program icon isn’t enough to convince you that, indeed, your copy of XP is activated, here’s how you can really check:&lt;/p&gt;  &lt;p&gt;There is an executable that lives in &lt;font face="Courier New"&gt;&lt;strong&gt;C:\Windows\system32\oobe&lt;/strong&gt;&lt;/font&gt; called &lt;font face="Courier New"&gt;&lt;strong&gt;msoobe.exe&lt;/strong&gt;&lt;/font&gt; (I believe OOBE is for “&lt;a href="http://en.wikipedia.org/wiki/Out-of-box_experience" target="_blank"&gt;out-of-box experience&lt;/a&gt;”). You need to run that with the &lt;font face="Courier New"&gt;&lt;strong&gt;/a&lt;/strong&gt;&lt;/font&gt; option (I’m guessing for “activate”). When you do, the activation program will start let you know if you’re already activated.&lt;/p&gt;  &lt;p&gt;The easiest way to do this is via &lt;em&gt;Start… Run…&lt;/em&gt;, typing this into the box:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font face="Courier New"&gt;oobe/msoobe /a&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_Frh-z7iin4w/TUP6JLYXKcI/AAAAAAAAA2A/Sy55Vb7tPvw/s1600-h/Run%5B4%5D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Run" border="0" alt="Run" src="http://lh6.ggpht.com/_Frh-z7iin4w/TUP6JS89UPI/AAAAAAAAA2E/OoV0MsUN1G4/Run_thumb%5B2%5D.png?imgmax=800" width="357" height="229" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;If activated, you should see this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_Frh-z7iin4w/TUP6Ju-TyOI/AAAAAAAAA2I/m4JS7u0JPSs/s1600-h/Activated%5B4%5D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Activated" border="0" alt="Activated" src="http://lh5.ggpht.com/_Frh-z7iin4w/TUP6JzcmNDI/AAAAAAAAA2M/Q9wljSxwUsg/Activated_thumb%5B2%5D.png?imgmax=800" width="688" height="565" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2180987757847974648-4437130178503588009?l=blog.adamjcooper.com' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.adamjcooper.com/2011/01/how-to-check-that-windows-xp-is.html</link><author>noreply@blogger.com (Adam Cooper)</author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_Frh-z7iin4w/TUP6JS89UPI/AAAAAAAAA2E/OoV0MsUN1G4/s72-c/Run_thumb%5B2%5D.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-2180987757847974648.post-1248502090202817400</guid><pubDate>Wed, 19 Jan 2011 22:05:00 +0000</pubDate><atom:updated>2011-01-21T12:08:22.073-05:00</atom:updated><title>Create a Hotkey to Enable or Disable Your Second Monitor</title><description>&lt;p&gt;I’ve been doing some multi-touch testing with &lt;a href="http://multitouchvista.codeplex.com/" target="_blank"&gt;MultiTouchVista&lt;/a&gt;, a poor man’s multi-touch simulator. It lets you use multiple mice to simulate multiple touch points. Unfortunately, it doesn’t play well with multiple monitors (Whatever coordinate data exists for the touch points gets “squished” into the space of a single, primary monitor. So if you have 2 screens side by side and you “tap” at the midpoint of your desktop that falls on the edge of each screen, the actual tap will be applied to the midpoint of the first monitor.)&lt;/p&gt;  &lt;p&gt;No problem. I’ll disable my second monitor. &lt;/p&gt;  &lt;p&gt;Which is fine. &lt;/p&gt;  &lt;p&gt;Until I need to do some real work.&lt;/p&gt;  &lt;p&gt;No problem. I’ll just enable my second monitor. &lt;/p&gt;  &lt;p&gt;Let’s see… one click, two clicks, three clicks… no, wrong drop down, grr… four clicks, five clicks…&lt;/p&gt;  &lt;p&gt;This is ridiculous! I need a hotkey!&lt;/p&gt;  &lt;h2&gt;Toggle Your Second Monitor with AutoHotKey&lt;/h2&gt;  &lt;p&gt;This information is already out on the internet, but I couldn’t find it all in once place. So here goes.&lt;/p&gt;  &lt;p&gt;If you use &lt;a href="http://www.autohotkey.com/" target="_blank"&gt;autohotkey&lt;/a&gt;, there’s an easy way to define hotkeys to turn any of your monitors on and off.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;UPDATE: This has only worked for me with the original, non-unicode, “basic” version of AutoHotKey. If you’re using the new AutoHotKey_L, chances are this script won’t do anything for you.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;First, you’ll need a couple of monitor management functions (&lt;a href="http://www.autohotkey.com/forum/topic21800.html" target="_blank"&gt;which are separately buried in a old 2006 forum post, and provided courtesey of Lexikos&lt;/a&gt;). Don’t be intimidated by how long these are. Just shove them into a separate file, like MonitorManagement.ahk:&lt;/p&gt;  &lt;p&gt;&lt;font size="2" face="Courier New"&gt;; EnumDisplayDevices(Index [, ByRef Name, ByRef StateFlags ] )      &lt;br /&gt;;       &lt;br /&gt;; Index:&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; One-based index of device to get info for.       &lt;br /&gt;; DeviceName:&amp;#160;&amp;#160; [out] The name of the device.       &lt;br /&gt;; StateFlags:&amp;#160;&amp;#160; [out] Any reasonable combination of the following flags:       &lt;br /&gt;;&amp;#160;&amp;#160; 0x00000001&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; DISPLAY_DEVICE_ATTACHED_TO_DESKTOP       &lt;br /&gt;;&amp;#160;&amp;#160; 0x00000004&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; DISPLAY_DEVICE_PRIMARY_DEVICE       &lt;br /&gt;;&amp;#160;&amp;#160; 0x00000008&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; DISPLAY_DEVICE_MIRRORING_DRIVER       &lt;br /&gt;; DeviceKey:&amp;#160;&amp;#160;&amp;#160; [out] Path to the device's registry key relative to HKEY_LOCAL_MACHINE.       &lt;br /&gt;;       &lt;br /&gt;; Returns true if the display device exists, otherwise false.       &lt;br /&gt;;       &lt;br /&gt;/* Example 1 (requires EnableDisplayDevice()):       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; SecondaryDevice =       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; count = 0       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Loop {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if ! EnumDisplayDevices(A_Index, DeviceName, StateFlags)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; break       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if !(StateFlags &amp;amp; 8) ; not a pseudo-device       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (++count = 2) ; second device       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; break       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; if DeviceName       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; EnableDisplayDevice(DeviceName, -1) ; toggle       &lt;br /&gt;*/       &lt;br /&gt;/* Example 2:       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Loop {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if ! EnumDisplayDevices(A_Index, DeviceName, StateFlags)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; break       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (StateFlags &amp;amp; 4)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; text .= DeviceName &amp;quot; is the primary display device.`n&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; else if (StateFlags &amp;amp; 1)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; text .= &amp;quot;The desktop extends onto &amp;quot; DeviceName &amp;quot;.`n&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (StateFlags &amp;amp; 8)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; text .= DeviceName &amp;quot; is a pseudo-device.`n&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; MsgBox %text%       &lt;br /&gt;*/       &lt;br /&gt;EnumDisplayDevices(Index, ByRef DeviceName, ByRef StateFlags=&amp;quot;&amp;quot;, ByRef DeviceKey=&amp;quot;&amp;quot;)       &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ; DISPLAY_DEVICE DisplayDevice       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; VarSetCapacity(DisplayDevice, 424)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ; lpDisplayDevice.cb := sizeof(DISPLAY_DEVICE)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; NumPut(424, DisplayDevice, 0)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; VarSetCapacity(DeviceName, 32, 0)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; VarSetCapacity(DeviceKey, 128, 0)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ; For consistency, clear StateFlags in case of failure.       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; StateFlags = 0       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; if ! DllCall(&amp;quot;EnumDisplayDevices&amp;quot;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; , &amp;quot;UInt&amp;quot;, 0       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; , &amp;quot;UInt&amp;quot;, Index-1       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; , &amp;quot;UInt&amp;quot;, &amp;amp;DisplayDevice       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; , &amp;quot;UInt&amp;quot;, 0)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return false       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; StateFlags := NumGet(DisplayDevice, 164)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; DllCall(&amp;quot;lstrcpynA&amp;quot;, &amp;quot;Str&amp;quot;, DeviceName, &amp;quot;UInt&amp;quot;, &amp;amp;DisplayDevice+4,&amp;#160;&amp;#160; &amp;quot;int&amp;quot;, 32)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; DllCall(&amp;quot;lstrcpynA&amp;quot;, &amp;quot;Str&amp;quot;, DeviceKey,&amp;#160; &amp;quot;UInt&amp;quot;, &amp;amp;DisplayDevice+296, &amp;quot;int&amp;quot;, 128)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; if (SubStr(DeviceKey,1,18)=&amp;quot;\Registry\Machine\&amp;quot;)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; DeviceKey := SubStr(DeviceKey,19)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; return true       &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2" face="Courier New"&gt;; Enables, disables or toggles a display device.      &lt;br /&gt;;       &lt;br /&gt;; DeviceName:&amp;#160;&amp;#160; The name of the device, e.g. \\.\DISPLAY1       &lt;br /&gt;; Action:&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; The action to take.       &lt;br /&gt;;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 0&amp;#160;&amp;#160; Disable       &lt;br /&gt;;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 1&amp;#160;&amp;#160; Enable       &lt;br /&gt;;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; -1&amp;#160;&amp;#160; Toggle (may not be reliable if NoReset=true)       &lt;br /&gt;; NoReset:&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; If true, settings will be saved to the registry, but not applied.       &lt;br /&gt;;       &lt;br /&gt;; The following can be used to apply settings saved in the registry:       &lt;br /&gt;;&amp;#160;&amp;#160; DllCall(&amp;quot;ChangeDisplaySettings&amp;quot;, &amp;quot;uint&amp;quot;, 0, &amp;quot;uint&amp;quot;, 1)       &lt;br /&gt;;       &lt;br /&gt;; Return values:       &lt;br /&gt;;&amp;#160;&amp;#160;&amp;#160; DISP_CHANGE_SUCCESSFUL&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 0       &lt;br /&gt;;&amp;#160;&amp;#160;&amp;#160; DISP_CHANGE_RESTART&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 1       &lt;br /&gt;;&amp;#160;&amp;#160;&amp;#160; DISP_CHANGE_FAILED&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; -1       &lt;br /&gt;;&amp;#160;&amp;#160;&amp;#160; DISP_CHANGE_BADMODE&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; -2       &lt;br /&gt;;&amp;#160;&amp;#160;&amp;#160; DISP_CHANGE_NOTUPDATED&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; -3       &lt;br /&gt;;&amp;#160;&amp;#160;&amp;#160; DISP_CHANGE_BADFLAGS&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; -4       &lt;br /&gt;;&amp;#160;&amp;#160;&amp;#160; DISP_CHANGE_BADPARAM&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; -5       &lt;br /&gt;;       &lt;br /&gt;; Examples:       &lt;br /&gt;;&amp;#160;&amp;#160; ; disable display 2       &lt;br /&gt;;&amp;#160;&amp;#160;&amp;#160;&amp;#160; EnableDisplayDevice(&amp;quot;\\.\DISPLAY2&amp;quot;, 0)       &lt;br /&gt;;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Sleep, 10000       &lt;br /&gt;;       &lt;br /&gt;;&amp;#160;&amp;#160; ; simultaneously enable display 2 and disable display 1       &lt;br /&gt;;&amp;#160;&amp;#160;&amp;#160;&amp;#160; EnableDisplayDevice(&amp;quot;\\.\DISPLAY2&amp;quot;, 1, true)       &lt;br /&gt;;&amp;#160;&amp;#160;&amp;#160;&amp;#160; EnableDisplayDevice(&amp;quot;\\.\DISPLAY1&amp;quot;, 0)       &lt;br /&gt;;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Sleep, 10000       &lt;br /&gt;;       &lt;br /&gt;;&amp;#160;&amp;#160; ; ensure both are enabled       &lt;br /&gt;;&amp;#160;&amp;#160;&amp;#160;&amp;#160; EnableDisplayDevice(&amp;quot;\\.\DISPLAY2&amp;quot;, 1, true)       &lt;br /&gt;;&amp;#160;&amp;#160;&amp;#160;&amp;#160; EnableDisplayDevice(&amp;quot;\\.\DISPLAY1&amp;quot;)       &lt;br /&gt;;       &lt;br /&gt;; Note: DeviceNames may vary. Rather than hard-coding the device name,       &lt;br /&gt;;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; EnumDisplayDevices() should be used to enumerate the devices.       &lt;br /&gt;;       &lt;br /&gt;EnableDisplayDevice(DeviceName, Action=1, NoReset=false)       &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; if (Action = -1)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&amp;#160;&amp;#160; ; Determine if the display should be enabled or disabled.       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Loop {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if ! EnumDisplayDevices(A_Index, this_name, this_state)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; break       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (this_name = DeviceName) {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Action := !(this_state &amp;amp; 1) ; DISPLAY_DEVICE_ATTACHED_TO_DESKTOP       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; break       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ; If Action is still -1, an invalid DeviceName was specified.       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ; The script will attempt to enable the display device, but       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ; ChangeDisplaySettingsEx() will most likely return error -5.       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2" face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160; VarSetCapacity(devmode, 156, 0)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; NumPut(156, devmode, 36, &amp;quot;UShort&amp;quot;)&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2" face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160; ; Set DEVMODE.dmFields to indicate which fields are valid.      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; if (Action) ; Enable       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; NumPut(0x000020, devmode, 40)&amp;#160;&amp;#160; ; position={0,0}       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; else&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ; Disable       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; NumPut(0x180020, devmode, 40)&amp;#160;&amp;#160; ; width=0, height=0, position={0,0}&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2" face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160; ; Since CDS_NORESET is specified here, if NoReset=true, the user must      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ; manually call ChangeDisplaySettings(NULL,1) or restart the computer.       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; err := DllCall(&amp;quot;ChangeDisplaySettingsEx&amp;quot;, &amp;quot;str&amp;quot;, DeviceName       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; , &amp;quot;uint&amp;quot;, &amp;amp;devmode, &amp;quot;uint&amp;quot;, 0, &amp;quot;uint&amp;quot;, 0x10000001, &amp;quot;uint&amp;quot;, 0)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ; ChangeDisplaySettings() is called here for two reasons:       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ;&amp;#160;&amp;#160; - A restart is otherwise required to enable a secondary display device.       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; See: &lt;/font&gt;&lt;a href="http://support.microsoft.com/kb/308216"&gt;&lt;font size="2" face="Courier New"&gt;http://support.microsoft.com/kb/308216&lt;/font&gt;&lt;/a&gt;     &lt;br /&gt;&lt;font size="2" face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160; ;&amp;#160;&amp;#160; - Disabling display devices with just ChangeDisplaySettingsEx()      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ;&amp;#160;&amp;#160;&amp;#160;&amp;#160; tends to leave them turned on.       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; if (!err &amp;amp;&amp;amp; !NoReset)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; err := DllCall(&amp;quot;ChangeDisplaySettings&amp;quot;, &amp;quot;uint&amp;quot;, 0, &amp;quot;uint&amp;quot;, 1)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; return err       &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Now that you have that in a separate file, you can include it in your main ahk script and easily create a hotkey to toggle your second monitor (or your first or third or fourth). I’m currently using &lt;strong&gt;Ctrl–Backtick&lt;/strong&gt; to toggle my second monitor. Here’s how:&lt;/p&gt;  &lt;p&gt;&lt;font size="2" face="Courier New"&gt;#Include MonitorManagement.ahk      &lt;br /&gt;&lt;/font&gt;&lt;font size="2" face="Courier New"&gt;^`::EnableDisplayDevice(&amp;quot;\\.\DISPLAY2&amp;quot;, -1) ;toggle second monitor&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Modify to your liking.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2180987757847974648-1248502090202817400?l=blog.adamjcooper.com' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.adamjcooper.com/2011/01/create-hotkey-to-enable-or-disable-your.html</link><author>noreply@blogger.com (Adam Cooper)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-2180987757847974648.post-3317056377876008834</guid><pubDate>Fri, 03 Dec 2010 22:37:00 +0000</pubDate><atom:updated>2010-12-03T17:37:47.130-05:00</atom:updated><title>White button Click() not working? Set your build to x86.</title><description>&lt;p&gt;After about an hour of not being able to figure out why &lt;a href="http://white.codeplex.com" target="_blank"&gt;white&lt;/a&gt; wasn’t clicking on my buttons correctly, I finally stumbled across &lt;a href="http://white.codeplex.com/Thread/View.aspx?ThreadId=233211" target="_blank"&gt;this discussion&lt;/a&gt; that answered my question.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;If you’re on an x64 based system and you can’t get white to click, set your project to build for x86.&lt;/strong&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2180987757847974648-3317056377876008834?l=blog.adamjcooper.com' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.adamjcooper.com/2010/12/white-button-click-not-working-set-your.html</link><author>noreply@blogger.com (Adam Cooper)</author><thr:total>1</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-2180987757847974648.post-3579892065145363649</guid><pubDate>Fri, 03 Dec 2010 21:25:00 +0000</pubDate><atom:updated>2010-12-03T16:25:28.773-05:00</atom:updated><title>NonComVisibleBaseClass Exception When Debugging</title><description>&lt;p&gt;I was using &lt;a href="http://white.codeplex.com/" target="_blank"&gt;white&lt;/a&gt; to automate an installer UI today and I hit an unexpected NonComVisibleBaseClass exception while debugging. And, as I’m sure I’ll hit this again when I start on a new machine, I’m making a note to myself on how to get around this.&lt;/p&gt;  &lt;p&gt;Apparently this is a debug-only exception and all you need to do is tell Visual Studio that you aren’t interested in it:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Go to &lt;em&gt;Debug &lt;/em&gt;menu and choose &lt;em&gt;Exceptions…&lt;/em&gt;&lt;/li&gt;    &lt;li&gt;Find the NonComVisibleBaseClass exception&lt;/li&gt;    &lt;li&gt;Uncheck the Thrown option&lt;/li&gt;    &lt;li&gt;Click OK&lt;/li&gt; &lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2180987757847974648-3579892065145363649?l=blog.adamjcooper.com' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.adamjcooper.com/2010/12/noncomvisiblebaseclass-exception-when.html</link><author>noreply@blogger.com (Adam Cooper)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-2180987757847974648.post-5589500824427137152</guid><pubDate>Wed, 28 Jul 2010 14:07:00 +0000</pubDate><atom:updated>2010-07-28T10:07:28.157-04:00</atom:updated><title>Only a Programmer Can QA Your Programming Components</title><description>&lt;p&gt;It seems self-evident, but if you’re developing software components for use by other programmers—APIs, SDKs, reusable controls, whatever—if your QA is being done by non-programmers, you’re just pretending to do QA.&lt;/p&gt;  &lt;p&gt;I once worked for a company where the QA process for some of our software components went like this: a developer is told to create a new software component for use by other developers. However, since the QA team can’t test the component directly, the developer should also create a “tester application” that gives the QA team a nice, graphical way of exercising the module. Well, you can imagine what happened.&lt;/p&gt;  &lt;p&gt;The “tester application” the developer created only exposed a minimal, even partial, set of functionality supported by the component; enough for the QA team to do a sanity check and make sure the thing isn’t completely broken, but by no means a robust tool for ensuring quality. The reason for this isn’t necessarily because the developer was lazy or didn’t care (though that certainly doesn’t help). Rather, there is a more fundamental issue.&lt;/p&gt;  &lt;p&gt;When you ask a developer to create a UI for a non-programmer to test a component that is intended for use within a full-fledged programming environment, you’re essentially asking them to create a programming-language-to-user-interface mapper, a daunting task that will never be able to retain the full fidelity and power of the original programming environment. The dream of easy, graphical programming for the masses has been around for a long time, but it has yet to be attained and arguably never will be. There’s a reason professional development is still done using text-based grammars. Asking your developer to adorn the software component with a UI so the QA department can test it is like asking them to convert a diesel engine to use gasoline. It’s a lot of work that results in something very different than the original.&lt;/p&gt;  &lt;p&gt;Graphical testing tools a great for a quick sanity check that your QA team can run. But if you want real, comprehensive QA of your software components, you need a programmer to build an automated test suite that will exercise the component as it will actually be used.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2180987757847974648-5589500824427137152?l=blog.adamjcooper.com' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.adamjcooper.com/2010/07/only-programmer-can-qa-your-programming.html</link><author>noreply@blogger.com (Adam Cooper)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-2180987757847974648.post-2566427170775588271</guid><pubDate>Thu, 29 Apr 2010 04:33:00 +0000</pubDate><atom:updated>2010-04-29T00:33:38.667-04:00</atom:updated><title>string.KeepOnly</title><description>&lt;p&gt;Often when working with string data you need to strip away certain characters, filtering out some kernel that you’re interested in. For example, you may want to compare two phone numbers to see if they contain the same digits but you don’t care if the formatting is different. Or you may need to strip punctuation, or keep only letters, etc. &lt;/p&gt;  &lt;p&gt;Normally when you encounter a situation like this, we pull out a for loop and get the job done. But if you solve any one of the above scenarios &lt;em&gt;directly&lt;/em&gt; with an off-the-cuff for loop, you’ve just missed your chance to solve the more generic problem of keeping only certain types of characters in a string. And in C#, this is a solution we can easily package into an extension method:&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:b2107728-dc82-4a99-8457-2cdf32e47d13" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background-color: #ffffff; overflow: auto; padding: 2px 5px;"&gt;&lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; KeepOnly(&lt;span style="color:#0000ff"&gt;this&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; text, &lt;span style="color:#2b91af"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff"&gt;char&lt;/span&gt;, &lt;span style="color:#0000ff"&gt;bool&lt;/span&gt;&amp;gt; filter)&lt;br&gt; {&lt;br&gt;     &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (text == &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;)&lt;br&gt;         &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;;&lt;br&gt; &lt;br&gt;     &lt;span style="color:#0000ff"&gt;var&lt;/span&gt; sb = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;StringBuilder&lt;/span&gt;();&lt;br&gt; &lt;br&gt;     &lt;span style="color:#0000ff"&gt;foreach&lt;/span&gt; (&lt;span style="color:#0000ff"&gt;var&lt;/span&gt; c &lt;span style="color:#0000ff"&gt;in&lt;/span&gt; text)&lt;br&gt;     {&lt;br&gt;         &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (filter(c))&lt;br&gt;             sb.Append(c);&lt;br&gt;     }&lt;br&gt; &lt;br&gt;     &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; sb.ToString();&lt;br&gt; }&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;Armed with this simple method, we can now strip a string of anything but digits like this:&lt;/p&gt;  &lt;p&gt;   &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:18a9f071-816a-4aae-8fcd-4e87e2ddf0d9" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background-color: #ffffff; max-height: 300px; overflow: auto; padding: 2px 5px;"&gt;&lt;span style="color:#0000ff"&gt;var&lt;/span&gt; digits = &lt;span style="color:#a31515"&gt;&amp;quot;(123) 456-7890&amp;quot;&lt;/span&gt;.KeepOnly(c =&amp;gt; &lt;span style="color:#0000ff"&gt;char&lt;/span&gt;.IsDigit(c));&lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;/p&gt;  &lt;p&gt;Which can be packaged into an even more easy-to-read extension:&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:e0ee2849-a680-4fe0-be60-a776632aa592" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background-color: #ffffff; max-height: 300px; overflow: auto; padding: 2px 5px;"&gt;&lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; KeepOnlyDigits(&lt;span style="color:#0000ff"&gt;this&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; text)&lt;br&gt; {&lt;br&gt;     &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; text.KeepOnly(c =&amp;gt; &lt;span style="color:#0000ff"&gt;char&lt;/span&gt;.IsDigit(c));&lt;br&gt; }&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;Which can be used like this:&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:12e79851-45c1-405e-b42d-6c9e83aae505" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background-color: #ffffff; max-height: 300px; overflow: auto; padding: 2px 5px;"&gt;&lt;span style="color:#0000ff"&gt;var&lt;/span&gt; digits = &lt;span style="color:#a31515"&gt;&amp;quot;(123) 456-7890&amp;quot;&lt;/span&gt;.KeepOnlyDigits();&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;Which, I guarantee you, is a thousand times more readable and reusable than an inline for loop.&lt;/p&gt;  &lt;p&gt;In my &lt;a href="http://code.google.com/p/cooper-dotnet-util"&gt;.NET utility library&lt;/a&gt; I’ve defined a bunch of methods like this for common string filtering. Here’s the entire class:&lt;/p&gt;  &lt;p&gt;   &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:04e1aafd-f2f0-4014-97c3-b85351153d14" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background-color: #ffffff; overflow: auto; padding: 2px 5px;"&gt;&lt;span style="color:#0000ff"&gt;using&lt;/span&gt; System;&lt;br&gt; &lt;span style="color:#0000ff"&gt;using&lt;/span&gt; System.Text;&lt;br&gt; &lt;span style="color:#0000ff"&gt;using&lt;/span&gt; System.Linq;&lt;br&gt; &lt;br&gt; &lt;span style="color:#0000ff"&gt;namespace&lt;/span&gt; Cooper.Extensions&lt;br&gt; {&lt;br&gt;     &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af"&gt;StringKeepOnlyExtensions&lt;/span&gt;&lt;br&gt;     {&lt;br&gt;         &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; KeepOnly(&lt;span style="color:#0000ff"&gt;this&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; text, &lt;span style="color:#2b91af"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff"&gt;char&lt;/span&gt;, &lt;span style="color:#0000ff"&gt;bool&lt;/span&gt;&amp;gt; filter)&lt;br&gt;         {&lt;br&gt;             &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (text.IsNull())&lt;br&gt;                 &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;;&lt;br&gt; &lt;br&gt;             &lt;span style="color:#0000ff"&gt;var&lt;/span&gt; sb = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;StringBuilder&lt;/span&gt;();&lt;br&gt; &lt;br&gt;             &lt;span style="color:#0000ff"&gt;foreach&lt;/span&gt; (&lt;span style="color:#0000ff"&gt;var&lt;/span&gt; c &lt;span style="color:#0000ff"&gt;in&lt;/span&gt; text)&lt;br&gt;             {&lt;br&gt;                 &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (filter(c))&lt;br&gt;                     sb.Append(c);&lt;br&gt;             }&lt;br&gt; &lt;br&gt;             &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; sb.ToString();&lt;br&gt;         }&lt;br&gt; &lt;br&gt;         &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; KeepOnly(&lt;span style="color:#0000ff"&gt;this&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; text, &lt;span style="color:#0000ff"&gt;char&lt;/span&gt; characterToKeep)&lt;br&gt;         {&lt;br&gt;             &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; text.KeepOnly(c =&amp;gt; c == characterToKeep);&lt;br&gt;         }&lt;br&gt; &lt;br&gt;         &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; KeepOnly(&lt;span style="color:#0000ff"&gt;this&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; text, &lt;span style="color:#0000ff"&gt;char&lt;/span&gt;[] charactersToKeep)&lt;br&gt;         {&lt;br&gt;             &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; text.KeepOnly(c =&amp;gt; charactersToKeep.Contains(c));&lt;br&gt;         }&lt;br&gt; &lt;br&gt;         &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; KeepOnlyDigits(&lt;span style="color:#0000ff"&gt;this&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; text)&lt;br&gt;         {&lt;br&gt;             &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; text.KeepOnly(c =&amp;gt; c.IsDigit());&lt;br&gt;         }&lt;br&gt; &lt;br&gt;         &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; KeepOnlyDigitsAnd(&lt;span style="color:#0000ff"&gt;this&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; text, &lt;span style="color:#0000ff"&gt;char&lt;/span&gt; additionalCharacterToKeep)&lt;br&gt;         {&lt;br&gt;             &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; text.KeepOnly(c =&amp;gt; (&lt;span style="color:#0000ff"&gt;char&lt;/span&gt;.IsDigit(c) || c == additionalCharacterToKeep));&lt;br&gt;         }&lt;br&gt; &lt;br&gt;         &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; KeepOnlyDigitsAnd(&lt;span style="color:#0000ff"&gt;this&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; text, &lt;span style="color:#0000ff"&gt;char&lt;/span&gt;[] additionalCharactersToKeep)&lt;br&gt;         {&lt;br&gt;             &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; text.KeepOnly(c =&amp;gt; (&lt;span style="color:#0000ff"&gt;char&lt;/span&gt;.IsDigit(c) || additionalCharactersToKeep.Contains(c)));&lt;br&gt;         }&lt;br&gt; &lt;br&gt;         &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; KeepOnlyLetters(&lt;span style="color:#0000ff"&gt;this&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; text)&lt;br&gt;         {&lt;br&gt;             &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; text.KeepOnly(c =&amp;gt; &lt;span style="color:#0000ff"&gt;char&lt;/span&gt;.IsLetter(c));&lt;br&gt;         }&lt;br&gt; &lt;br&gt;         &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; KeepOnlyLettersAnd(&lt;span style="color:#0000ff"&gt;this&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; text, &lt;span style="color:#0000ff"&gt;char&lt;/span&gt; additionalCharacterToKeep)&lt;br&gt;         {&lt;br&gt;             &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; text.KeepOnly(c =&amp;gt; (&lt;span style="color:#0000ff"&gt;char&lt;/span&gt;.IsLetter(c) || c == additionalCharacterToKeep));&lt;br&gt;         }&lt;br&gt; &lt;br&gt;         &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; KeepOnlyLettersAnd(&lt;span style="color:#0000ff"&gt;this&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; text, &lt;span style="color:#0000ff"&gt;char&lt;/span&gt;[] additionalCharactersToKeep)&lt;br&gt;         {&lt;br&gt;             &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; text.KeepOnly(c =&amp;gt; (&lt;span style="color:#0000ff"&gt;char&lt;/span&gt;.IsLetter(c) || additionalCharactersToKeep.Contains(c)));&lt;br&gt;         }&lt;br&gt; &lt;br&gt;         &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; KeepOnlyLettersAndDigits(&lt;span style="color:#0000ff"&gt;this&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; text)&lt;br&gt;         {&lt;br&gt;             &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; text.KeepOnly(c =&amp;gt; &lt;span style="color:#0000ff"&gt;char&lt;/span&gt;.IsLetterOrDigit(c));&lt;br&gt;         }&lt;br&gt; &lt;br&gt;         &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; KeepOnlyLettersAndDigitsAnd(&lt;span style="color:#0000ff"&gt;this&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; text, &lt;span style="color:#0000ff"&gt;char&lt;/span&gt; additionalCharacterToKeep)&lt;br&gt;         {&lt;br&gt;             &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; text.KeepOnly(c =&amp;gt; (&lt;span style="color:#0000ff"&gt;char&lt;/span&gt;.IsLetterOrDigit(c) || c == additionalCharacterToKeep));&lt;br&gt;         }&lt;br&gt; &lt;br&gt;         &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; KeepOnlyLettersAndDigitsAnd(&lt;span style="color:#0000ff"&gt;this&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; text, &lt;span style="color:#0000ff"&gt;char&lt;/span&gt;[] additionalCharactersToKeep)&lt;br&gt;         {&lt;br&gt;             &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; text.KeepOnly(c =&amp;gt; (&lt;span style="color:#0000ff"&gt;char&lt;/span&gt;.IsLetterOrDigit(c) || additionalCharactersToKeep.Contains(c)));&lt;br&gt;         }&lt;br&gt; &lt;br&gt;         &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; KeepOnlySpaces(&lt;span style="color:#0000ff"&gt;this&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; text)&lt;br&gt;         {&lt;br&gt;             &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; text.KeepOnly(c =&amp;gt; (c == &lt;span style="color:#a31515"&gt;&amp;#39; &amp;#39;&lt;/span&gt;));&lt;br&gt;         }&lt;br&gt; &lt;br&gt;         &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; KeepOnlyWhitespace(&lt;span style="color:#0000ff"&gt;this&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; text)&lt;br&gt;         {&lt;br&gt;             &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; text.KeepOnly(c =&amp;gt; (c.IsWhitespaceCharacter()));&lt;br&gt;         }&lt;br&gt;     }&lt;br&gt; }&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2180987757847974648-2566427170775588271?l=blog.adamjcooper.com' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.adamjcooper.com/2010/04/stringkeeponly.html</link><author>noreply@blogger.com (Adam Cooper)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-2180987757847974648.post-7669374615266312478</guid><pubDate>Wed, 28 Apr 2010 04:20:00 +0000</pubDate><atom:updated>2010-04-28T00:20:21.558-04:00</atom:updated><title>Your Mindset is More Important</title><description>&lt;p&gt;It’s amazing how prone we can be to superficial measures of maturity. Sometimes we get it in our head—though we wouldn’t ever say it out loud—that using things like TDD, BDD, IoC, ORM, etc. will automatically lead us to software quality nirvana. It doesn’t. &lt;/p&gt;  &lt;p&gt;Kyle Baley has &lt;a href="http://codebetter.com/blogs/kyle.baley/archive/2010/04/27/defect-culture-or-how-to-broach-quality.aspx"&gt;a great article&lt;/a&gt; reminding me that, ultimately, what makes a software team great is not the tools or practices that they use, but their &lt;em&gt;mindset&lt;/em&gt;. It is only when developers care deeply about keeping the codebase clean and maintainable and producing quality results that these tools and practices show their merit. In order to build truly great software we need to do more than use great tools and say we follow great practices; we need to cultivate and encourage a culture of quality.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2180987757847974648-7669374615266312478?l=blog.adamjcooper.com' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.adamjcooper.com/2010/04/your-mindset-is-more-important.html</link><author>noreply@blogger.com (Adam Cooper)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-2180987757847974648.post-4804214956783943322</guid><pubDate>Tue, 19 Jan 2010 05:19:00 +0000</pubDate><atom:updated>2010-01-19T00:19:07.076-05:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>F#</category><category domain='http://www.blogger.com/atom/ns#'>Project Euler</category><title>Learning F# via Project Euler</title><description>&lt;p&gt;I’m convinced F# is a far more advanced and productive language than the C# I’ve been using for the past 7 years. And having tasted the beauty and power of functional programming with LINQ, lambdas, and extension methods in C# 3.5, I’m anxious to move to a paradigm that’s functional by default.&lt;/p&gt;  &lt;p&gt;And yet every time I try to start a personal project in F#, I seem to freeze with questions. Is this really the way I should be building this? Should I be using a class or a record? What was the name of that module again? You know, basic stuff.&lt;/p&gt;  &lt;p&gt;So I’ve decided that a good way to learn F# would be to go through (at least some of) the Project Euler problems. Already I’ve worked through the first two and have found the experience to be very worthwhile in general and a nice way to get comfortable with F#. Time permitting I may blog about some of my experiences.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2180987757847974648-4804214956783943322?l=blog.adamjcooper.com' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.adamjcooper.com/2010/01/learning-f-via-project-euler.html</link><author>noreply@blogger.com (Adam Cooper)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-2180987757847974648.post-1288195208867254331</guid><pubDate>Tue, 19 Jan 2010 04:46:00 +0000</pubDate><atom:updated>2010-01-19T13:04:43.054-05:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>Architecture</category><category domain='http://www.blogger.com/atom/ns#'>NHibernate</category><category domain='http://www.blogger.com/atom/ns#'>ORM</category><title>Are ORMs Solving Anything? Yes.</title><description>This was meant to appear as a comment on Shawn Wildermuth's post "&lt;a href="http://wildermuth.com/2010/01/18/Are_ORMs_Solving_Anything"&gt;Are ORMs Solving Anything?&lt;/a&gt;". But it turned out to be too long to be accepted as a comment, so I've posted it here.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;This is certainly thought provoking, though I'm surprised that the small consensus here is that ORMs are better suited for small projects. Because, in my experience, it is in the enterprise space that a good ORM (like NHibernate) can really shine.&lt;br /&gt;&lt;/blockquote&gt;&lt;blockquote&gt;I think we often assume that using an ORM means generating code or schema. With some ORMs, this is definitely the case. Why, LINQ-to-SQL generates reams of C# code to give you a type safe version of your data schema. And, as you pointed out, you can use tools like NHibernate to go the other direction as well, generating your data schema from your class mappings. If code/schema generation was what made ORMs great, then yeah, I think they'd only be good for newer, smaller projects. But there's a lot more to ORM than code generation that's worth keeping in mind.&lt;br /&gt;&lt;/blockquote&gt;&lt;blockquote&gt;In my mind, using a robust ORM (like NHibernate) really makes the most sense in an enterprise context. Here are some of the advantages of using NHibernate on a project of substantial size:&lt;br /&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Database agnosticism. &lt;/b&gt;If being able to provide a choice in database technology is an advantage to your business, NHibernate can certainly deliver.&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Testing. &lt;/b&gt;As a consequence of being database agnostic, you can replace your heavy SQL Server with a nimble SqlLite instance at test time, allowing you to write blazing fast tests.&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Caching.&lt;/b&gt; NHibernate offers a tremendous amount of options and control when it comes to caching. First-level caching is built in, and there are a variety of second-level caching providers you can chose from. Need to add distributed memory caching to your app? Plug into the NHibernate memcached second-level cache provider.&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Higher level of query abstraction.&lt;/b&gt; Most ORMs allow programmers to query in ways that are more consise (and type safe) than raw SQL. Of course, this can be a performance liability if you don't know what you're doing (or if you neglect to use a good profiler), but overall the productivity gain seems like a win to me.&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Dealing with legacy data schemas.&lt;/b&gt; A framework like NHibernate offers significant advantages when working with a large, legacy codebase and database that need to be maintained. With it, I can start modeling my own view of the world in code (in a DDD style) and then use NHibernate to map my objects down to the way they are actually represented in the database. Having done that, we can then start querying our domain model directly, allowing the development team to think in terms of the way we think of the business rather than having to constantly translate our intent to a data schema that hasn't grown with the business. And, once we've abstracted away direct access to the database, we can more safely modify the database schema knowing that it is only our mappings which will need updating.&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;&lt;blockquote&gt;I'm sure someone with more ORM experience than me could add a lot more to the list. But notice that none of the points above are particularly suited for small projects. In fact, quite the opposite. All of these gains are relevant when developing larger projects for the enterprise.&lt;br /&gt;&lt;/blockquote&gt;&lt;blockquote&gt;So I suppose what I'm suggesting is that code and schema generation is only a small part of what ORMs offer. Of course there are enterprise situations where performance is so important that an ORM tool is simply not appropriate, but few of us are Amazon or Google, and I would argue that the advantages listed above make long-term maintenance, changes, and refactoring significantly easier rather than more difficult.&lt;br /&gt;&lt;/blockquote&gt;&lt;blockquote&gt;I hope this reply doesn't come off as defensive, because, like you, I'm not trying to chose a pro- or anti-ORM side. But I did want to point out some ways in which ORMs can be very helpful in managing large projects.&lt;br /&gt;&lt;/blockquote&gt;&lt;blockquote&gt;I do wonder what the future holds for ORMs though, particularly with the rise of functional programming. A language like F# can deal with relational data in a much more natural way than most of the OO languages we've been using for so long, and I wonder how that might change the ORM landscape.&lt;br /&gt;&lt;/blockquote&gt;&lt;blockquote&gt;Your chart on the right side of the page illustrates something that astounds me--look at how much stuff we have to do above and below the business objects, which are the real heart of the software! It's amazing how much effort and energy we expend on all of the infrastructural pieces that we need to put in place in order to get real work done. Then again, perhaps the better way to look at it is that we're trying to extract that sweet core of business knowledge out of and away from all of the infrastructure concerns (both front end and back) so that we can swap out the pieces that change without destroying the code that models our business. And that is, I think, the real reason I find value in an ORM.&lt;br /&gt;&lt;/blockquote&gt;&lt;blockquote&gt;Hope that helps,&lt;br /&gt;&lt;/blockquote&gt;&lt;blockquote&gt;Adam&lt;br /&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2180987757847974648-1288195208867254331?l=blog.adamjcooper.com' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.adamjcooper.com/2010/01/are-orms-solving-anything-yes.html</link><author>noreply@blogger.com (Adam Cooper)</author><thr:total>1</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-2180987757847974648.post-978521806258559113</guid><pubDate>Fri, 18 Sep 2009 07:51:00 +0000</pubDate><atom:updated>2010-01-19T00:21:04.190-05:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>Christian</category><title>My Lord, My Truth, My Way</title><description>&lt;p&gt;Shortly before he was arrested and crucified, Jesus told his disciples “you know the way to where I am going” (John 14:4). Where he was going was heaven, to be with the Father. The way there was through the cross he was about to suffer.&lt;/p&gt;  &lt;p&gt;But Thomas, bewildered and confused, responded “Lord, we do not [even] know where you are going. How can we know the way?” (John 14:5) To which Jesus said: “&lt;em&gt;I&lt;/em&gt; am the way, and the truth, and the life. No one comes to the Father except through me.”&lt;/p&gt;  &lt;p&gt;This answer is startling—Jesus has already told his disciples there is a “way” which he must go to the Father (an obvious reference to the coming cross), but now he says that this “way” is &lt;em&gt;himself&lt;/em&gt;.    &lt;br /&gt;It seems to me this is Jesus’ way of saying that there’s more to his cross than just the wood and the nails and the fact that he died. There is something about Jesus himself in the way he went to the cross that we need to pay close attention to.&lt;/p&gt;  &lt;p&gt;Jesus’ death was not a tragedy that could have been avoided, something that just “happened” to him. No, it was a deliberate choice, a choice to sacrifice himself for the good of others, a deliberate decision to lay aside his greatness and stoop low, as low as anyone has, to rescue a sinful humanity. It was this particular aspect of his death, this willingness to humble himself out of love for other people, that Jesus seems to refer to when he says “&lt;u&gt;I&lt;/u&gt; am the way.” It is as if Jesus was saying “Look at me Thomas. Watch what I am about to do. Learn from my humble submission to the Father and my sacrificial love for you, and then &lt;em&gt;make my example the pattern for all of your life&lt;/em&gt;.” Indeed, he had just told them “just as I have loved you, you also are to love one another.” (John 13:34)&lt;/p&gt;  &lt;p&gt;But after an unjust arrest, a brutal execution, and three days of loneliness as Jesus’ body lay lifeless in a tomb, Thomas seems to have lost all hope. How could this be the “way” to the Father? When the disciples come to him claiming that Jesus was alive, he would not hear it. “Unless I see in his hands the mark of the nails, and place my finger into the mark of the nails, and place my hand into his side, I will never believe.” (John 20:25)&lt;/p&gt;  &lt;p&gt;Eight days later, Thomas found himself face-to-face with the man he thought he would never see again. “Put your finger here,” Jesus said, “and see my hands; and put out your hand, and place it in my side. Do not disbelieve, but believe.” (John 20:27 ) In that moment Thomas suddenly realized that Jesus’ dying example was not a failure, but a pathway to victory, to which he exclaimed “My Lord and my God!” (John 20:28)&lt;/p&gt;  &lt;p&gt;One of my favorite hymns, &lt;em&gt;My Lord, My Truth, My Way,&lt;/em&gt; begins with a line that is really a combination of Jesus’ words to Thomas before his death (“I am the way, the truth, and the life”) and Thomas’ words to Jesus’ after his resurrection (“My Lord and my God!”). It is the song of a Thomas-like disciple who has seen the risen Lord and longs to follow in his steps. Here are three verses:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;My Lord, my Truth, my Way,      &lt;br /&gt;My sure, unerring light,       &lt;br /&gt;On Thee my feeble steps I stay,       &lt;br /&gt;Which Thou wilt guide aright.&lt;/p&gt;    &lt;p&gt;My Wisdom and my Guide,      &lt;br /&gt;My Counsellor Thou art;       &lt;br /&gt;O never let me leave Thy side,       &lt;br /&gt;Or from Thy paths depart!&lt;/p&gt;    &lt;p&gt;Teach me the happy art      &lt;br /&gt;In all things to depend       &lt;br /&gt;On Thee; O never, Lord, depart,       &lt;br /&gt;But love me to the end!&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;You can find the entire hymn at &lt;a href="http://www.cyberhymnal.org/htm/m/l/mlmtruth.htm"&gt;CyberHymnal&lt;/a&gt;.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2180987757847974648-978521806258559113?l=blog.adamjcooper.com' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.adamjcooper.com/2009/09/my-lord-my-truth-my-way.html</link><author>noreply@blogger.com (Adam Cooper)</author><thr:total>0</thr:total></item></channel></rss>
