There are a few different reasons given, but the main one is that Microsoft have a lot of hardcore C++ OS programmers who didn’t want to switch to C#. Because C# is type-safe, it’s a lot harder to do some of the standard C tricks of peeking and poking memory locations, tweaking bits in registers, etc.
This is a shame, because while that type checking can be frustrating at times, it does give an awful lot of protection from malicious coding techniques. Given the rate at which Microsoft publishes Windows Security Updates, you’d have thought they’d be very keen to adapt a more secure computing environment.
Another reason given was performance: since .NET code is pseudo-interpreted, it is not as efficient as native C/C++ code. That’s a red herring though – my experience with .NET has been that it runs more than fast enough for almost anything you’re likely to do with it. Like any environment, you can easily write bad code that runs like a dog; you can also write good code that runs very fast indeed.
And as if to prove my point, the current non-.NET betas of Vista run incredibly slowly, at least on my Athlon 2400 system with 1 GB RAM and a very fast Radeon graphics card. Intel must be rubbing their hands with glee…