Wednesday, May 03, 2006
Thanks to Scott Hanselman for the heads up.

I've been using Consolas for a few months now and it is easily one of the best programming fonts I've ever used... and I've tried an awful lot of them... (see here and here for others).

Once it is loaded, start pimping your IDE.
posted on Wednesday, May 03, 2006 6:42:19 AM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Monday, May 01, 2006
I wanted to share an experience I had last week while working with my development team. I think I've mentioned this before, but we're the first group in my company to move to .NET 2.0. As a result, we're also the first to get to really use Visual Studio 2005. We had been working on mockups and UI designs with our users for quite a while on this project.

Finally, we were getting ready to start work on the internals. The three of us met in a conference room with a projector and I pulled up the Class Designer in Visual Studio. I've done team-coding a few times before, where one person is typing while everyone else is yelling out bugs or typos. While the process can be annoying, it also tends to produce less-buggy code. Doing the same thing with the Class Designer worked out really well. It helped us visualize how everything would tie together. We were drawing out our code, but behind the scenes, the Class Designer was also spitting out workable code!

I don't think I could use the Class Designer in all cases, but it really does force you to think about design issues and it makes for a good team development product. It also helps ease developers who aren't as comfortable with OO concepts see how inheritance is working. Give it a try and let me know how it works for you.
posted on Monday, May 01, 2006 11:36:56 AM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Thursday, April 27, 2006

I've really become a fan of MSN Desktop Search at work. I don't really use the toolbar at all, because I've got tabbed browsing in both Firefox and the IE7 beta, but the search features are great. I also like it better than Google's offering because the results don't pull up in a webpage. Even with all the buzz over AJAX lately, there is still a lot more interaction that can happen with a true client application.

Anyway, on to Desktop Search. It makes finding emails SO MUCH easier. The ability to use special search keywords makes it even better. For example, let's say I wanted to find all emails from me. Here's what I could do:

kind:mail from:David Mohundro

Voila! I now have all emails from me. The kind keyword lets you specify things like mail, pictures, documents, etc. If you want to get even more detailed, you can use things like the ext keyword and specify file extensions. Here's a search to find all icon files that have 'mail' in the name.

ext:ico mail

I haven't seen an all-encompassing list of all of the different keywords that you can use with Desktop Search, but there are quite a few if you'll look in the Desktop Search Help under Advanced Users.

And don't forget to use CTRL+ALT+M to get focus to your search box!

NOTE: If you're running into performance problems with it, check out this KB download. It really helped speed Desktop Search up on my PC. I couldn't work without it now.

posted on Thursday, April 27, 2006 11:47:24 AM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Wednesday, April 26, 2006
Never heard of PowerShell you say?

I hadn't either, at least until today. That's because it used to be called Monad. Microsoft released the RC1 of PowerShell today and it is pretty sweet. Basically, it offers scripting and CLI access to the .NET Framework. Instead of using cmd.exe, you'll be using PowerShell.exe. I haven't used it much yet, but it is really cool. Just as a quick example, try this out in PowerShell:

$var = "This is a sweet"

Now, type $var. and then hit tab.

OH WOW! Tab completion for System.String from the command line!

Check it out!
posted on Wednesday, April 26, 2006 11:44:27 AM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Friday, April 21, 2006
Continuing in the tradition of posts on Visual Studio WSoD's, I ran into another one today that gave me this error: "Object does not match target type."

Okay... super.

Luckily, I got some warnings with line numbers. They pointed me to a line in my designer code that looked like this:

CType(Me.MyUserControlInstance, System.ComponentModel.ISupportInitialize).BeginInit()

The other error was the same line except it was the matching EndInit call.

Similar to before, I was working with code that was in the process of being updated to the .NET 2.0 Framework. I had been working with a control that was inheriting from a .NET 1.1 control. The ISupportInitialize code had been in there for the 1.1 parent. The designer didn't mind at all until I moved the parent control over to 2.0. The solution was easy enough... just take the ISupportInitialize code out. I'm not sure if this is the recommended solution or not (I didn't Google it for too long), but it works.
posted on Friday, April 21, 2006 2:34:20 PM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Friday, April 14, 2006

Ever seen this error in Visual Studio 2005?

I've seen it all too often and it is really annoying.

However, I did find a possible fix today. I was working in a project that had multiple assembly references. One of the references was using a 1.1 assembly, so it came along for the ride. By simply removing that reference, I was able to view my form without any problems. If I tried to add the reference back, I would get the designer error again. I reworked the assembly being referenced to not use any 1.1 components and... lo and behold... the designer errors stopped.

Is this just a really random bug or is this a subtle way to push people to migrate to .NET 2.0?

posted on Friday, April 14, 2006 2:09:51 PM (Central Standard Time, UTC-06:00)  #    Comments [3]
I had some code that I was porting from .NET 1.1 to .NET 2.0 today. The code I had was checking the version of comctl32.dll to see if it was version 6 or greater to determine if the application supported visual styles or not. As I didn't write that code, I'm not sure if that is a valid way to check for visual style support in .NET 1.1.

I DO know that in .NET 2.0, that check doesn't necessarily work correctly; however, there is a new way to check that is much easier and more reliable -- Application.RenderWithVisualStyles. If you call Application.EnableVisualStyles in your Sub Main method, this boolean will be set to true. That's all you need to check!

See MSDN documentation here.
posted on Friday, April 14, 2006 10:50:11 AM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Thursday, April 13, 2006
Check out this article on ABC News. Or this press release from Winternals.

Apparently, a few members of Geek Squad have been using pirated versions of software from Winternals. In case you're unfamiliar with Winternals, they're the enterprise side of Sysinternals, which provides the excellent Process Explorer as well as a few other invaluable tools. Mark Russinovich, who discovered the original Sony DRM rootkit, is one of the people who established the company.

Way to go Best Buy.
posted on Thursday, April 13, 2006 12:06:37 PM (Central Standard Time, UTC-06:00)  #    Comments [0]
Mozilla Firefox 1.5.0.2 was released today. At first glance, it seems to be a lot more stable than 1.5.0.1. I had all sorts of issues with the last version randomly crashing on me. In their defense, it seemed to be a combination of some of the extensions I was using and the corporate proxy. I never had any problems at home using the same extensions.

Check it out.

(via Neowin.net Software)
posted on Thursday, April 13, 2006 11:51:05 AM (Central Standard Time, UTC-06:00)  #    Comments [0]
I stumbled across this post by Mike Woodring today. Apparently, the UserState property from the BackgroundWorker isn't accessible from the RunWorkerCompleted event. What in the world???

Anyway, I wasn't actually looking for information on the UserState property -- I was trying to find some information on the Error property off of RunWorkerCompletedEventArgs. It gets populated when an exception is thrown in your background thread. The weird thing is, I couldn't get my code to fall in there. The debugger kept popping up on the line where I was actually throwing the exception. Believe it or not, but that is actually the intended behavior... IF you're running in the debugger. Check out this post on the MSDN forums. If you're running standalone, then the Error property will be set as expected and you can check it. I wonder if you can continue on the exception and get to the RunWorkerCompleted event. I'll have to try that.

One last potential gotcha involving using the Error property: make sure it is the FIRST thing you check in your RunWorkerCompleted event handler. See this post on the MSDN forums for details there. According to Mike Woodring's post referenced above, if you access the Result property off of the RunWorkerCompletedEventArgs parameter and the Error property is populated or the Cancelled property is true, you'll get an invalid operation exception.

So now you know... and knowing is half the battle!
posted on Thursday, April 13, 2006 11:48:15 AM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Tuesday, April 11, 2006

MSBuild is a great tool. If you're not familiar with it, it is Microsoft's new build engine which was released with .NET 2.0. Visual Studio 2005 uses it behind the scenes. If you'd like to see it in action, pull up a VS2005 Command Prompt and type "msbuild YourSolution.sln" and watch the magic. It provides a much faster way of recompiling solutions and projects than reopening Visual Studio.

MSBuild runs off XML files. If you'd like to see one, just open up one of your vbproj or csproj files. Visual Studio projects default to the MSBuild format. Unfortunately, the solution files still aren't in an XML format. Because it uses XML, you can extend a build to do any number of tasks. I'll walk you through a very simple example.

My task is a Replace task that simple takes an input string (likely a file path or assembly name), an old value, and a new value and returns a value with all old values replaced with new values. It works exactly like the Replace method off of String objects.

First off, create a new Class Library project in Visual Studio. You'll need to add a reference to Microsoft.Build.Framework and to Microsoft.Build.Utilities. Next, for your class, inherit from Microsoft.Build.Utilities.Task. You'll be forced to override an Execute method. That's really all it takes to get a custom task. Everything else is driven off of public properties that are described by specific MSBuild attributes like "Required" or "Output".

Here's the source for my Replace task:

using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;

using System;
using System.Collections.Generic;
using System.Text;

namespace Tasks
{
    
/// <summary>
    /// Custom MSBuild task to perform String replacement. Primarily used for
    
/// Namespace to directory replacement (DTC.NRA.App -> DTC\NRA\App).
    
/// </summary>
    public class Replace : Task
    {
        
string _input;
        [
Required]
        
public string Input
        {
            
get { return _input; }
            
set { _input = value; }
        }

        
string _oldValue;
        [
Required]
        
public string OldValue
        {
            
get { return _oldValue; }
            
set { _oldValue = value; }
        }

        
string _newValue;
        [
Required]
        
public string NewValue
        {
            
get { return _newValue; }
            
set { _newValue = value; }
        }

        
string _results;
        [
Output]
        
public string Results
        {
            
get { return _results; }
            
set { _results = value; }
        }

        
public override bool Execute()
        {
            
bool success = true;
            
try
            {
                Results = Input.Replace(OldValue, NewValue);
            }
            
catch (Exception e)
            {
                Log.LogErrorFromException(e);
            }
            
return success;
        }
    }
}

The XML below is how I'm currently using this task.

<UsingTask TaskName="Tasks.Replace" AssemblyFile="C:\Development\References\MSBuildTasks.dll" />
<
PropertyGroup>
  <
RootDirectory>C:\Development\Build\</RootDirectory>
</
PropertyGroup>
<
Target Name="AfterBuild">
  <
Replace Input="$(RootNamespace)" OldValue="." NewValue="\">
    <
Output TaskParameter="Results" PropertyName="NamespaceDirectories" />
  </
Replace>
  <
CreateItem Include="$(OutputPath)\**\*.*">
    <
Output TaskParameter="Include" ItemName="FilesToArchive" />
  </
CreateItem>
  <
Copy SourceFiles="@(FilesToArchive)" DestinationFolder="$(RootDirectory)$(NamespaceDirectories)\%(FilesToArchive.RecursiveDir)" />
</
Target>

As you can see, I've got the UsingTask which references the assembly I built. Then you can use the Replace task like any other provided task. The above exactly can be copied into a Visual Studio project and it will copy the output files from your build into the RootDirectory you specify with the root namespace making up the folders beneath it (i.e. give the namespace System.Windows.Forms, this will copy your compiled assemblies to c:\Development\Build\System\Windows\Forms\*).

posted on Tuesday, April 11, 2006 11:43:25 AM (Central Standard Time, UTC-06:00)  #    Comments [0]