Keith's profileKeith Hill's BlogPhotosBlogListsMore Tools Help
    November 13

    Windows 7 Media Center Update

    Well my cheap-o ($50) 500 GB hard drive went belly up with a “S.M.A.R.T status bad” error after just two days – RMA time.  So it was off to Best Buy for a replacement drive.  I completely reinstalled Windows 7 and amazingly this time it recognized my Audigy2 sound card and my modem.  And without me installing any of the original Gateway drivers the front panel HID buttons work including the Home button *and* the IR receiver works!  Excellent.  The only thing I didn’t get back was the front panel display that mostly shows the current time.  Definitely can live without that. 

    Now we are still running into the “Copying Prohibited” errors watching live TV and this is starting to annoy the family. Fortunately you can switch channels, wait for a bit and then switch back to get around this blockage.  These seem to be popping up a lot during commercials.  One other issue is that I haven’t had any luck getting a DVD movie to play.  That kind of sucks except that the kids mostly watch movies off the DVD library.  And I can watch DVDs via our XBOX 360 – as long as I crank the volume so I can hear the movie above the sound of the XBOX fan noise.

    November 11

    PDC 2008 Recap Presentation

    Jeff Certain (VB MVP) and I gave a PDC 2008 recap last night at the Northern Colorado .NET User Group.  It went pretty good given the short notice.  Jeff contacted me earlier that day and told me the presentation had been pushed up a month because another speaker couldn’t make it.  :-)  Here are the slides:

    Team Foundation PowerShell PSSnapin in October Team Foundation Power Tools Drop

    Oh thank you, thank you TFS team!!!  This is a great development because it enables version control queries for mere mortals (ie those of us not well versed in SQL Reporting Services).  It also enables easily scriptable queries.  With the October Team Foundation Power Tools drop, you get a PowerShell console icon in the start menu or you can just add the following to your profile:

    Add-PSSnapin Microsoft.TeamFoundation.PowerShell

    Once you’ve done that, here are the new cmdlets you get:

    • Add-TfsPendingChange
    • ConvertTo-FixedByte
    • ConvertTo-FixedPath
    • Get-TfsChangeset
    • Get-TfsChildItem
    • Get-TfsItemHistory
    • Get-TfsItemProperty
    • Get-TfsPendingChange
    • Get-TfsServer
    • Get-TfsShelveset
    • Get-TfsWorkspace
    • New-TfsChangeset
    • New-TfsShelveset
    • Remove-TfsPendingChange
    • Remove-TfsShelveset
    • Restore-TfsShelveset
    • Select-TfsItem
    • Set-TfsChangeset
    • Update-TfsWorkspace

    Now that you have the Team Foundation snapin loaded, you can start doing some interesting stuff like finding out who has pending changes older than 30 days:

    PS> Get-TfsPendingChange . -User * -Recurse | 
    where {$_.CreationDate -lt (get-date).AddDays(-30)} |
    select OwnerName -expand PendingChanges |
    format-table Filename, ChangeType, OwnerName, @{l="Server Folder";e={$_.ServerItem}} -auto

    Or say you want to see the level of checkin activity over the past 30 days:

    PS> $history = Get-TfsItemHistory . -Recurse -Stopafter 1000 | 
    Where {$_.CreationDate -gt (get-date).AddDays(-30)} |
    Sort CreationDate |
    Select Owner,@{n='CreationDate';e={$_.CreationDate.ToShortDateString()}}
    PS> $history | Group CreationDate -noelem
    Count Name ----- ---- 4 10/12/2008 7 10/13/2008 103 10/14/2008 67 10/15/2008 23 10/16/2008 13 10/17/2008 3 10/19/2008 3 10/20/2008 23 10/21/2008 19 10/22/2008 31 10/23/2008 67 10/24/2008 10 10/27/2008 13 10/28/2008 29 10/29/2008 7 10/30/2008 4 10/31/2008 3 11/3/2008 2 11/4/2008 7 11/5/2008 10 11/6/2008 3 11/7/2008

    If you have the excellent PowerGadgets, then you could do this:

    PS> $history | group CreationDate | Out-Chart -Caption "Checkins/Day" -Size 480,320 -modal

    And get this nice graph:

    image

    Now if I’m a project manager on a large team, I might want to see “who” is checking in a bunch of code right before a deadline.  That is easy enough:

    67> $history | Group CreationDate | 
    Foreach { "$($_.Name) - Total Checkins: $($_.Count)";
    $_.Group | group Owner |
    sort @{e={$_.Count};asc=$false},Name |
    Format-Table Count,Name -auto }
    10/12/2008 - Total Checkins: 4 Count Name ----- ---- 4 Acme\moe 10/13/2008 - Total Checkins: 7 Count Name ----- ---- 3 Acme\moe 2 Acme\socrates 1 Acme\curly 1 Acme\optimus

    Querying is an especially powerful aspect of PowerShell and teamed with these new Team Foundation version control cmdlets, you have access to some interesting information.

    psmdtag:snapin: Team Foundation Power Tools
    psmdtag:snapin: TFPT

    November 07

    Taking Windows 7 Media Center for a Spin

    After getting back from the PDC, the Windows 7 excitement drove me to upgrade my old Gateway FMC-901X running MCE 2005 (pre-rollup 2) to Windows 7 Media Center.  I bought 2 GB of memory for it and a new 500 GB harddrive (so I could preserve the original MCE 2005 setup).  The Win7 install was a breeze and went pretty fast.  But getting the Vista Audigy2 driver on there required me to trick the installer program into thinking it was installing on Vista (thank goodness for that “Compatibility” tab on the file Properties dialog).  Unfortunately the front panel display driver doesn’t seem to work.  I could install it but the built-in IR receiver doesn’t work anymore.   Oh well, I’m buying an inexpensive Pinnacle MCE remote that comes with an IR receiver.  That should take care of that problem.  Curiously, the front panel button (HID) driver does seem to work, well except that the “Home” button doesn’t work.

    Setting up W7 MCE was also pretty easy.  It even recognized my Hauppauge PVR500 card right away - nice!  I also setup my XBOX 360 as an extender which was very straight-forward.  I pointed W7 at my Windows Home Server music, photo and DVD collection and it all works great.

    But (you knew there was a but coming, right?), we keep getting these "Copying Prohibited – Protected Content" messages which stops "live" TV in the middle of a show.  I was trying to watch the Browns/Broncos game last night and it did this several times at what appeared to be commercial breaks.  I did a bit of research and came across the recent KB950126 and KB955519 patches.  I downloaded the Vista version of these but they won't install on Windows 7 – not too surprising.  Any chance we could get these updates (even as a hotfix) on Windows 7?  Pretty please with sugar on top.  :-)  My family would love to help you collect CEIP data (yes, I turned that on) using Windows 7 Media Center.

    BTW *this* kind of crap is why folks despise and I mean DESPISE DRM.

    November 04

    Windows 7 “Personal Documents” – You’ve Got to Be Kidding Me

    Take a look at this screen from the PDC M3 Win7 build:

    image

    WTF??? Is that schizophrenic or what?  Fortunately, at the very least, the real folder name appears to be “Documents” from the command line.  Whew!  However the Windows Explorer can’t seem to make up its own mind on what to call it. 

    Here’s my two cents – Vista did a good, no GREAT, service by nuking all the *STUPID* “My <blah>” prefixes.  Please don’t let Win7 introduce an even worse prefix - “Personal”.  OK, I’ll get off my soapbox now.

    Windows 7 Resource Monitor

    Handle lists, searching for handle names, cool!  I wonder if Mark Russinovich had a hand in this?  Whoever it was, we owe them some thanks!  SysInternals is a great set of tools but it is so nice to have this functionality built into Windows 7:

    image

    C# 4 – It’s a Dynamic World After All

    Well after years of maintaining a pure statically type checked face, the C# team is relenting a bit on this stance.  In C# 4.0 you will be able to write code that uses late binding in a much easier way.  Note that VB has had this capability since it shipped.  What this means it the C# gets one new keyword “dynamic” which actually carries static type information (ie just that the associated variable uses runtime binding) and that type information flows throughout your program as you dynamic variables in other places. 

    Also, in order to make Office (COM OM) programming easier from C#, they have added support for optional and named parameters.  This makes using certain Office methods that take say 30+ parameters, most of them optional, much easier to invoke from C# 4.  Here’s what these features look like from a very simple usage:

       1: static void Main(string[] args)
       2: {
       3:     // Unlike the type inferencing keyword var which retains compile-time type checking
       4:     // the use of the dynamic keyword tells C# *not* to type check at compile time and
       5:     // let the runtime handle member resolution and invocation.
       6:     dynamic foo = "I'm a string";
       7:  
       8:     // I compile just fine but throw RuntimeBinderException at runtime
       9:     foo.MethodThatDoesntExist();
      10:  
      11:     Method("Hi");
      12:     Method("Hi", ignoreCase: true);
      13:     Method(count: 10, ignoreCase: true, str: "Hi");
      14: }
      15:  
      16: // Optional parameters and named parameters
      17: static void Method(string str, int count = 5, bool ignoreCase = false)
      18: {
      19: }

    Note that when you run this program and hit line 9, you get this error:

    image

    Here’s the IL for the code above:

       1: private static void Main(string[] args)
       2: {
       3:     object foo = "I'm a string";
       4:     if (<Main>o__SiteContainer0.<>p__Site1 == null)
       5:     {
       6:         <Main>o__SiteContainer0.<>p__Site1 = CallSite<Action<CallSite, object>>.Create(
       7:             new CSharpCallPayload(Microsoft.CSharp.RuntimeBinder.RuntimeBinder.GetInstance(), 
       8:             false, false, "MethodThatDoesntExist", typeof(object), null));
       9:     }
      10:     <Main>o__SiteContainer0.<>p__Site1.Target(<Main>o__SiteContainer0.<>p__Site1, foo);
      11:     Method("Hi", 5, false);
      12:     bool CS$0$0000 = true;
      13:     Method("Hi", 5, CS$0$0000);
      14:     int CS$0$0001 = 10;
      15:     CS$0$0000 = true;
      16:     string CS$0$0002 = "Hi";
      17:     Method(CS$0$0002, CS$0$0001, CS$0$0000);
      18: } 
      19:  
      20:  
      21: private static void Method(string str, 
      22:                            [Optional, DefaultParameterValue(5)] int count, 
      23:                            [Optional, DefaultParameterValue(false)] bool ignoreCase)
      24: {
      25: }

    The one thing here I really don’t like is that it appears the “optional” value is being embedded at the call-site (see line 11 above).  This has versioning issues.  I hope I’m wrong about this or the C# team changes this behavior before shipping.  Note that on line 4 you can see the call-site caching that happens for dynamic invocation.  This means that the first dynamic call to this method will be expensive but future invocations (say if this code was called a lot) will be much faster. 

    One of the big wins for the C# “dynamic” approach is that it normalizes how you do late binding in C# rather than having different APIs for .NET late binding (aka reflection), COM interop, JavaScript interop (as in Silverlight) and interop with dynamic languages like IronPython and IronRuby.  BTW you can write your own ObjectBinder to plug into C#’s late binding mechanism.  I don’t know any details but they said it could be done.  You can also implement “dynamic” objects in C# by implement IDynamicObject or deriving from DynamicObject.  Dynamic objects in C# don’t participate in compile time member resolution – that is done at runtime.  I can see some interesting uses of this in Mock frameworks.