Wednesday, July 26, 2006

Recently, I've been experimenting with different console colors in PowerShell, primarily because the light gray on black is sort of boring (lame excuse, I know). I've been using Console and I had set the foreground color to green in the options. The only problem with doing this is that programs that output other colors, such as the error messages from MSBuild, are not displayed. I like seeing the color difference because the red text really jumps out at me and says that I have an error.

This got me curious about whether or not I could set a different color in PowerShell, instead of in Console. I stumbled across this TechNet article from way back when PowerShell was still MSH. Basically, you use the -foregroundcolor or -backgroundcolor switch against Write-Host to alter the color of the text you're outputting. That's certainly userful information if you're writing cmdlets, but I wanted to change the default color for the entire session.

If you've worked with .NET console applications, you may have seen System.Console.ForegroundColor. Well, this is available from PowerShell as well! .NET shell integration is great! So now, my PowerShell profile has a brand new line in it:

[System.Console]::ForegroundColor = [System.ConsoleColor]::Green

By doing this, whenever an application, cmdlet, function or whatever changes the default output color, like MSBuild does, you'll be able to see it. As a side note, I really like the PowerShell profile idea. Though options dialogs tend to be more user friendly, the PowerShell profile (try 'notepad $profile') is far more powerful and customizable.

posted on Wednesday, July 26, 2006 12:00:28 PM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Thursday, July 20, 2006
Like many other users of Visual Studio 2005, I've occasionally received the WSoD (White Screen of Death) while using the designer. And like a typical user, I blamed it on Visual Studio. That's what users do, right? They blame the program, because the user is always right. The same behavior that frustrates me to no end when users enter invalid data into MY program and then blame MY program (of course, if my UI were better, it wouldn't be as difficult to use, but that is another story). Anyway, my frustrations with VS2005 crashing and the WSoD's were in fact a problem with the user - me.

In one of my forms, I had some background threading work that was started when the form loaded. Like a good programmer, I had wrapped this threading work in a check against Me.DesignMode to ensure that it wouldn't try to do this work while in the designer. What I didn't know at the time is that the DesignMode property isn't set until AFTER the constructor fires. I checked around with some guys at work and I discovered that I wasn't the first one to discover this. They had already put a check against Application.ExecutablePath to see if it was devenv.exe. If it is, then we're in DesignMode. Simple as that!

So, all of my VS crashes and weird WSoD's have now been tracked back to my OWN code. HOWEVER, I would like to say that it would have been nice if Visual Studio had given me a better message to inform me that my designer code was trying to run background threads or something - in much the same way that my own code should work better and give my users better messages.

Ah, the joys of user interaction.

Note: This fixed the problem suggested after sending error reports that link to this hotfix (http://support.microsoft.com/?kbid=915038). If you're running into this, check and double-check the code in your UI constructors, INCLUDING base class constructors!
posted on Thursday, July 20, 2006 10:22:10 AM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Tuesday, July 18, 2006
Earlier today, Mark Russinovich announced that Microsoft had acquired Winternals and Sysinternals. In other words, some of the best administration tools available will be moving to Microsoft. Not only that, but by having Mark on board at Microsoft, they will have a great developer working with them. I think that this is a great move as far as bringing Mark on board. As far as acquiring Winternals and Sysinternals, I'm excited about that as well, so long as the products continue to be supported by Microsoft. I'm quite confident they will, too, because I know that Microsoft uses a lot of their tools as well (i.e. Process Explorer, RegMon, FileMon, etc).

Congratulations and I look forward to hearing more!
posted on Tuesday, July 18, 2006 11:11:58 AM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Thursday, July 13, 2006

Yesterday, I downloaded the Developer Productivity Tools video from the Wrox website that Scott Hanselman did for one of his presentations with a user group. He had a lot of great resources in the video but the command prompt tips he had were new to me. I've done some work with the console, but I've only recently been using it more, particularly with PowerShell coming along.

Scott's tip about customizing your prompt (from c:\dir\> to whatever) was really cool (also posted here). I knew that the prompt could be customized, but at the time I saw someone do it, I didn't have a good grasp of environment variables so it didn't really make sense what was going on, but Scott's video and his post have helped out a lot. They also prompted me to want to do the same with my PowerShell prompt!

The PROMPT environment variable trick doesn't work for the PowerShell prompt, but after a little digging around with Google, I discovered this post from Lee Holmes about the prompt function. If you have a function named prompt declared, PowerShell will use the value returned by that function to alter the display of your prompt. Here's my prompt function, which I have saved in PowerShell profile so that it will load every time (mine is located here C:\Documents and Settings\David\My Documents\PSConfiguration\Microsoft.PowerShell_profile.ps1)

# Initialize custom prompt
function prompt
{
   "PS " + (get-location).Path + [System.Environment]::NewLine + ">".PadLeft((get-location -stack).Count + 1, "+")
}

The only thing I haven't figured out yet is how to get a visual indication of how far in the stack you are (by using pushd and popd). Once I figure that out, I'll have a PowerShell prompt customized just like my cmd prompt!

UPDATE: I did some more research and discovered get-location -stack which will return everything on the pushd/popd stack. I've updated my prompt function accordingly. Now it matches my cmd prompt in every way!

posted on Thursday, July 13, 2006 12:00:39 PM (Central Standard Time, UTC-06:00)  #    Comments [0]

Last night, Cara and I were driving back from church during a thunderstorm. The entire time, I kept wishing that I had my digital camera with me, because the lightning was amazing! The storm was almost past just as the sun was going down, so the entire sky was almost golden in color. There was also a full rainbow all the way across the sky. While all of this was going on, the lightning was filling the sky, shooting from cloud to cloud. (side note - I'm not a writer, so if my descriptive writing skills are lacking, I apologize)

Well, today at work, I notice a post on digg about "incredible pictures" and "the moment lightning shared the sky with a rainbow." Hmm... that's interesting. But surely it couldn't be Fort Smith, Arkansas, now could it? But it is! Check out the digg post here.

The actual website with pictures is here at Daily Mail. The craziest part of all is that this Daily Mail site is apparently a British site! Be sure to check out the pictures.

posted on Thursday, July 13, 2006 11:24:56 AM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Tuesday, July 11, 2006

Just last month, I posted on how much I hated corporate content filters, specifically for blocking sites such as Scott Hanselman's site and del.icio.us, labeling them as "personal" sites. I've got good news and bad news regarding my rant from earlier. I spoke with some of my supervisors at work and the technology argument won over regarding Scott's site - they've unblocked it because it is a great technological resource. Unfortunately, del.icio.us does not fall into that category.

Today, I discovered another site that apparently is not a good resource for information: Wikipedia. I guess because users decide on the content of this online encyclopedia, it must be personal. In fact, here is what I see when I attempt to go there at work:

The following error was encountered:

  • Access Denied by SmartFilter: Forbidden, this page (http://en.wikipedia.org/) is categorized as: Personal.

I would post a screenshot, but it has the phone number for the corporate help desk and other related information. You know, one of the things that is most frustrating of all is that the entire content filtering system has nothing to do with productivity at work. Why? Because ESPN.com isn't blocked. And no, my company has NOTHING to do with sports. Enough people would complain if ESPN were blocked that they keep it open, while blocking sites that are actually beneficial to work, such as Wikipedia and del.icio.us. Oh, and by the way, Chris Sell's site is blocked because it is personal, too.

Just another frustration from the life of a programmer I suppose.

posted on Tuesday, July 11, 2006 3:39:37 PM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Monday, July 10, 2006

This will be a short post, but someone at work emailed me a link to a page that will let you see how fast you can type. Check it out here! Here are my results from my last run:

---------------------------
Windows Internet Explorer
---------------------------
Wow! Your typing speed (with 5 mistakes) is:

104.55 wpm
438.62 cpm
---------------------------
OK  
---------------------------

Not too bad, eh?

posted on Monday, July 10, 2006 9:08:02 PM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Wednesday, July 05, 2006
Just a short note, but for those who have been waiting for a version of NDoc that supports .NET 2.0 assemblies, there is a separate project out on SourceForge called NDoc 2005. It is still in beta, but it may be the way to go until NDoc gets moving again. Per comments at MSDN forums, it looks like the best way to go is to download the source and recompile it yourself. The binaries (at least the GUI binary) looks like it still has some issues.

Note: unfortunately, it still doesn't completely work for me... *sigh*

(from DotNetKicks)
posted on Wednesday, July 05, 2006 11:37:04 AM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Friday, June 30, 2006

If anyone out there knew about the BindingList before today, I sure wish one of you would have told me. Now I know, if you had known I was looking for something like the BindingList, you would have told me, but still...

Okay, all joking aside, the BindingList is what I've been trying to find for a long time. With Visual Studio 2005, the option to bind to an object data source is now possible (see screenshot).

The typical usage scenario for me with this data binding option is that I have just used .NET remoting to pull a collection of business objects back from a remote server. After that, I usually want to bind this collection to a datagrid or something like. For the past few months, I had used the new BindingSource object and set its DataSource property to my collection (usually a System.Collections.Generic.List<T> or a System.Collections.ObjectModel.Collection<T>). The problem I had was that any changes to either of those collections later would not fire ListChanged events. I had settled myself to the fact that I would have to reset the binding everytime.

Well, not so!

Dinesh Chandnani posted to his MSDN blog over a year ago about this subject. Too bad I didn't find it until today. In his post, he provides some very simple code examples, one of which details how to get a "DataGridView bound to business objects." *gasp!* Where have I been? This is what his code looks like:            

            DataGridView dgv = new DataGridView();

            BindingSource bs = new BindingSource();

            BindingList<Customer> bList = new BindingList<Customer>();

           

            // Fill bList with Customers

 

            bs.DataSource = bList;

            dgv.DataSource = bs;

 

I wish I known about the System.ComponentModel.BindingList<T> before now. It would've saved me so much time. If you're still trying to bind to a List or Collection like I was, take that guy out and bind to the BindingList instead! It really works the way you would expect it to!
posted on Friday, June 30, 2006 11:31:42 AM (Central Standard Time, UTC-06:00)  #    Comments [0]
I don't like repeating myself, but I need to again: if you're not subscribed to the PowerShell blog, then why in the world not?!? The PowerShell team has been on top of it lately providing some GREAT one-liner PowerShell scripts such as listing all of the sub-directories from the current directory or, as in the case today, listing all of the PROGIDs that you can use to instantiate your own COM objects from PowerShell script.

Sure, the scripts are fairly simple and are clearly obvious once you see them, but it displays the power right at your fingertips that PowerShell gives you. Currently, I'm not using it for any projects. I'm just using it as a productivity tool! The parsing you can do with directories and files is great and you can very quickly leverage your knowledge of .NET in the process.
posted on Friday, June 30, 2006 6:35:10 AM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Tuesday, June 27, 2006
I'm not sure how often people run into situations where the ManualResetEvent is needed, but I have a few times. System.Threading.ManualResetEvent provides an easy way to allow cross-thread communication and to let other threads know when something has completed. Most of the time that I've needed it, I have a property in a class that is loaded in another thread, but I want to prevent access to the property until it is loaded. From what I've seen, this is a great time to use the ManualResetEvent.

It is easiest to explain with some code snippets. Here's how you create the ManualResetEvent.

Private _dataLock As New ManualResetEvent(False)

The constructor takes a boolean that signifies whether the object is signaling or not. A signaling object implies that the action has been completed... we're done with the work. If signaling is false, the work hasn't finished yet.

To wait on the signal, use this code:

_dataLock.WaitOne()

You can also specify a period of time to wait instead of waiting indefinitely.

Once your background work is completed, you can call Set like so:

_dataLock.Set()

This begins signaling, so any calls to wait will stop blocking and will continue execution.

Here's a full code sample that shows how it would work and also gives a short example on the BackgroundWorker.

Imports System.ComponentModel
Imports System.Threading

Module Module1

    
Private _dataLock As New ManualResetEvent(False)

    
Sub Main()

        Thread.CurrentThread.Name =
"[Main]"

        Dim wkr As New BackgroundWorker
        
AddHandler wkr.DoWork, AddressOf wkr_DoWork
        
AddHandler wkr.RunWorkerCompleted, AddressOf wkr_RunWorkerCompleted

        wkr.RunWorkerAsync(
"Get to work!")

        Write(
"Waiting on the lock...")
        _dataLock.WaitOne()
        Write(
"we're back!")


        Console.WriteLine(vbNewLine &
"Press any key to continue...")
        Console.ReadLine()
    
End Sub

    Private Sub wkr_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs)
        Thread.CurrentThread.Name =
"[Work]"

        Write("DoWork just received this value: " & CStr(e.Argument))
        Thread.Sleep(
5000)

        e.Result =
"DoWork finished!"

        Write("DoWork is done so start signaling completion.")
        _dataLock.Set()
    
End Sub

    Private Sub wkr_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs)
        
Dim wkr As BackgroundWorker = DirectCast(sender, BackgroundWorker)
        
RemoveHandler wkr.DoWork, AddressOf wkr_DoWork
        
RemoveHandler wkr.RunWorkerCompleted, AddressOf wkr_RunWorkerCompleted
        wkr.Dispose()
    
End Sub

    Private Sub Write(ByVal s As String)
        Console.WriteLine(
String.Format("Thread: {0}, Message: {1}", Thread.CurrentThread.Name, s))
    
End Sub

End
Module

The output from running looks like this:
Thread: [Main], Message: Waiting on the lock...
Thread: [Work], Message: DoWork just received this value: Get to work!
Thread: [Work], Message: DoWork is done so start signaling completion.
Thread: [Main], Message: we're back!

Press any key to continue...
One thing to remember: do NOT put the call to Set (i.e. _dataLock.Set()) in the thread where you are waiting (i.e. _dataLock.WaitOne())! You'll never get the signal because that thread is already blocking! Because of this, make sure your call to Set always happens in the DoWork event of the BackgroundWorker instead of the RunWorkerCompleted event.
posted on Tuesday, June 27, 2006 11:59:56 AM (Central Standard Time, UTC-06:00)  #    Comments [0]