Scott Hanselman

Changes in the .NET BCL between 2.0 and 3.5

August 09, 2007 Comment on this post [8] Posted in Learning .NET | Programming
Sponsored By

(Actually between the BCL Version 2.0.50727.42 and 2.0 (Version 2.0.50727.1378)

API Changes from org2.0 to 2.0 - Windows Internet ExplorerI was thinking that while folks are blogging about all the new stuff in .NET 3.5 and VS2008 (or VS3.508 as I think to think of it) there must be other fixes here and there in the Base Class Library itself.

I googled around and couldn't find a list of what's changed in the BCL. I'm sure it's out there somewhere and I've missed it and the second I post this someone will post a better list in the comments, but anyway...

First, I look in C:\windows\assembly with Explorer. Remember that this is a "lie" - what you're seeing is a namespace extension's representation of the Global Assembly Cache, although a very useful one. Here's the new 3.5 stuff, sorting by version. This stuff is near all new. New assemblies, etc.

assembly

Nothing in here appears to have "rev'ed" like moving from 2.0 to 3.5 and kept the old version. One might expect to see System.Web 2.0 and then System.Web 3.5, but that's not the case from what I can see.

There is, however, a large amount of new (what I would call) BCL stuff in the new System.Core assembly. Remember that namespaces can exist across assemblies, so releasing a new assembly is a pretty decent way to get sweeping additive changes across a few dozen namespaces in a very compatible way.

Reflector says that System.Core includes new things in System.Threading, System.IO, System.Security, System.Diagnostics, and more. I would encourage you (as I do everyone who will listen) to download Reflector and do this:

  • Run Reflector
  • Hit the Home key on your keyboard
  • Hold down Delete until Reflector's window is clear
  • Press Ctrl-L, then Enter

...and you'll get this dialog. Reflector is smart enough to prompt you to fill up your empty assembly list, and the defaults are so useful that I usually just delete everything and pick one of these.

Start Default Assembly List

As you move around in Reflector, notice the "Location:" arrea at the bottom that tells you where the assembly is (although there are copies in the GAC).

image

Look at all the assemblies in the .NET 3.5 list and you'll see which ones live in the 2.0 directory, the 3.0 directory and the 3.5 directory.

While 3.5 is huge conceptually, on disk it's very small, consisting of the new compilers and basically these three assemblies:

  • System.Core
  • System.Data.Linq
  • System.Xml.Linq

There are other assemblies for MSBUILD improvements and such, but it's still very compact, from a "redistributable" point of view.

I would personally recommend that anyone who hasn't moved their 1.1 shop over to 2005, or who is starting out with .NET to just start with 2008/3.5. The multi-targeting stuff is very slick (I'll do a dissection soon, more detailed that ScottGu's post)

Has Anything Changed?

I wanted to find out what's changed between a standard Windows XP SP2 machine - totally fresh - with just the 2.0 runtime distributable installed, and my Vista machine with 3.5 on it.

There's a really great, but largely unknown, tool called Libcheck that you can download for free, that'll compare two versions of an assembly and show you the differences in a report. It'll look only at the public (inter)face of the assembly. In this case, that's exactly what I want.

It doesn't look to have been changed since 2005, so first I need to download and compiled it and hope it works. Fortunately it comes with source code and rather than spending time converting it to 2008, I just run the included nmake.bat that builds the three supporting libraries it needs and spits out libcheck.exe. Nice and easy (and lazy). There's a couple of obsolete warnings, but they're obsolete, not dead.

First, I brought up my 2.0 XP SP2 VM (again, fresh) and ran the .NET 2.0 Redistributable Package on it. This would be version 2.0.50727.42.

I went to the Libcheck folder and ran this command:

libcheck -store all org2.0

...and libcheck created a database of all the schmutz in 2.0.

Then I ran the same thing on my Vista machine with 3.5 - remembering that it's just going to look at the 2.0 Framework stuff on my system. This version of 2.0 was 2.0.50727.1378.

libcheck -store all 2.0

Notice that one was "org2.0" and the other '"2.0." I then copied all the org2.0 folder off my VM and onto my main machine, then ran:

libcheck -compare org2.0 2.0

The Report appeared in a folder called org2.0to2.0. Then I copied the report up to my blog, and it's available here.

Note: You can modify the text files in /RefFiles and use LibCheck on your own framework internal to your company. That's what we did at Corillian. There is apparently a much better version of this tool (this one is 3 years old) internal to Microsoft. I'll see what I can do to free it.

The percentage of churn was in the single digit percentages. Personally I find the report a fascinating read. You can see what was breaking, what was just added. You can see where new enums appeared and where overrides became virtuals and all sorts of things. Check it out, it's not that scary.

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 bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

Vista Pre-SP1 Performance and Reliability Fixes

August 08, 2007 Comment on this post [10] Posted in Bugs
Sponsored By

2723_Windows_Vista_logo Everyone knows that Vista SP1 is due out soon, but if you're having any trouble now (I'm not anymore), you might take a look at these two updates:

  • Performance Update - KB938979 - This one has some networking related fixes as well as fixes for some hibernation weirdness, as well as a possible fix for the now-legendary Explorer "estimated time remaining" issue.
  • Compatibility Update - KB938194 - This one contains mostly video driver related fixes.

You don't need to install these now unless you're having some trouble. These should be rolled up into the SP1 when it comes out, so you'll get them automatically later anyway.

If you do download, make sure you get the appropriate 32-bit or 64-bit version.

It doesn't say in the release notes, but I personally recommend that you install 1, reboot, install 2, reboot to avoid problems. Just a good practice, IMHO.

Technorati Tags: , , , ,

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 bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

Additional Automatic Printer Driver Installation with Vista 64 as a Print Server

August 07, 2007 Comment on this post [8] Posted in Tools
Sponsored By

Now that I'm running Vista 64, while most everything is running very smoothly, there's an occasional reminder here and there that I'm living in an alternate universe.

I'm still running a Canon Pixma MP500 Multifunction Inkjet and the fact that Vista 64 drivers were available for download confirmed that this Printer was a great decision.

However, when I tried to connect from one of my XP VMs or from my Wife's Vista32 machine, I was told that Drivers weren't available. I'm used to connecting to a printer in Windows "just working." I just visit the machine, like \\QUADPOWER, hit the Printers folder and double click the Printer. In this case, my system had only the 64-bit drivers I had already installed.

Here's how to tell your 64-bit system that it has 32-bit drivers it can serve to the family (or the reverse):

  1. From your server, go to the Printers folder and right click to get your Printer's Properties. Click the Sharing Tab and click Additional Drivers. You'll see this dialog or something like it.
    Additional Drivers

    Here you can see that the only driver available is x64 on my system. Click the x86 checkbox and click OK. You'll be prompted for an INF file - the new printer driver. Now you need to find the Printer Driver...
  2. Go get the 32-bit Driver for your printer. In my case the 32-bit Vista Driver was packaged in a WinZip EXE and it refused to run on this 64-bit system.

    Trick: Because it's a WinZip Self-Extracting Archive, I renamed it from .EXE to a .ZIP file and unzipped it into a folder using the standard Windows unzip facilities..

    Next I pointed the Open File Dialog from before at the folder with the 32-bit Printer's INF files. In my case it was called Drivers so it was obvious. Sometimes you'll have to dig, but the are in there. You'll know you found it when the Additional Drivers dialog looks like this:
    Additional Drivers (2)

Now I can point my XP or Vista machine at the Vista 64 \\QUADPOWER machine and it'll automatically install the correct drivers for the client machine.

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 bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

Bug Migrating Web.config with a browserCaps section to IIS7

August 07, 2007 Comment on this post [0] Posted in ASP.NET | Bugs
Sponsored By

When running the "appcmd.exe" tool to migrate an existing Web Application to IIS7, make sure you have a backup of your web.config.

99.999% of the time the changes made are additive, but there is an obscure issue that I bumped into.

Here's some info on the long-ago-deprecated browserCaps section of the web.config:

Using the browserCaps element in the Web.config file to define browsers is deprecated in the .NET Framework 2.0, but it is still supported. The data in this element is merged with the information from the browser definition files (.browser) that is located in the machine-level %SystemRoot%\Microsoft.NET\Framework\version\CONFIG\Browsers folder and any existing application-level App_Browser folders. For more information, see Browser Definition File Schema (browsers Element).

This section was and is used to tell ASP.NET about the capabilities of various browsers, usually mobile ones. The original idea was that it'd be updated a lot by a company called Cyscape but Cyscape has hijacked their own URL and turned it into an upsell for their BrowserHawk product. The community tried to step up, but the workload is huge. There's some good browserCaps sections out there, one from SlingFive a few years back, a valiant attempt to energize the CodeProject community around this issue by Chris Maunder.

As I said, this section is deprecated but supported. The preferred - and easier - way is to use BROWSER files, which are more portable and can be installed with ASPNET_REGBROWSERS.

Back to the migration bug. The format of the old browerCaps section was funky from an XML perspective:

<configuration> 
   <browserCaps>
      <result type="System.Web.HttpBrowserCapabilities, System.Web"/>
        <use var="HTTP_USER_AGENT"/>
              browser=Unknown
              version=0.0
              majorversion=0
              minorversion=0
              frames=false
              tables=false
              cookies=false
              backgroundsounds=false ...etc...

It's totally valid XML, but it's very uncommon to see "mixed nodes" in XML, with an Element, then some text, then an element. In this example the browser=Unknown and all that is just 'tunnelled' in a text node that most folks writing XML processing code would ignore, or not see coming.

It appears that the migration portion of this IIS7 tool...

%systemroot%\system32\inetsrv\APPCMD.EXE migrate config "Default Web Site/DasBlog2"

...toasts these text nodes so that the resulting file is just flat out missing them. This is a common mistake when processing XML that I'm likely guilty of as well.

The Moral and Workaround - Backup your web.config and add this section back after migrating. Of course, this only applies if you're using this kind of obscure section. In our case, DasBlog uses it for Mobile Support.

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 bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

32bitness and 64bitness and migrating DasBlog on IIS7 and ASP.NET under Vista64

August 07, 2007 Comment on this post [4] Posted in ASP.NET | DasBlog | Musings
Sponsored By

After building the QuadPowerPC and getting it setup with Vista 64, the next step was to get DasBlog building so I could continue development. I installed Orcas Visual Studio 2008 first. Then I realized that I hadn't installed IIS on Vista yet. Doh!

Getting an existing Web App to Compile on Vista64

  • Install IIS: Go into Programs and Features and click "Turn Windows Features on or off." Only certain Vista SKUs have Full IIS - I believe Business, Enterprise and Ultimate. The Home SKUs have a limited version that will serve 3 requests. Enough to develop on, but that's about it.
    Windows Features
    The easiest thing for a developer machine is to turn all the checkboxes on from IIS on down.
    Note: This is a wacky dialog and unless the box is actually CHECKED ("filled" with color doesn't count) then it won't install everything. Open up the tree and make sure.
  • Pick an IIS Pipeline Mode: There are two modes for ASP.NET apps under II7. There's the integrated pipeline, and the classic pipeline.
    If you just create an application and run your existing app with the defaults, like I did, you'll likely see something like this (Note the incredibly detailed error message that I can ACTUALLY do something with...That's hot.):
    IIS 7.0 Detailed Error - 500.0 - Internal Server Error - Windows Internet Explorer (2) 
    At this point I have two choices, I can migrate my httpModules section using this command line expression:
    %systemroot%\system32\inetsrv\APPCMD.EXE migrate config "Default Web Site/DasBlog2"
    Or I can make an AppPool that is configured to use the "classic" pipeline - meaning, it'll use HttpModules just as before with this command line:
    %systemroot%\system32\inetsrv\APPCMD.EXE set app "Default Web Site/DasBlog2" /applicationPool:"Classic .NET AppPool"
    Either expression needs to be run from an administrator command line.
    Internet Information Services (IIS) Manager
    If you change your mind, you can always move your app between AppPools, or make as many as you like. Notice the IIS7-style admin tool shows you what Pipeline type you've chosen.
    If just use the First Option and just stick with classic mode, things will work fine and I don't have to change anything in my web.config. Let's see what happens if I choose The Second Option...
    %systemroot%\system32\inetsrv\APPCMD.EXE migrate config "Default Web Site/DasBlog2"
    Successfully migrated section "system.web/httpModules".
    Successfully migrated section "system.web/httpHandlers".
    At this point the newly written web.config has a new section at the bottom.

    NOTE: There appears to be an obscure bug with this tool when migrating web.configs with the old-style ASP.NET 1.1 browserCaps section. More on that here. Backup your web.config before running this, or any other tool!

    Notice that the modules and handlers have moved to a new system.webServer section, the modules have been marked as managedHandler and the handlers have a preCondition that they are run in integratedModule under the 2.0 runtime. It's worth noting, however, that the original httpHandlers section under system.web remains. This means you can run under both modes with this migrated web.config file, but if you're switching around, you'll need to keep those sections in sync - or, just pick a mode and stick with it.
    <system.webServer>
        <modules>
            <add name="UrlMapperModule" type="newtelligence.DasBlog.Web.Core.UrlMapperModule, newtelligence.DasBlog.Web.Core" preCondition="managedHandler" />
    ...
        </modules>
        <handlers>
           <add name="*.blogtemplate_*" path="*.blogtemplate" verb="*" type="System.Web.HttpForbiddenHandler" preCondition="integratedMode,runtimeVersionv2.0" />
    ...
        </handlers>
      <validation validateIntegratedModeConfiguration="false" />
    </system.webServer>
  • Convert and Compile: After doing this migration I opened the main solution in Visual Studio 2008 and it converted and compiled, no problem. Most 2.0 projects will convert just fine.
  • Check Your Bitness: After migrating the web.config and building in Visual Studio 2008 I ran the application, I got the Yellow Screen of Death telling me: "System.BadImageFormatException: Could not load file or assembly 'BasicFrame.WebControls.BasicDatePicker' or one of its dependencies."
    YellowScreenofDeath
    This error is slightly more obscure, but still fairly easily dealt with. Remember that I'm on Vista64. Open up the Advanced Settings of the AppPool you're running in and notice the option "Enable 32-Bit Applications." At this point, I have another choice.
    Advanced Settings
    I could switch this AppPool to a 32-bit Worker Process. I could tell because itwould say "w3wp.exe *32" in TaskManager. Or, I could find out why this is not working and get DasBlog running on 64-bit.
    I'll choose the latter.
    Open up a Visual Studio Command Prompt and run corflags.exe on the offending assembly.
    Administrator Visual Studio 2008 Beta2 x64 Win64 Command Prompt
    Mine says:
    D:\dev\DasBlog\lib>corflags BasicFrame.WebControls.BasicDatePicker.dll
    Microsoft (R) .NET Framework CorFlags Conversion Tool.  Version  3.5.20706.1
    Copyright (c) Microsoft Corporation.  All rights reserved.

    Version   : v2.0.50727
    CLR Header: 2.5
    PE        : PE32
    CorFlags  : 11
    ILONLY    : 1
    32BIT     : 1
    Signed    : 1


    Notice the 32bit: 1 value. Looks like because the company that sells this assembly used Xenocode's Postbuild Obfucastor and it requires a CPU decision. Consequently I pay the price. Kind of lame.
    However, easily solved because Basic Date Picker has a 64-bit version available for download. I swap it out and check it with corflags...

    D:\dev\DasBlog\lib>corflags BasicFrame.WebControls.BasicDatePicker.dll
    Microsoft (R) .NET Framework CorFlags Conversion Tool.  Version  3.5.20706.1
    Copyright (c) Microsoft Corporation.  All rights reserved.

    Version   : v2.0.50727
    CLR Header: 2.5
    PE        : PE32
    CorFlags  : 9
    ILONLY    : 1
    32BIT     : 0
    Signed    : 1

    Still with me? Here's the funny part. It's not the 32BIT Flag that actually indicates if the assembly is 32bit or 64bit. It a property that tries to "insist" that the assembly run in a 32-bit process. You can, sometimes force it back and forth with corflags:

    D:\dev\DasBlog\lib>corflags.exe /32bit+ BasicFrame.WebControls.BasicDatePicker.dll
    Microsoft (R) .NET Framework CorFlags Conversion Tool.  Version  3.5.20706.1
    Copyright (c) Microsoft Corporation.  All rights reserved.
    corflags : error CF012 : The specified file is strong name signed.  Use /Force to force the update.
    D:\dev\DasBlog\lib>corflags.exe /32bit+ BasicFrame.WebControls.BasicDatePicker.dll /force
    Microsoft (R) .NET Framework CorFlags Conversion Tool.  Version  3.5.20706.1
    Copyright (c) Microsoft Corporation.  All rights reserved.
    corflags : warning CF011 : The specified file is strong name signed.  Using /Force will invalidate the signature of this image and will require the assembly to
    be resigned.
    But I can't because it's strong named and I don't have the key to sign it with, and I'm getting a little far down a silly road. Why would you want to compile a .NET assembly specific to 32-bit or X64, or IA? Usually because you're P/Invok'ing into a x64 specific native dll.
    The interesting things that corflags tell us are these:
    • CLR Header: The compiler version...2.0 is .NET 1.1, 2.5 is .NET 2.0 and 3.0 is .NET 3.5. Don't ask. ;)
    • PE (Portable Executable): PE32 is 32bit and PE32+ is 64-bit.
    • 32BIT: Are we asking to force 32-bit execution or not?

Anyway, I recompiled with the 64-bit version and all is well. I'm now running DasBlog compiled under Visual Studio 2008 on Vista 64 running under IIS7. All very smooth. Here's the "It's Not That Scary™ Summary":

It's Not That Scary™ Summary

  • Install IIS
    • Pick a Pipeline Mode and Migrate if needed
  • Compile
    • Confirm Bitness if Error.

So, really, just two steps if I'd been on Vista32 and already had IIS7 installed. Thanks to Richard Lander for all his tips and pointers! If there's mistakes in this post, they are mine, and he'll surely show up and correct them in the comments. :)

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 bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

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