About Windows Installer, the .NET Framework, and Visual Studio.
After installing Security Update KB928365 for the Microsoft .NET Framework 2.0 to fix MS07-040, some users are noticing some managed applications - especially those developed using the Windows Presentation Framework (WPF) - are running sluggish.
The apparent problem is that native images, which are assemblies already compiled to native code, do not exist for all assemblies but a few. Those assemblies for which native images do not exist, like PresentationCore.dll for WPF, must be just-in-time compiled, or JIT'd, when code must be executed each time the assembly is loaded until they compiled to native code (NGEN'd) while the machine is idle.
To work around this issue,
This will take some time but applications will run more quickly again since assemblies will not have to be JIT'd.
The root problem is that the patch only targets a single Windows Installer package, or MSI, and the Microsoft .NET Framework 3.0 redistributable is actually composed of multiple MSIs including the .NET Framework 2.0 MSI. Inside of some of these MSIs is a custom action that queues assemblies the MSI installs to be compiled to native images, or NGEN'd, at different priorities. Priority 1 assemblies are NGEN'd immediately at the end of each MSI installation. All other assemblies to be NGEN'd that are not explicitly queued are given the default priority of 3 and will, by default, be NGEN'd when the machine is idle.
When you initially installed the Microsoft .NET Framework 3.0 redistributable, all MSIs were installed and so the custom actions in each MSI were run. Some assemblies like mscorlib.dll and System.dll in the .NET Framework 2.0 MSI were queued as priority 1 while others were queued as priority 3. Some assemblies like PresentationCore.dll in the WPF MSI were queued as priority 1 as well. But when a patch is installed, only installed products that the patch targets are reinstalled. In the case of KB928365 only the .NET Framework 2.0 MSI is reinstalled so only its custom actions are executed to re-queue some of its assemblies at priority 1. All other assemblies dependent on any updates are queued at the default priority of 3.
Toward the end of the patch installation, priority 1 assemblies are NGEN'd immediate but priority 3 assemblies will only be NGEN'd when the machine is idle. For those curious, priority 2 assemblies are aggressively compiled after priority 1 assemblies.
Man, and I thought the Garbage Collection patterns in .NET were interesting. Taking that model and applying it to preJITing assemblies whenever the system gets around to it after the installs are finished is.... well.... `interesting`.
I also wonder.... on Vista w/UAC.... should `ngen queue status` really require Admin priv?
I was wondering - when I ran this, at first I received this information:
Microsoft (R) CLR Native Image Generator - Version 2.0.50727.312
Copyright (C) Microsoft Corporation 1998-2002. All rights reserved.
Failed to load dependency stdole of assembly ehiProxy, Version=6.0.6000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 because of the following e
rror : The system cannot find the file specified. (Exception from HRESULT: 0x80070002)
Failed to load dependency stdole of assembly ehiPlay, Version=6.0.6000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 because of the following er
ror : The system cannot find the file specified. (Exception from HRESULT: 0x80070002)
Failed to load dependency stdole of assembly ehiVidCtl, Version=6.0.6000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 because of the following
error : The system cannot find the file specified. (Exception from HRESULT: 0x80070002)
Compiling 74 assemblies:
After that last line it started compiling a lot of things - but the errors at the beginning, is that SOP?
The reason I ask is I just (last week) had to re-install Vista, due to a mobo replacement, and I was advised (since they mobos were different brands and I could not get Vista to load) that a complete wipe and re-installation of XP followed by upgrade to Vista (yes, I purchased the upgrade) was required since the drivers were too different. Anyhoo, this is a fairly basic system, not a lot of apps installed, yet, but everything has been updated through tonight, so I was wondering is this was normal b/c I don't have a lot installed other than Vista, Firefox, Thunderbird, and Sunbird, along with a few tweaking apps?
You need admin privileges to do this on Windows 2000 and later as well.
Christopher: the CLR team might have some good reason for that, but I can't really say what that might be. You could ask in http://forums.microsoft.com/MSDN/ShowForum.aspx?ForumID=44&SiteID=1.
John: dependent assemblies of ehiProxy.dll and ehiPlay.dll are missing. These files appear to belong to Windows Media Center. If you look in %WINDIR%\assembly do you see stdole? If not, you might get it from another machine. I'm not sure how it might've went missing, but appears to have done just that.
Mike: you need admin privileges on all NT-based platfors, including 2000, XP, 2003, and Vista. I mentioned "elevated", however, since on Vista and newer an admin doesn't have full privileges unless they are running in an elevated process. So, even as an admin, you could perform certain operations. See http://blogs.msdn.com/heaths/archive/2006/10/20/impersonating-the-right-token-in-vista.aspx for more details with additional links to topics on MSDN.
My applications were not just sluggish, but wouldn't even run without recompiling. This was a nightmare to debug (as I use Vista but most of my users don't). If you google KB928365 you find a lot of people with similar problems. Here is an example: http://forums.asp.net/t/1132582.aspx
In my case about 90% of my users could not use my C# application, in this user's case the server could not create the ASP.NET page at all.
If your applications are *just* sluggish, it seems you are pretty lucky.
George: the absense of native images won't prevent an application from running, only that they must first be JIT'd. Something else is likely wrong. Could you run fuslogvw.exe from the SDK's bin directory, make sure it's enabled, then run your application again. Refresh fuslogvw.exe and see if it says any assemblies are missing.
We've also experienced a problem with this patch and the BinaryReader using the PeekChar() method. It seems that this path somehow has affected the encoding under the covers and it results in incorrect data being passed by the reader. The end result was refactoring our application to NOT use the PeekChar() method.
Jason, the problem is that binary data should not be treated as text and fixes in the Encoding classes uncovered problem areas that did this. Please read http://blogs.msdn.com/shawnste/archive/2005/09/26/474105.aspx.
John: The error you describe with ehiProxy and the like is on all Vista boxes with Media Center. See http://blogs.msdn.com/astebner/archive/2006/08/06/690489.aspx for an explanation.
Heath: The only fix was to recompile the application.
The actual error that almost all of my users received was something like "Unable to find a runtime version to run this application".
This only happened to users after installing the security update, and after removing the update the application worked again. It is a .net 1.1 application for compatibility. Recompiling with the update installed on a 1.1 compiler allows it to run, but the old application (compiled before the update, run after the update) still does not work.
George: thanks for reporting this. I'm not sure we've seen that problem and I'll report it immediately. Could you go to http://blogs.msdn.com/heaths/contact.aspx and send me your contact detail for follow up?
We also have a list of reported problems for both KB928365 (.NET 2.0) and KB928366 (.NET 1.1 SP1) at http://support.microsoft.com/kb/928365 and http://support.microsoft.com/kb/928366, respectively. Leaving managed applications sluggish (most notable for WPF applications) was, unfortunately, just one of the problems encountered.