Scott Hanselman

Web 2.0 Explained in Video by Michael Wesch

February 8, '07 Comments [12] Posted in Musings
Sponsored By

It moves fast, so pay attention, but this is the single best 5-minute explanation of Web 2.0 I've seen. It was created by Michael Wesch, Assistant Professor of Cultural Anthropology at Kansas State University.

It's absolutely worth your five minutes.

I'm personally interested in what your spouses and parents thinks about it.

Too fast? Too intense? To many concepts too fast? Or does it open their eyes and help them to "get" Web 2.0? 

Dad, what do you think?

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

KB928388 Breaking Tests with Windows DST TimeZone Patch and Past Dates

February 8, '07 Comments [18] Posted in Musings | NUnit | Programming
Sponsored By

UPDATE: It appears that what we suspected is true, Windows understands one set of DST rules. Whatever the current DST rules are are applied to all dates. This doesn't make sense to me as that would make the 2005 test below fail also, and it doesn't. More as it comes in.

UPDATE#2: Seems that a new "Dynamic DST" section is added for future OS's, like Vista, for handling future DST time changes. This change will affect all Windows OS's equally - that is, you don't need to custom code for one OS versus another. If congress, in their infinite wisdom, decides to change the laws of Time and Space again, Vista and other OS's will require only a registry change, and past time rules will still apply. Thanks to Tim Heuer for helping puzzle through it all.

One of our Architects at Corillian, Paul Gomes, led the team that designed our .NET-based OFX Banking Server. That product happens to have ridiculously good Code Coverage and a metric-crapload of Unit Tests. Recently a build server had the Daylight Savings Time (DST) Windows KB928288 patch applied. Immediately an internal Date-related test failed. 

Paul dug into it and boiled it down to this simplified test that takes a date in March of 2006 and converts it to GMT.

   1:  [TestFixture]
   2:  public class DSTTest
   3:  {
   4:        private const string DATEFORMAT = 
@"yyyyMMddHHmmss.fff[0\:G\MT]";
   5:   
   6:        public DSTTest(){}
   7:   
   8:        [Test]
   9:        public void TestDateInThePast()
  10:        {
  11:              DateTime myDate = DateTime.ParseExact(
                       "2006/03/17 11:42:33",
                       "yyyy/MM/dd HH:mm:ss",
                       CultureInfo.InvariantCulture);
  12:              string myDateAsString = myDate.ToUniversalTime().ToString(
DATEFORMAT, CultureInfo.InvariantCulture);
  13:              Assert.AreEqual("20060317194233.000[0:GMT]",
                       myDateAsString);
  14:        }
  15:  }

The output is interesting. Note that we're comparing strings in this case for clarity.

Output from unit test:

TestCase 'DSTTest.DSTTest.TestDateInThePast'
failed:
String lengths are both 25.
Strings differ at index 9.
expected: <"20060317194233.000[0:GMT]">
but was:  <"20060317184233.000[0:GMT]">
---------------------^
c:\dsttest\dsttest.cs(19,0): at DSTTest.DSTTest.TestDateInThePast()

I first thought that this was no problem and I said to Paul:

Makes sense…that date in your test is inside the DST boundary, so we switch from -8 to -7.  11:00 becomes 18:00, rather than 19:00. We “sprung forward.”

However, Paul reminded me that we were testing a date within 2006! We're testing the 17th of March, 2006, outside of DST. Note the table below. I'd expect that day to be DST for 2007, but not 2006.

Here's where it gets really weird. Let's try the 12th of March, and try dates in 2005, 2006, and 2007. Note that when the time is 02:59:59am on March 12th, 2006, the test succeeds, but it fails at 3am, one minute later. Again, note that this is using a date in 2006, where DST started in April.

   1:              [Test]
   2:              public void TestDateIn2007Succeeds()
   3:              {
   4:                    DateTime myDate = DateTime.ParseExact(
"2007/03/12 03:00:00",
"yyyy/MM/dd HH:mm:ss",
CultureInfo.InvariantCulture);
   5:                    string myDateAsString = myDate.ToUniversalTime().ToString(
                             DATEFORMAT, CultureInfo.InvariantCulture);
   6:                    Assert.AreEqual("20070312100000.000[0:GMT]",myDateAsString);
   7:              }
   8:   
   9:              [Test]
  10:              public void TestDateIn2006Succeeds()
  11:              {
  12:                    DateTime myDate = DateTime.ParseExact(
"2006/03/12 02:59:59",
"yyyy/MM/dd HH:mm:ss",
CultureInfo.InvariantCulture);
  13:                    string myDateAsString = myDate.ToUniversalTime().ToString(
                             DATEFORMAT, CultureInfo.InvariantCulture);
  14:                    Assert.AreEqual("20060312105959.000[0:GMT]",myDateAsString);
  15:              }
  16:   
  17:              [Test]
  18:              public void TestDateIn2006Fails()
  19:              {
  20:                    DateTime myDate = DateTime.ParseExact(
"2006/03/12 03:00:00",
"yyyy/MM/dd HH:mm:ss",
CultureInfo.InvariantCulture);
  21:                    string myDateAsString = myDate.ToUniversalTime().ToString(
                             DATEFORMAT, CultureInfo.InvariantCulture);
  22:                    Assert.AreEqual("20060312110000.000[0:GMT]",myDateAsString);
  23:              }
  24:   
  25:              [Test]
  26:              public void TestDateIn2005Succeeds()
  27:              {
  28:                    DateTime myDate = DateTime.ParseExact(
"2005/03/12 03:00:00",
"yyyy/MM/dd HH:mm:ss",
                             CultureInfo.InvariantCulture);
  29:                    string myDateAsString = myDate.ToUniversalTime().ToString(
                             DATEFORMAT, CultureInfo.InvariantCulture);
  30:                    Assert.AreEqual("20050312110000.000[0:GMT]",myDateAsString);
  31:              }
  32:        }
  33:  }

What are we missing, dear reader? Is there a problem (bug?) with the registry-based Windows DST Patch?

I'm leaning towards assuming it's us, but I wanted to ask you. It seems that the data points towards this patch not working with dates in 2006. Not a huge deal, but non-trivial,IMHO.

As an aside, but very slightly related note, Steve Harman had an interesting bug where his Unit Tests were expecting to see "Tijuana" at the end of his TimeZone's Display Name. Since Mexico isn't following our lead (if it could be called a "lead") and changing their DST, so Tijuana isn't in PST proper anymore.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Corillian, CardSpace, and Open ID - Digital Identity is happening

February 7, '07 Comments [4] Posted in Corillian | Identity
Sponsored By

I totally stole the picture at right from Ashish Jain's blog post on CardSpace/OpenID Integration. It's a great image. Ashish works for PingIdentity and is down at the RSA Conference right now, along with Corillian it turns out. Ping is demonstrating a prototype OpenID IdP server that uses CardSpace for authentication at runtime.

Today JanRain, SXIP, Verisign and Microsoft announced that they'd collaborate on interoperability between OpenID and CardSpace. It's so refreshing to see folks in Web 2.0 getting along so well and moving the ball forward.

While some are surprised that folks are actually getting along, Dare puts it best when he says:

"With OpenID it didn't take as long for us to go through the NIH<->FUD<->Acceptance<->Approval<->Adoption cycle that I've come to expect from my fellow B0rg. It seems we have adapted."

Corillian (my company) was involved in the Identity Press Release today as well with a joint demo between Corillian, Wachovia and Arcot, led on the Corillian side by the tireless Stuart Celarier.

To further enable the vision of secure and easy anywhere access, Microsoft today announced the following product milestones and industry alliances:
...
On the heels of the Windows® CardSpace™ general availability launch in Windows Vista™, Microsoft demonstrated momentum with industry partners that are working to apply this technology to help consumers realize a more confident online experience. This includes the announcement of collaboration on use of Windows CardSpace with the OpenID 2.0 specification. Through the support of the WS-Trust-based Windows CardSpace experience, consumers can take advantage of increased security against phishing attacks without adding complexity to their identity management experience. Also at the conference, Wachovia Corp., Arcot Systems Inc. and Corillian Corp. showcased a proof of concept demonstration using Windows CardSpace to deliver a simpler and safer online banking experience for customers.

We've been looking at Digital Identity 2.0 solutions for at least 2 years now at Corillian led in part by our multi-factor authentication product and other identity solutions, all designed to stop phishing. We've integrated our suite with CardSpace, and that's what we're demoing at RSA. OpenID was next on my list. If you're not familiar, OpenID is different from CardSpace, as explained by Kim Cameron in that it assumes two things:

  1. Every person has a URL to which they lay claim.
  2. Every URL has an identity provider that “speaks for” it.

He summarizes:

"All in all, the closest analogy is to using an email address as an identifier by asking what email address you own, sending you the email, and getting you to click a link showing you own the email.  In this case the relying party depends on the underlying mail system, DNS, and all that.  OpenID replaces email with web URLs.  So it’s a lot more direct."

Digital Identity is getting closer with InfoCard/CardSpace, OpenID and i-names starting to converge on something very real. Here's some fun links to check out for yourself:

OpenID and CardSpace together are going to cover the maximum number of platforms, the maximum number of browsers and make the end-user experience (like my Mom's) more secure and easier to use that ever before. I'm stoked that Corillian's involved in the banking back-end side of things with folks like Arcot and Wachovia and I'm jazzed to be architecting, in a small way - along with my fellow wonks here at Cori - something called Banking 2.0. I'm looking forward to logging into a Corillian bank using OpenID and/or CardSpace. If you're down in SFO at the RSA Conference, go see our InfoCard Banking Demonstration!

Also, one of these days we'll get another DasBlog release that includes Kevin Hammond's good CardSpace work as well as OpenID. It's only a matter of doing it. You can also CardSpace-enable Community Server if you like.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Showing Video on an Optimus Mini Three

February 6, '07 Comments [13] Posted in Coding4Fun | Programming | Reviews | Screencasts | Tools
Sponsored By

I got frustrated with MSBUILD today so I took a lunch break to clear my mind and decided to play with my Optimus Mini Three (user's manual). The hardware is really lovely. Sincerely. Each key is 96x96 24-bit color and very bright.

However, while their software configurator is pretty as heck, their Plugin Model is stuck in the world of VTables and is largely unusable for the general hacker out there. If you want to write a plugin, you do it in C++ and implement a Create() method and export it. There are three pure virtual methods that a plugin writer needs to implement, GetInfo, Paint, and OnKeyDown. My preferred software environment is managed. Full stop. I'm not going to apologize for preferring it. I was a bad-ass in C++ back in the day, but I fully recognize that those days are over, and I'm not going to write another lpcszcbFoo* again.

I'm pretty disappointed that I'd need to do all that unmanaged dancing. That said, if you, dear reader, would like to dance, I'd like an unmanaged shim in C++ that forwards these three calls to a parallel C# managed interface. Any takers? Give me a call. I'm sure we could work on it together and give it back to the company so their plugin model wouldn't suck so much. It'd really make the device take off, I think. I'd love to do a Continuous Integration widget.

Anyway, while they are a USB device, as with all good (read: usable/hackable) USB devices they are really a "Prolific USB-Serial" Device so they are addressable via a virtual COM port and they have a well defined spec. So instead of a plugin, this is currently a command line app. I suspect it'd be pretty easy to make it a Tray App and basically rewrite their config app in .NET.

They also include a C# sample that pushes bitmaps to the buttons as byte[] arrays. I used the existing IVideoSource libraries from the brilliant Andrew Kirillov (he worked on the motion detection baby article for Coding4Fun with me) and captured each frame from the AVI and resized it to 96x96 before pushing it to the Mini Three.

The SendToButton method takes a .NET Bitmap and a button number apart and sends it as an array that's 96x96x3 (3 for R,G,B). It calls the Optimus C-style library via PInvoke calls.

public unsafe static void SendToButton(int button, Bitmap i)
{
    byte[] bmpBytes = null;
    BitmapData bData = i.LockBits(new Rectangle(new Point(), i.Size), 
ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
    try
    {
        // number of bytes in the bitmap
        int byteCount = bData.Stride * i.Height;
        bmpBytes = new byte[byteCount];
 
        // Copy the locked bytes from memory
        Marshal.Copy(bData.Scan0, bmpBytes, 0, byteCount);
    }
    // don't forget to unlock the bitmap!!
    finally
    {
        i.UnlockBits(bData);
    }
    IOptimusMini.ShowPictureBlocking(button, bmpBytes);
}

Here's a fantastically poor video taken with a cell phone camera that shows an AVI of a plane landing on the second mini-three button. The frame rate is crap, but it'll do. I've also got the Mini Three showing my infant son's internet "cradle cam" via a secure MJPEG stream as well. I think I'll do a Vista Side Show driver at some point as well.

Video: Video on an Optimus Mini Three. I'll do a more complete Coding4Fun Article soon.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

How to change the width of the text insertion cursor

February 6, '07 Comments [9] Posted in Musings
Sponsored By

I got this question today:

Do you know how to change the icon used for the blinking insertion point in VStudio?  I’d like to make it a little more visible…

Here's how to change the width for that little "i-bar." Go to Control Panel | Accessibility, then to the Display Tab, and move the Width Slider to the right.

The accessibility stuff in Windows is very nice. I say that as someone who used to have VERY bad eyes and then got Lasik'ed by a machine running Windows 98.

Have you been LASIK'ed? How'd it go?

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.