Tuesday, March 21, 2006

Last week we had overwhelming success with our SQL Server 2005 Overview event, that people have been banging down the doors for more.  By popular demand, therefore, we are pleased to invite you to a follow-up event.  If you were unable to attend the first session for one reason or another and would like to attend this one, please check it out!  We had a great time doing it and it was a lot of fun.

Three separate seminars are presented: SQL Server Development Platform, Business Intelligence, and Infrastructure.  The event is to be held on March 9th from 9:00 AM to 5:00 PM at the Microsoft offices in the International Center.

Date / Location:

March 29th, 2006, 9:00 AM - 5:00 PM
Microsoft Corporation
123 Wright Brothers Drive, Suite 100
Salt Lake City, Utah 84116
(801) 257-6400
http://www.microsoft.com/mscorp/info/usaoffices/rockymtn/saltlakecity.mspx

Registration:

Register today at http://www.microsofttraining.com/devonsites
Class / Invitation ID: 304560

Tuesday, March 21, 2006 2:00:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Saturday, March 18, 2006

We had, today, our first board gaming session in which we tried something completely different.  For some time now we've wanting to play Puerto Rico after hearing so much goodness about it.  In our usual monthly get-togethers we play Settlers of Catan, Carcassonne, Shadows over Camelot.  This time, however, we opted for a completely new game, seeing that one couple wasn't able to make it tonight.  Not one of us had ever played it so we were on even ground to start, which made for a lot of fun and discovery.

Wow! What a cool game!  At first the rules looked daunting - even after having read them some 3+ times.  They didn't really make a lot of sense until putting them into practice and then it was oh so simple!  The game was extremely well balanced and everyone had a great time.  We will definitely need to try the 6-player unofficial variation when we get together in our normal 3 couple gatherings.

If you're a board gamer and haven't tried it out, or are wanting something quite different and a blast, I highly recommend Puerto Rico.  I can't say that I've developed a strategy yet, as the first two games have been focused on learning the rhythyms and patterns in the game and learning how what I do and choose affects all the other players (and myself), but I'll be watching for more of the subtle nuances and tricks in future games.  I'm looking forward to it!

Saturday, March 18, 2006 5:05:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Thursday, March 16, 2006

We (fellow MVP Patrick Wright, our regional RD Scott Golightly, and I) had the opportunity to head down to the local Microsoft offices to participate in some free SQL Server 2005 training.  The day was split up into three sections.  Pat started out the day, presenting on Migration, Management, and Infrastructure.  Scott followed up with a talk on Business Intelligense, focusing on Reporting Services, Analysis Services, and Integration.  I finished off the day with a discussion on the Development platform, targetting the SQLCLR, TSQL enhancements, etc.

The event was completely booked and it appears that most everyone who registered showed up and we had some walk-ins too so it was a full house.  As far as I'm aware the even went very well and people left pleased with the day.

In the event that you missed it, we'll be putting it on again on March 29th.  As soon as I have the event details, I'll post them here and on the Utah .NET User Group site.

Thanks everyone for showing up and participating.  I had a great time doing it and look forward to the next opportunity.

Thursday, March 16, 2006 6:33:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 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