Tuesday, March 14, 2006

I have both the .NET 1.1 and .NET 2.0 frameworks installed on my laptop because I frequently write software on both platforms.  I recently had the need to create a new ASP.NET 2.0 website.  I set everything up in IIS first (because I like to be able to dictate the name of the virtual directory and have it routed somewhere other than the InetPub\wwwroot folder for development.

Aside: VS2005 happily supports having a virtual directory pointed at a folder with a name other than the virtual directory name :)  VS2003 and prior didn't support this, so I didn't have nearly as many hoops to jump through when setting it up.  For instance, my virtual directory might be named TestSite and point to a folder named Source within the TestSite folder.  (I might have other peer folders, such as DbScripts, Documentation, etc all within the TestSite parent folder.  I no longer have to jump through hoops to make that work. :)

Anyway, I set it up and began writing some framework code for the site, setting up some master pages, themes, et al.  When I went to browse to the page I was greeted with a 'Mutex could not be created' error page.  Not deterred (and, frankly, half expecting the exception in the first place), all I had to do was this:

  1. Grant myself (rather the user the site impersonates) Full Control to the %WINDIR%\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files folder.
  2. Then, as I have the tradition of doing, delete the 'TestSite' folder (and all others for that matter) from the 'Temporary ASP.NET Files' folder.
  3. Perform an IISRESET.

Once those steps were done, the site worked like a charm!  Happy Coding.

Tuesday, March 14, 2006 7:41:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [12]  |  Trackback
 Thursday, March 09, 2006

Today is something of a sad day.  For the first time in the many years of the Utah .NET User Group we're having to cancel the meeting.  All week long everything was looking to a great day today, but we got hit pretty hard with snow and wind creating perpetual white-out conditions.  All the meteorologists are saying it's going to continue and to be bad into the weekend.

We don't want anyone to unnecessarily put their lives at risk to come to the meeting nor do we want to put lots of time and money into the meeting to have no one show up.  Therefore, we've opted to cancel today's meeting in lieu of the weather.  Perhaps we can simply postpone it for a week or so.  If not, we'll pick up in April where we would have been today.

Thursday, March 09, 2006 3:44:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Tuesday, March 07, 2006

I was experimenting last night with a friend of mine (I would link to him, but he doesn't yet have a blog, the bum) and we came up with a pretty cool solution for application configuration files.  Generally, the practice and recommendation is to create/add an app.config file into your VS.NET project.  The compiler will then take the responsibility of copying the configuration file to the appropriate output directory (e.g. Debug, Release, etc) named after the executable (e.g. MyApplication.exe.config).  Then, when your application needs to access information within the configuration file via AppSettings or a call to GetConfig, it can do so via the ConfiurationSettings (in .NET 1.1) or ConfigurationManager (in .NET 2.0).  All is well, and most everybody is happy.

Suppose, then, that you have several applications that get deployed across the computer (maybe into the same folder, maybe not).  These applications may each require their own app.config file.  What can escalate the issue further and introduce maintenance problems is the concept of Library Assemblies.  Library assemblies (DLLs) will look for settings within their host .exe's app.config file.  If you have a 'family' or 'suite' of tools that share a common set of libraries, you will end up repeating the same settings across a multitude of configuration files for the dlls to read.  This easily gets out of control and it makes troubleshooting an application suite cumbersome to deal with, especially when settings must be updated.

By default, as mentioned, your application will look for configuration settings in a configuration file named after the host executable (e.g. MyApplication.exe.config) in the same working directory as the application.  An exception to this is a COM+ component which will look in either %windir%\system32 or the application folder as specified in the application.config (except on Windows 2000) as discussed here.  You do, however, have the means to override this default behavior on both the .NET 1.x and .NET 2.0 platforms.  This overriding must occur prior to any access to the configuration file, so it's a good practice to include this call at the start of your application.

You simply need to tell the AppDomain where to look and this is done via the simple call:

AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", @"c:\myconfig.config");

Of course, it's probably not a good idea to hardcode the path to the configuration file in your application, so reading it from the command line, a registry setting, or some other known location (but not a config file) might be a good idea.  The cool thing about this is you then can have a single, centralized location for all settings and a single location to edit them to have global effect.  Goodbye several configuration files.

Tuesday, March 07, 2006 9:56:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [3]  |  Trackback
 Monday, March 06, 2006

I have the opportunity this month to host a follow up presentation to last month's (seemingly well received) presentation in a series focused on The Component Developer.  Last month's meeting was targeted at WinForm controls.  This month we move into the realm of ASP.NET control development.  We'll be exploring UserControls, WebControls, and much more.  Hope to see you there!

NOTE: If you have any requests or have some questions you want addressed, please leave me a comment/rating and I'll do my best to include the appropriate discussion.

Monday, March 06, 2006 2:30:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Saturday, March 04, 2006

I had the situation today in which I needed to take standard console output and write it to an alternate location.  Typically console output gets written to the console window's standard output (i.e. the computer monitor's screen) via the various Write() and WriteLine() methods.  In order to change the destination of the output you usually create an instance of a TextWriter, assign it to the Console object (via SetOut(...)), and away you go.

However, all of the examples that I found regarding this technique involved redirecting console output to a stream writer over a FileStream or a MemoryStream so the output wasn't ever visible.  That is, the stream was opened, information was pumped into it via the various methods, and when the application ended the stream was flushed and closed and the user never was the wiser about the output.  In some cases that's just fine, but I had an application that utilized the Console to provide periodic and frequent updates, effectively notifying the user of status and progress through a lengthy set of operations.  I was extremely hesitant to rewrite the application or introduce a TextWriter parameter (substituting for Console.Out) and using that rather than Console or (heaven forbid) introducing a global TextWriter that all classes magically utilized.  Besides, the Console object is already there for precisely that purpose.

Therefore, I had made the decision long ago to stick with using Console.WriteLine(), et al and stay the course.  However, one obstacle remained: how can I, using Console.Write[Line]() redirect the output to a TextBox (or some other control) without having to wait for the stream to be closed to get the information written to it?

The answer I came up with is to create a special class (in my case I called it FeedbackWriter) that inherits from the abstract TextWriter.  Then, I overrode the various WriteXXX() methods to take the string and pump it into the TextBox.  NOTE: it may not be sufficient to simply override one Write() or one WriteLine() method, and yes, there are many overloads.  Each of these methods on the Console object calls directly into the matching WriteXXX() on the TextWriter so you might have a little work, but once it's done, it's done.  Even then, you might not need to do much more than what's below.  A quick glance to Reflector shows that the various .Write() and .WriteLine() methods pipe their calls through the string overloads (with the exception of the char and char[] overloads).

My example resembles the following:

[UPDATED 03/06/2006: Removed the assignment to the base.NewLine explicitly - it defaults to “\r\n“ which is the appropriate line break in a TextBox]

internal sealed class FeedbackWriter : TextWriter {
   internal FeedbackWriter(TextBox textBox) : base() {
      _textBox = textBox;
   }

   private TextBox _textBox;


   public override Encoding Encoding {
      get { return Encoding.Default; }
   }


   // when the Console's Out property is set to other than the default,
   // the Console class will create a synchronized, thread-safe TextWriter
   // so we don't need to perform the otherwise required calls to
   // .InvokeRequired and .Invoke() on the TextBox.


   public override void Write(string value) {
      _textBox.AppendText(value.Replace("\n", base.NewLine));
   }


   public override void WriteLine(string value) {
      this.Write(value);
      // WriteLine() needs to append and additional line break.
      _textBox.AppendText(base.NewLine);
   }
}

Then, once all of the desired overloads are defined, you can use it simply like this:

FeedbackWriter writer = new FeedbackWriter(txtFeedback);
Console.SetOut(writer);

It's nice and convenient to be able to redirect the console output like this and not have to make any other changes to the application.  This discussion is not really complete, but it potentially provides the basis for some future posts on the topic, if I feel so inclined or have the requests.

Saturday, March 04, 2006 6:46:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [9]  |  Trackback
 Wednesday, March 01, 2006

Today was amazing.  We came to Chicago yesterday for, among other reasons, the Microsoft CRM Tour on Thursday.  However, to take advantage of the trip to Chicago (a place to which I haven't been for almost 20 years), we came in a few days early to see the sights.  Yesterday afternoon was spent perusing the Miraculous Mile - a mile of shopping - culminating at the John Hancock building.

Today, we had the opportunity to go and see the Shedd Aquarium and the Field Museum.  Having been to both places as a child, I do have some recollections of the experience, but it was a blast to relive it.  To my great delight I saw something today that I've been wanting to see for YEARS: Sue, the Tyrannosaurus Rex.  I'd ALWAYS wanted to see a T-Rex and today my wish was fulfilled!  Sue is, if you're not aware, the largest specimen of T-Rex every found and the most complete skeleton.  Missing just a few bones in one claw, the lower left leg and a few tail bones, Sue is sure a sight to see!  Most amazing!

I've attached a link to one of the many pictures taken.  Clicking the image will show a larger sample of the picture (940 KB).

The walk back to the hotel included a walk along Lake Michigan and through Millenium Park.  All in all, a great day.

Tonight we're going to dinner at Topolobampo.  We saw Rick Bayless on Iron Chef America and loved his style...can't wait to try it!

Wednesday, March 01, 2006 10:03:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Thursday, February 23, 2006

Well, I'm in the airport in Portland about ready to fly home.  This trip has been quite fun and much more enjoyable that other similar trips.  For example, I had the opportunity last night to go hang out at the PADNUG (Portland Area .NET User Group) to see/hear a great presentation on LINQ (Language INtegrated Query) that is forthcoming in Orcas - Visual Studio .NEXT/.NET 3.0.  The presentation was given by Nick Muhonen and was pretty awesome.  Recently, we had a presentation at our UtahDNUG on LINQ by Fabio Cavalcante that was also very good.

Following the meeting I hung out with a few of the guys from the group which was lots of fun.  I had my concerns about getting back to the hotel from the place and after having been given two different sets of directions from the group, I followed the advice to go across the Steel Bridge and found my way back ultra-easily :-)

Today, I had the opportunity to man our booth at the Microsoft Dynamics CRM 3.0 Launch Tour and demonstrate our product to several people and had lots of interest.  What a wonderful day.

On top of that, I had rented an H3 (Hummer) and had a blast driving it.  Aside from the low (narrow?) windshield I very much enjoyed driving it.  Were I to actually purchase one, however, I don't know if my wallet would enjoy me driving it.

My trip here was preceded with a brief two-night stint in Santa Barbara, which proved to be very productive and lots of fun.  So all in all, I've had my hands full, but it's been fun all the while.

Thursday, February 23, 2006 10:17:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Monday, February 20, 2006

I've been kinda quiet these past few days, but that not for lack of desire or for a lack of content.  Rather, I have been intensely busy on nailing down some functionality in some software projects as well as remodeling my bedroom.  I tore out the carpet, the padding, the baseboards, the shelving on the closet walls and completely revamped the room.  I built from scratch a new shelving system (which I have yet to totally finish, but it's hard being out of town), a new entertainment center, painted the walls (including an accent wall), installed new carpet with deluxe padding, put in a new bed, and the works.

It's been a fun experience and well worth it.  I hope to be more focused on the blogging moving forward, but I also need to finish the furniture...it'll be great!

Monday, February 20, 2006 6:38:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback

In an attempt to help spread the word, the next DevUtah Geek dinner is coming up this next Wednesday (that's 2 days from now).  Unfortunately, I will not be able to attend being that I'll be in Portland for the Microsoft CRM 3.0 Launch Tour on the 23rd, but the past events have been fantastic!  Instead, I'll be making a visit to the Portland Area .NET User Group.

Don't miss the Geek Dinner if you can help it.  I've attached the details below.

**EVENT SUMMARY**

DevUtah's February Geek Dinner will be held at the Miller Business Innovation Center on Wednesday February 22 at 6 PM.

David Spann and Alistair Cockburn will lead a discussion on "Introducing Agile to the Organization". If you’ve heard of Agile methodologies but can’t get others in your organization interested; or if you’ve been a member of a high performing Agile team but can’t find the right words to convince upper management to spread the "gospel", this discussion may be helpful. David and Alistair will take your questions before they begin and will respond to as many as possible. Being agile by nature, they want to meet your (the customer’s) interest. If you’ve only heard about Agile, feel free to do a little research and post beginner questions as well.

**SPEAKERS**

David Spann is high-tech management consultant who focuses teams on making a reasonable return on investment while exceeding customer expectations. David has helped conduct each of the annual Agile Software Conferences since the first one held at Westminster College in 2002 and is currently involved with Alistair Cockburn in developing Utah's Agile Project Leadership Network.

Alistair Cockburn is an internationally known project witchdoctor and strategist. He co-authored the 2001 Manifesto for Agile Software Development and the 2005 project management "Declaration of Inter-Dependence" and has written several best-selling books.

**MENU**

A build-your-own taco buffet will be catered by Megan Faulkner Brown.

The meal cost is $12. You can prepay from the wiki or just bring cash to pay at the door.

Please RSVP:

http://www.phil801.com/devutah/index.php?title=2006_February_Event

Monday, February 20, 2006 6:28:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [1]  |  Trackback