Wednesday, July 26, 2006

The DevUtah Geek Dinner tonight was a lot of fun.  I carpooled down again with my buddy, Nate Jones, and we were two of about 35 attendees who showed up to the Brick Oven restaurant in Provo.  We all enjoyed some great conversations and meals and had a great time.  Due to the atmosphere and not having our own dedicated room we weren't able to accomplish all that we had wanted, but we did have Jeff Rust of Corporate Alliance take us through some networking tips and drills.  They were a good deal of fun especially as they were a break from the norm and helped us become more acquainted with the other attendees.

Can't wait until the next one.

Wednesday, July 26, 2006 3:42:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [1]  |  Trackback

I'm an avid fan of ReSharper by JetBrains (as many of you are very aware).  It wasn't until today, however, that I discovered that the team at JetBrains has an official JetBrains .NET Tools Blog where the various .NET products are discussed.  Fortunately, I'm not too far behind as the blog was only started on June 1, 2006.

What a great idea.  I'm subscribed!

Wednesday, July 26, 2006 8:14:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback

I saw this post on Craig's blog today and thought I'd give the test a whirl.  It's kind of fun.  After an initial, free registration, the online face recognition software matches up your face with those of celebrities and provides a list of approximate matches.

My first photo yielded these results:

Julia Roberts (66%)
Howard Dean (64%)
Cary Grant (60%)
Roy Keane (59%)
Zsolt Baumgartner (58%)
Jason Donovan (58%)
Hillary Rodham Clinton (55%)
Dennis Hopper (55%)
Jack Brabham (54%)
Luis Figo (53%)

Whereas the picture on the left (on my blog homepage) matches the following:

Joi Ito (59%)
Sugar Ray Leonard (54%)
Matt Damon (51%)
Karl of Austria (48%)
John Deacon (47%)
Neil Sedaka (46%)
Jesse Metcalfe (46%)
Tiger Woods (45%)

Maybe I'll try to channel some of that Cary Grant, Matt Damon, and Tiger Woods charm that runs so prevalently in my blood. :)

Wednesday, July 26, 2006 7:25:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [1]  |  Trackback
 Tuesday, July 18, 2006

I've had an issue on my laptop that's been plaguing me now for about a month, but only today (this evening) have I really had a chance to dive into it and figure out what the problem was.

Almost everytime I would reboot and log in to my machine one process (svchost.exe) would peg the processor at 100% for about 3-4 minutes.  I have a dual-core, so it effectively was pegging my system at 50%, but I still couldn't do too much with one processor being hogged so much.  The crazy thing about this is that it wouldn't happen every time; it was very intermittent.  Even then, it would also occur out of the blue during the normal course of my work.

As any self-respecting Windows developer, I like to have the fantastic Process Explorer as my CTRL+ALT+DEL replacement for viewing processes, threads, memory, and much more.  This tool allows me to double click on the process in question to view information about the process.  Svchost.exe is a special system process that runs Windows Services, so there are many instances of this process on my laptop, each running one or more services.

This particular process, for instance, runs about 24 different services.  I found, by brute force method (e.g. stopping services one by one until the CPU was restored to normal), that the offending service was the Automatic Updates.  Now, I enabled this service long ago (and always have enabled this service) and the issues didn't arise then so it was a bit trickier to nail it down.  I like to have this service running, but not at the cost of losing so much productivity.

NOTE: Earlier I mentioned that I traditionally use Process Explorer to see what services are running in a svchost.exe process.  You can also list services by the following command line:

TASKLIST /SVC
this will list each process and any services running within them

TASKLIST /SVC /FI “PID eq XXXX“
this will list just the services running in the process whose PID is XXXX

PS:  I also just found this blog entry after having written the above post, that I wish I had seen before.  This may very well prove to be helpful in the future.  Thanks, Joel.

Tuesday, July 18, 2006 3:57:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [1]  |  Trackback

Well, it's been announced now for a little while, but I thought I'd add my two cents.

We had a great time last month (June 2006) at the Utah Geek Dinner with a slight departure from the norm; we went out to eat at Tucanos and then out to see Superman Returns.  This time, however, we should be back to our normal form (maybe 3rd Normal Form).  The Utah Geek Dinner will be held on Wednesday, July 26th, 2006 at 6:30 PM at the Brick Oven in Provo (111 East 800 North).  Please RSVP up on the wiki if you plan to attend.

Come out and join in the fun.  It's free and open to all!  Let's get some of the .NET community out to these wonderful events!

Tuesday, July 18, 2006 3:21:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Monday, July 17, 2006

This past week was a bit on the crazy side.  I had the opportunity to go to Boston, MA for the Microsoft Worldwide Partner Conference representing Experlogix, Inc.  We had a booth there and had a great show.  Perhaps as a downer for the company I was, unfortunately, the best we could come up with for a booth babe.  How unfortunate.  Seriously, though, the show was great and we had a fantastic time.

While I was there in Boston, a tragedy occurred in which a large cement slab fell from the tunnel ceiling killing a woman.  How terrible!  And to think that I had passed through that very tunnel just the day before (if I'm not mistaken).

We also had (back in Salt Lake City), our monthly Utah .NET User Group meeting.  Aaron Skonnard presented the second in a back-to-back series on Biztalk, this time focusing on Orchestrations.  I wish I could have been there.  I'm a big fan of Biztalk - maybe I'll blog about it someday as well.  They also sang “Jon Boy Jon“ which is to a few of the tunes from Les Miserables and “Uncle Earl's Hairpiece“ which was quite funny.  It was a great time!

Tonight we had the opportunity to take a family outing to the 'Arts in the Park' in Lehi with some great friends.  We attended a concert by the a capella group Moosebutter.  They're a lot of fun and we had a great time.  We heard about Moosebutter several months ago with their clever renditions of Star Wars and Harry Potter.

I'll get back to technical posts here in the coming days.  Conferences seems to drain some of my tech-blogging powers.  Usually, I'm armed with my Gauntlets of Blogging +1, but I left them in my suitcase as they don't let me bring them into the tradeshow floor.  I'll see if I can't find them here somewhere...

Monday, July 17, 2006 3:21:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Wednesday, July 12, 2006

We're very excited to have Aaron Skonnard back to the Utah .NET User Group for a second month of Biztalk.  This time, the focus is on Biztalk Orchestrations, whereas last month, he targeted an overview of Biztalk and Messaging, etc.

Therefore, you are encouraged to come and participate on July 13th, 2006 at 6:00 PM at Neumont University.  It'll be great fun.  Bring your buddies, find your friends, persuade your pals, convince your comrades and companions, venid con vuestros vecinos, and let's gather as a gang of geeks! - or is it gaggle of geeks :) ?

It'll be a blast.

Aaron's a great speaker - you won't want to miss it.

(Don't forget to join us afterwards to hang out, chill, and have a great time!)

Wednesday, July 12, 2006 5:01:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Monday, July 10, 2006

I updated my download control a bit tonight - fixing (hopefully) a bug in the download process.  I've had many people download files from the site and not a single person has sent me the feedback that it wasn't working though all other indications are that it's failing.  For instance, a user attempts to download a file multiple times in a few minute span, etc.  It was working fine in my test environment but apparently it wasn't working correctly from the actual server.

When you request a download you get an email with a confirmation number and a direct link back to the download.  Well, I had an HTTP handler set to receive the request that consists of the download identifier along with the confirmation code.  However a bug (I'm presuming it's in IE) misinterprets the HTTP Headers in the response and it attempts to save the file with the useless name of the CONFIRMATIONCODE.dspx rather than the appropriate name (.dspx is the extension I use to identify my 'Devstone Server Page' handler).

My code resembles the following, where info is a class instance that identifies the requested download:

HttpResponse res = context.Response;
res.Cache.SetCacheability(HttpCacheability.Private);
res.ContentType = "application/download";
res.AppendHeader("Content-Disposition", "attachment; filename=" + info.FileName);
res.WriteFile(info.GetDirectServerPath());

Can anyone see anything blatently wrong with this code?  I've had it work many times (even occasionally from the production site), but for the most part it doesn't seem to work from a direct link - however, it does work with I perform a Response.Redirect() to the url.  I'll look into the differences to see what might be happening.

As a temporary patch to the problem, when you attempt to download a file, you're asked to provide your confirmation number.

I apologize for the inconvenience.

Monday, July 10, 2006 4:08:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [1]  |  Trackback
 Sunday, July 09, 2006

This week we (Experlogix) will be in Boston at the annual Microsoft Worldwide Partner Conference.  While the conference officially starts on Tuesday, we're heading down tomorrow to get established and prepare our booth (#806).

This is a wonderful opportunity to meet other partners and interact with them and share ideas, not to mention showcase our products and build our reputation and customer base.  We've made it a point to be present at each of the past WWPC's (in Toronto as well as Minneapolis) and they've been fantastic events.

If you're going to be there, please feel free to stop by our booth, drop me a line, or shoot me an email.  Let's hang out!

Sunday, July 09, 2006 5:58:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback

I finally added my feed to FeedBurner.com a couple days ago - I don't know why I hadn't done it until now.  If you're so inclined, please subscribe via FeedBurner if nothing else for the stats that it provides.  If you like, you are still more than welcome to subscribe directly to the blog at the standard url.

Sunday, July 09, 2006 6:45:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Thursday, July 06, 2006

Well, my quiz from about 3 weeks ago didn't really elicit the response I was hoping.  However, for the benefit of those that have been wondering, I've decided to post my results.  As you may recall, the quiz was a seemingly simple one: to determine if a directory is empty (e.g. that it has no contents: files or folders).

Almost alarmingly, there is nothing built into the .NET Framework for such an operation.  One solution (which was proposed in the preceding post) is to evaluate the results of the Directory.GetDirectories() and Directory.GetFiles() methods.  Doing this, however, forces the runtime to enumerate all of the contents of the folder only to be discarded once we see determine that there were indeed files and folders.  There's no way (that I've seen) to call a Directory.IsEmpty() method or even a Directory.GetDirectoryCount() or Directory.GetFileCount() (though those might also force enumeration internally if they existed).

I have a solution that I propose as being better than the contrived example from the original post, though it is a little lengthier.  I haven't run any stringent analysis on its performance though I have to believe that it's faster than the method that relies on enumeration.  I also imagine that its performance will be substantially better over a network.

This solution relies on some built-into-the-Windows-kernel API calls to walk the contents of a directory (for there isn't any functionality there either to see if a directory is empty).  As soon as a file or folder is found it quits and indicates that the folder is non-empty.

private static bool isDirectoryEmpty(string directory) {
   IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
   NativeMethods.WIN32_FIND_DATA findData;
   IntPtr handle = IntPtr.Zero;
  
   try {
      handle = NativeMethods.FindFirstFile(@"
\\?\" + Path.Combine(directory, "*"), out findData);
      if ( INVALID_HANDLE_VALUE == handle ) {
         // call GetLastError() here to be explicit on the reason of the failure
         // for now, simply assume that the directory is not empty.

         return false;
      }
  
      // spin on the directory until a file/directory other than the current (.) or parent (..) is found
      // if something is found, quit immediately - we've determined that the folder is not empty
      do {
         if ( "." != findData.cFileName && ".." != findData.cFileName ) return false;
      } while ( NativeMethods.FindNextFile(handle, out findData) );
     
      // no file or directory was found, so return that it is indeed empty.
      return true;
   }
   finally {
      if ( IntPtr.Zero != handle )
         NativeMethods.FindClose(handle);
   }
}

This code makes use of a NativeMethods class which I define below.  It contains the system API calls that are used to walk the directory contents.

internal static class NativeMethods {
   public const int MAX_PATH = 260;
   public const int MAX_ALTERNATE = 14;

   [StructLayout(LayoutKind.Sequential)]
   public struct FILETIME {
      public uint dwLowDateTime;
      public uint dwHighDateTime;
   };

   [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
   public struct WIN32_FIND_DATA {
      public FileAttributes dwFileAttributes;
      public FILETIME ftCreationTime;
      public FILETIME ftLastAccessTime;
      public FILETIME ftLastWriteTime;
      public int nFileSizeHigh;
      public int nFileSizeLow;
      public int dwReserved0;
      public int dwReserved1;
      [MarshalAs(UnmanagedType.ByValTStr, SizeConst=MAX_PATH)]
      public string cFileName;
      [MarshalAs(UnmanagedType.ByValTStr, SizeConst=MAX_ALTERNATE)]
      public string cAlternate;
   }

   [DllImport("kernel32", CharSet=CharSet.Unicode)]
   public static extern IntPtr FindFirstFile(string lpFileName, out WIN32_FIND_DATA lpFindFileData);

   [DllImport("kernel32", CharSet=CharSet.Unicode)]
   public static extern bool FindNextFile(IntPtr hFindFile, out WIN32_FIND_DATA lpFindFileData);

   [DllImport("kernel32")]
   public static extern bool FindClose(IntPtr hFindFile);
}

NOTE:  Please let me know if I overlooked something obvious.  I've not done stringent analysis with this code but wanted to put it out there as a proposed solution for determining that a directory is empty in an efficient manner.

Thoughts?

Thursday, July 06, 2006 7:31:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [2]  |  Trackback
 Sunday, July 02, 2006

Things have been a little insane around here lately.  I've made it a point to work on around-the-house projects.  Over the past several years we've done many: replaced the driveway, replaced the garage door, etched/painted/sealed the garage floor, installed vinyl fencing, poured approx 3800 sq feet of colored/stamped cement (including a basketball court), built an ironwood deck, built a shed, landscaped and then re-landscaped the yard, built a garden box, remodeled the master bedroom (I'm still working on the shelving and cabinetry), poured a courtyard and constructed a brick wall w/lights, and replaced the front door.

In addition to the aforementioned projects I've had this 5.5-6 year-running project of the basement.  I started it about six years ago and, amid all of the other goings-on, haven't really found the time to finish it.  Sure, I've worked on it here and there (mostly dabbling and stuff), but over the course of the past few weeks I've made it a point to actually finish that project.  Well 99.9% of my part is finally done (I just have to replace two can lights that for some reason aren't working and move a few ethernet cables).  I'll be moving my office to downstairs :-).  Primarily due to this project I've not really taken the time to blog like I have wanted to.

The drywall is getting installed this week (that's the one part of the whole project I don't like to do so I'm contracting it out).  A finished basement will add about 1300 sq feet to the house so I'm very much looking forward to that!  Plus I'll be moving my office out of an over-cramped 11'x10' bedroom to a dedicated office that is about 25'x14' + bath.  I'm very excited - this is long overdue.  I just pray that I did everything correctly and that it will all work once it's up.

Anyhow, I very much enjoy house projects, but sometimes I'm a bit overwelmed by trying to do so many at once.

Sunday, July 02, 2006 5:42:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback