# Wednesday, July 18, 2007
Unfortunately I found myself needing to use an out parameter in a legacy codebase, but couldn't figure out how to get it to work correctly with Rhino Mocks.  It turns out there's a special syntax for that.

From: http://en.wikibooks.org/wiki/How_to_Use_Rhino_Mocks/Out_and_Ref_Parameters

int theRef = 42;
int theOut = 0;
Expect.Call(obj.MyMethod(ref theRef, 0, out theOut)).Return(True).OutRef(13, 666)


Wednesday, July 18, 2007 5:17:16 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, July 06, 2007
So I spent a few hours on the 4th of July learning to use Windows PowerShell.  I was intrigued by the raw power available WMI, COM, and best of all .NET all from a scripting platform made for doing admin like tasks.  The best part is that the interfaces between local disk, UNC paths, and even registry keys are all the same.  So with my new tool in hand, I thought I would give my problem of recursive deletion of "_thumbs" directories another shot.

Get-ChildItem -path c:\temp -filter _thumbs -recurse | Remove-Item

How much simpler is that?!  That's what I wanted to do the first time with the regular windows command shell.  I'm sold, I'm using the Windows CommandShell from here on out - and you should too.

Friday, July 06, 2007 6:42:05 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Sunday, July 01, 2007
I needed to remove about 60 subdirectories named "_thumbs" from my pictures directory.  Of course manually doing this through Explorer wasn't something I was up for.  I tried to do it through the command line, but RD doesn't support multiple directories as inputs.  I wanted to do this:

dir /AD /B /S *_thumbs* | rd /s

but that didn't work, so I had to write my own RD command that is capable of piping input through it - which was still faster than doing it through Explorer.

dir /AD /B /S *_thumbs* | consoleapplication1

using System;
using System.IO;
using log4net;

namespace ConsoleApplication1
{
    class Program
    {
        private static readonly ILog Logger = LogManager.GetLogger(typeof(Program));

        static void Main(string[] args)
        {
            string input;
            do
            {
                input = Console.ReadLine();

                if (input != null)
                    DeleteDir(input);

            } while (input != null);
        }

        private static void DeleteDir(string input)
        {
            if (Directory.Exists(input))
            {
                Logger.InfoFormat("Deleting directory {0}", input);
                Directory.Delete(input, true);
            }
            else
                Logger.WarnFormat("Directory {0} does not exist", input);
        }
    }
}


Sunday, July 01, 2007 4:06:27 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [2]  | 
# Friday, June 29, 2007
There's nothing quite like running your application through the debugger for the first time in a day after 6 hours of coding only to realize the shared dev SQL instance is stopped.  Actually it's quite graitifying to know that I'm making a web page flow change and haven't run a SQL query or fired up IE once all day.  Thankfully my unit test have been giving me good feedback all day long.

+1 point for unit tests.
+1 point for refactoring previously untestable legacy code.
-1 point for sharing the same dev database!  I can't wait to fix that.

Friday, June 29, 2007 10:55:34 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
reg add "\\remotePCName\hklm\system\currentcontrolset\control\terminal server" /f /v fDenyT
SConnections /t REG_DWORD /d 0

Friday, June 29, 2007 4:27:29 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, June 27, 2007
Sometimes you want to share session between web apps, not just between web servers.  By default you cannot do this with the SQL Server session state provider because it keeps differently named applications session's separate.  To allow this, we can modify the TempGetAppID sproc in the ASPState database.  Most solutions I've seen to this just override the sproc and allow ALL web apps using this database to share session, or they are hardcoded to look for specific app names.  Neither of these options was appealing, and worse yet the second option wasn't even viable when using the builtin Visual Studio 2005 web server. 

The solution I came up with was to use the connection string "Application Name" as the appName.  If you are familiar with SQL Profiler you will recognize this.  By default all .NET applications report they have an application name of ".NET SQLClient Data Provider" unless you have overridden it in the connection string.  This allows me to pool sessions between web applications conditionally through a configuration change, that even works on the built-in Visual Studio 2005 web server (webdev.webserver.exe).  Here's the new sproc:

    USE ASPState
GO

ALTER PROCEDURE dbo.TempGetAppID
    @appName tAppName,
    @appId int OUTPUT
AS

    -- start change

    -- Use the application name specified in the connection for the appname if specified
    -- This allows us to share session between sites just by making sure they have the
    -- the same application name in the connection string.
    DECLARE @connStrAppName nvarchar(50)
    SET @connStrAppName = APP_NAME()

    -- .NET SQLClient Data Provider is the default application name for .NET apps
    IF (@connStrAppName <> '.NET SQLClient Data Provider')
        SET @appName = @connStrAppName

    -- end change

SET @appName = LOWER(@appName)
SET @appId = NULL

SELECT @appId = AppId
FROM [ASPState].dbo.ASPStateTempApplications
WHERE AppName = @appName

IF @appId IS NULL BEGIN
BEGIN TRAN

SELECT @appId = AppId
FROM [ASPState].dbo.ASPStateTempApplications WITH (TABLOCKX)
WHERE AppName = @appName

IF @appId IS NULL
BEGIN
EXEC GetHashCode @appName, @appId OUTPUT

INSERT [ASPState].dbo.ASPStateTempApplications
VALUES
(@appId, @appName)

IF @@ERROR = 2627
BEGIN
DECLARE @dupApp tAppName

SELECT @dupApp = RTRIM(AppName)
FROM [ASPState].dbo.ASPStateTempApplications
WHERE AppId = @appId

RAISERROR('SQL session state fatal error: hash-code collision between applications ''%s'' and ''%s''. Please rename the 1st application to resolve the problem.',
18, 1, @appName, @dupApp)
END
END

COMMIT
END

RETURN 0
GO


Wednesday, June 27, 2007 7:34:09 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [5]  | 
# Tuesday, June 26, 2007
I'm sure we've all seen this one at some point.  A comment that's less elegant than the code:

// these actions only occur if this is NOT a postback
if (!IsPostBack)
{
    if ((strDiscountCode != null) && (strDiscountCode != String.Empty))

...


WTF
Tuesday, June 26, 2007 9:08:43 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
Just because I was asked today, here's the spec to my new PC:
  • Antec Solara Sonata II case w/450 watt PS
  • Intel Core2 CPU E6600 @ 2.4GHz
  • ASUS P5B mainboard
  • 2GB of DDR2 RAM
  • 150GB SATA Western Digital 10,000rpm Raptor
  • NVidia GeForce 8600GT
  • Vista Business Pro 32bit (no Ubuntu yet...)
I mainly use this for development, but I also play some games.  Currently I'm catching up on Doom3 which I bought several years ago...

Tuesday, June 26, 2007 5:26:52 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
After spending all this money and time getting a new PC put together that was not only fast, but comparatively quiet, I was a little annoyed when I came home today and couldn't wake the PC up. All the fans and lights were on, but the video wouldn't display.  At first I thought it was a wireless keyboard and mouse driver issue, so I installed the latest MS drivers for them. Still it wouldn't sleep.  So then I thought it must be a power management or BIOS setting, but after combing through those and experimenting I didn't see anything that looked promising.  The one thing that did surprise me is that the default setting in the Vista pearl shutdown command is sleep rather than power off, which is the way it should be!

This made me wonder why my new PC was not in sleep mode when I came home today.  Last year I put together a new PC for my mom, and her PC went to sleep properly - i.e. no lights or fans running.  Clearly I had a sleep issue.  Long story short, it turned out I had two issues:

1. An old IEEE1334 card was forcing the system to power back on, but without any video display.  No amount of pounding on keys or pushing the power button would coerce it to do anything.
2. I had to go Into the Device Manager, find the mouse and keyboard, go to the properties on each one, go to the Power Management Tab, and UNCHECK "Allow this Device to wake the computer."

After I did those two things, I could properly put the system in sleep mode.  It seems to be using S4 fast sleep mode, because it powered back up almost instantaneously.  I feel much better now.

Tuesday, June 26, 2007 5:19:57 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, June 25, 2007
I wanted my external file based assembly references to behave like my project references when switching between debug and release configuration.  According to this very good Managing Dependencies document from Microsoft, you should always reference the release version of an external assembly and then use the "Reference Paths" in the project properties to override that setting to the debug folder if need be.  That sounded like extra work in the long run, and to be honest I would probably forget to do that until after I started my debug session.  Here's what I ended up doing to make Visual Studio automatically switch between release and debug versions of my external referenced assemblies:

  1. All my build output for all projects are setup to be copied to <working path>\build\<configuration>.  So when building a release build, that path is really d:\source\build\release.
  2. Add a reference to the release or debug version of the external file based assembly located in the directory mentioned in step 1.
  3. Unload the .csproj file from within Visual Studio that has the reference to the external assembly.
  4. Edit the unloaded project file and change the HintPath from ..\..\build\release\commons.dll to ..\..\build\$(Configuration)\commons.dll.
  5. Save, then reload the project.
Now you can use the built-in Visual Studio configuration manager to switch between debug and release external assemblies just like you can with project references.  Yeah!  Once less thing for me to mess up.

Monday, June 25, 2007 10:24:27 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Sunday, June 24, 2007

Its been a long while since I last purchased an entirely new PC, but today was the day that I finally replaced my trusty old Athlon XP based system.  I have a certain fondness for that computer, possibly because its been with me at every single employer I've had in the IT industry, thats a total of 4 employers over a span of 7 years.  Every single component except for the mainboard, the two hard drives, and the first 512MB of RAM have been replaced in that old system, in fact the power supply and the video card have been replaced twice over the years.  I think the longevity of the system was based largely on the uber reliable Gigabyte GA-7DXR mainboard, the two enormous (for the time) striped (RAID-0) 120GB Western Digital HDD's with 8MB cache, and a reliable install of Windows XP.  Now that I think about it, I can't believe I still have the original Windows install on that machine, especially when I consider the fact that I've had all sorts of beta software installed and uninstalled on that system over the years, and on top of that I've never had any anti-virus software.

Despite it being the longest living PC companion I've ever had, it was time to get a new one.  Things I hate about my old system:

  • The system was getting pretty slow especially when running several instances of Visual Studio with Re#.
  • The RAID controller never had a formal Windows XP driver, I was still using a Windows 2000 driver.
  • No Vista support.
  • The system would never power off.  If you tried to shut it down, it would turn off for 4 seconds then immediately power back on.
  • The amount of noise from all the fans was absolutely mind numbing and constantly reminded me its cousin was a jet engine.

My new system seems to have fixed ALL of the issues I had with my previous Athlon system it replaced.  I took special care to pick out quiet, yet fast components and it seems to have paid off in a big way.  Not only can I not hear my PC anymore, but the speed is just fantastic.  Here's the Windows Experience Index score:

Sunday, June 24, 2007 8:09:49 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  |