Previously, I had written about IE6 and IE7 Virtual PC images that the IE Team at Microsoft makes available. As the previous release of the VPCs has expired, a refresh release has been issued. The new release expires on 2007-12-07.
»
Tech things that interest me, the inevitable rant, and, of course, My Green Paste. Windows Internals, Windows Drivers, Security, Development, .NET, Software Tools & Utilities...
Previously, I had written about IE6 and IE7 Virtual PC images that the IE Team at Microsoft makes available. As the previous release of the VPCs has expired, a refresh release has been issued. The new release expires on 2007-12-07.
»
Posted by
«/\/\Ø|ö±ò\/»®©
at
9/06/2007 08:36:00 PM
Labels: debugging, development, ie, internet explorer, software, virtual machine, vm
Microsoft has recently published an "Events and Errors Message Center" on TechNet. It is a bit like EventId.net, but you can search on more fields than Event ID and Source (note that non-Microsoft products aren't included in the Microsoft offering).
The basic search allows for selection of a Microsoft product, and a search string. The advanced search adds a Version field for the selected product, an Event ID field, an Event Source field, a File name, and Language. The product list isn't yet all that comprehensive with only 18 entries (and some duplicates or products that could be further filtered by version), but I hope to see it grow to encompass more products and more versions (Vista is not listed yet, for example). It would also be cool if the capability to annotate specific events was made available to users, much like can be done at EventId.net. Another idea that would be nice to see is that as products are developed / maintained / updated, part of the process would involve documenting the events and their meaning, in the same database that the Events and Errors Message Center interfaces with. Perhaps QA and other groups could even add their own annotations to specific events - what caused the problem, how the problem was resolved, etc.
Hopefully, the Events and Errors Message Center keeps improving. Along similar lines, it would be nice to see the DLL Help Database get some attention - several times I have hoped to see Vista files appear but have been disappointed.
»
Posted by
«/\/\Ø|ö±ò\/»®©
at
8/14/2007 07:00:00 PM
Labels: error codes, errors, events, technet
If you need to run IE 6 and IE 7 on the same system for some reason (testing?), what are you supposed to do?
One solution is the "Multiple IE installer" from TredoSoft. I haven't tried it, but it is certainly a novel approach. Looks like you can run IE3, IE4.01, IE5, IE5.5, and IE6 with it.
TredoSoft also provides instructions and a utility that allows you to run IE7 side-by-side with IE6. Again, I haven't tried it, but it is good to know that it is available.
When I need to test different versions of the browser, I have as of late been relying on VPC images of Windows XP with IE6 and IE7 that have been provided by the IE team. The VPC images run with the free Virtual PC 2007. They expire on 2007-08-17, for various reasons, but the IE team has in the past provided a "refresh" for the IE6 VPC image when it last expired, and the expectation is that this will continue. The expiration-refresh cycle allows for control over how "old" an image is allowed to get - refreshes have the latest security patches installed so people aren't left running ancient and (overly) vulnerable VPC images.
The images won't pass WGA for obvious reasons but this hasn't affected my ability to test with them.
I tend to customize my IE settings pretty severely, so it is nice to be able to test with "stock" / "virgin" installs of IE. One might argue that using the VPC images doesn't necessarily mean one has two different versions of IE on the same system - that the introduction of a VM means another "system" is involved. While this is true, the VM solution does prevent one from needing to have multiple physical machines around just for the sake of testing. And, while the TredoSoft solution may work, I can't help but think that the possbility exists for the solution itself to be a potential cause of problems.
»
Posted by
«/\/\Ø|ö±ò\/»®©
at
7/29/2007 03:23:00 PM
Labels: debugging, development, ie, internet explorer, software, virtual machine, vm
I recently received the following via email. I responded, but never heard back. Hopefully the information will be of use to others...
I responded with the following:Hi, Found your name on the web when I was looking at some stuff on slashdot and I thought maybe you might have a moment to point me in the right direction.
I have a custom app which I have zero access to in terms of the developer. When the app was run on new hardware, a few users would periodically get a bizarre error, but never on their old hardware. Main difference seems to be core 2 duo on the new laptops.
Anyway, this error causes a total reset of the internal windows database system used by the app and then there's an error in msvcr80.dll. Is there a way I can tell from the data below what routine went bad in that module? I could at least then tell the guy who guards the gates to tell the developer a little bit more. At this point the "guard" is convinced it is just because the dll is not the latest version. I think it is probably not that simple.[app].exe signature
Appname [app].exe App. Ver. 0.0.0.0
Mod Name: msvcr80.dll
Mod Ver: 8.0.50215.44
Offsett: 000161fd
Error report contents
Exception info:
Code 0x0000005
Flag 0x00000000
Record 0x000000000000000
Address: 0x000000007C3861fd
It does appear that the problem may lie in the version of MSVCR80.DLL you referenced. At least, getting this to an appropriate version seems like a very reasonable first step towards troubleshooting.
According to a dude on the VC++ compiler team (Jonathan Caves @ http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=164465&SiteID=1&PageID=1 ), version 8.0.50215.44 of MSVCR80.DLL "is not an officially released version"; he links to this site (http://www.dll-files.com/dllindex/dll-files.shtml?msvcr80 ), which has a statement by another member of the VC++ team (Martyn Lovell):
"a) This is the beta 2 version of msvcr80.dll. Don\'t install it. b) This file should never be installed in system32 (except on Win9x and Windows 2000). c) The .NET framework already installs the copy correctly (in WinSxS). d) The correct source for an msvcr80 binary is from your application provider, not from this site. Martyn"
The MS DLLHelp Database entries for MSVCR80.DLL (http://support.microsoft.com/dllhelp/?dlltype=file&l=55&alpha=msvcr80.dll&S=1 ) indicate that you can get the DLL from "MS SQL 2005 Server Enterprise" or "Microsoft Visual Studio 2005 Professional". Martyn from Microsoft indicates that you should get this DLL from the application provider. He also stated that you can get it as part of the .NET Framework redistributable (version 2.0). It also appears that you can get it as a part of a package from the "Microsoft Visual C++ 2005 SP1 Redistributable Package (x86)" at http://www.microsoft.com/downloads/details.aspx?FamilyID=200B2FD9-AE1A-4A14-984D-389C36F85647&displaylang=en.
FWIW, 0x0000005 is not a valid exception code, though I suspect you meant 0xc0000005, which is the code for an access violation. You're reporting a crash at address 0x7C3861fd. With no other info it is difficult to determine what is loaded at that address (especially since the "shipping" / non-beta versions of MSVCR80.DLL are based at 0x78130000 with a virtual size of 0x9b000), but it seems likely that the beta version of MSVCR80.dll has a different base address (0x7C370000) / size which could/should include the crash address (or, the DLL could have been rebased by the loader).
I suspect that a "Dr. Watson" or "Windows Error Reporting" dump file may have been created from the application crash(es) - these are files with a .dmp extension, and they contain information useful for debugging, or getting more information about, these kinds of problems.
Hope this helps you!
-molotov
I was reading a recent blog entry by Eric Sink, and he made some comments that I thought I would take the time to share. Nothing profound on my end, mind you... ;)
In "In defense of Petzold's WPF book", the founder of SourceGear writes about a recent trend in books and tools for developers that focus on "quick results", and the trade off that goes along with this trend - loss of "deep understanding". I too have noticed this in working with various developers. While it is admirable that one is able to produce results quickly and ship a product in record time, or add some features in the blink of an eye, it seems that much of the productivity is lost when problems crop up - problems that are at least partially a lack of - you guessed it - deep understanding. As I'm one who likes to have Deep Understanding, I'm probably biased. That said, I can fully appreciate Eric's statement that "When I hire a software developer, I look for deep understanding". I think that it is important to understand how something works so you are able to use it as effectively as possible. Perhaps this is why I am inclined to consider writing software an art, as opposed to a means to an end. Sure, it's both, but how you treat it can have a significant impact on the quality of the end product. At least, that's been my experience.
To me, Deep Understanding implies passion - if one takes the time to understand something fully, to explore all venues of a topic or a technology, they truly care about what it is they're doing and are excited by it. And I can't see doing something as a profession and not being passionate about it.
»
Posted by
«/\/\Ø|ö±ò\/»®©
at
6/04/2007 11:52:00 PM
Labels: commentary, deep understanding, software
Just received the following that is related to the SVCHOST issues that I've written about in the past...
MS has released "Microsoft Security Advisory (927891) - Fix for Windows Installer (MSI)" that's not really a direct security concern, but actually addresses concerns that might prevent people from getting critical security or other updates.
As previously mentioned, it involves MS KB 927891 - "You receive an access violation error and the system may appear to become unresponsive when you try to install an update from Windows Update or from Microsoft Update", and the current revision of the article (8.0) states "This fix is one component of a two-part fix that includes a Windows Update client software update. These updates will be deployed automatically using Windows Update in May 2007 and June 2007."
Again, this update is one of two that need to be applied to fully address the issue. The other update is version 3.0 of the Windows Update Client Software, available from MS KB 932494, "When you use Automatic Updates to scan for updates or to apply updates to applications that use Windows Installer, you experience issues that involve the Svchost.exe process".
One can also hope that this will help address the 0x8ddd0009 problems that MANY have been experiencing...
»
Posted by
«/\/\Ø|ö±ò\/»®©
at
5/22/2007 08:57:00 PM
Labels: 0x8ddd0009, Automatic Updates, CPU Utilization, error message, Microsoft Update, SVCHOST, Windows Update, WUAUSERV
Initially, I was going to start off by saying that I've been reading more books and less content online, but that wouldn't be accurate. I've actually picked up more online reading, but I'm also more frequently finding myself with a good book in hand before bed. Currently, I'm finding my way through Eldad Eilam's Reversing: Secrets of Reverse Engineering. It's a good read so far and I hope to learn a lot.
I've ALWAYS got Russinovich & Solomon's Windows Internals open, and I've been through it cover to cover a few times as well. There's just so much good stuff there, and I've got a memory like a goldfish... =8->
Recently, I also read Hoglund and Butler's Rootkits: Subverting the Windows Kernel for the second time. The chapter on DKOM is probably my favorite.
I just finished Raymond Chen's The Old New Thing: Practical Development Throughout the Evolution of Windows. The anecdotes range from light to heavy, and the lessons to be learned are well presented. I like Raymond's writing style and it is good to hear his perspectives on why things are the way they are. For whatever reason I hadn't picked up Raymond's blog on MSDN, "The Old New Thing", though I was well aware of it. Probably had something to do with the volume; two posts per day seems quite high to me. After reading the book, though, I'm subscribed! Sigh. I'm not a fan of the "bonus online chapters" concept, though I am sure that I'm going to go and read them sometime. Kind of detracts from the whole "book" experience if the whole book isn't... well, whole, I suppose.
A later post will detail some of the stuff I'm subscribed to online.
»
I use ReadyBoost in Vista. One day, I went to power up my laptop and when Vista resumed from hibernation I noticed that the light on the USB Flash-memory Device (UFD) was not on. Finding this a bit odd, I jumped into Windows Explorer, double-clicked on the E drive (the letter assigned to the UFD), and was presented with an interesting dialog:
Title: Item Not Found
Text: Could not find this item
This is no longer located in <%3 NULL:OpText>.
Verify the item's location and try again.
Removable Disk
Try Again Cancel
So I looked at the back of my laptop to verify the item's location, and deciding that the item was still there I clicked "Try Again". (I know, I know - not really what the person who wrote the message for the dialog intended...) I don't recall if the dialog dismissed and another instance reappeared, or if it was just that nothing happened. Either way, I wasn't getting anywhere. I unplugged the UFD, and plugged it back in again and things were fine.
A few days later, the same thing happened. I suspect I'll be dealing with this for a while.
Procedurally, I hate to think that I'm going to have to eject the device prior to hibernating, and then plug the device in again when Vista resumes - that's too tedious for my tastes. ReadyBoost would have to have a significant impact on performance for me to go through that rigamarole, and at this point I'm just not convinced that's the case.
Anyone else coping with %3 NULL:OpText? How are you dealing with it?
»
Posted by
«/\/\Ø|ö±ò\/»®©
at
5/06/2007 06:29:00 AM
Labels: error message, ReadyBoost, Vista
Previously (here and here), I've written about isolating shared services so that they run in their own process, with a specific focus on the Windows Update Automatic Updates Service (wuauserv) that typically runs in the NETSVCS SVCHOST.EXE instance. One thing that can be done once this is accomplished is to lower the priority of the process so that when the service winds up consuming 100% of the CPU, the system doesn't become unresponsive.
Since we're dealing with a service, setting the priority of such a SVCHOST.EXE process can become problematic - the service may already be running, or, because it is a service, it is not started as non-service processes are, so one is not able to use START / [LOW NORMAL HIGH REALTIME ABOVENORMAL BELOWNORMAL] to impose a priority when the process starts. One can use a utility like Task Manager or Process Explorer to set the priority of a process on an ad hoc basis, but when the service restarts or the system reboots one has to remember to set the priority again.
Though not an ideal solution the following scripts (VBS using WMI, and PowerShell) can be used to set the priority of the SVCHOST.EXE instance hosting the isolated Windows Update Automatic Updates Service service to "below normal". Note that no check is done to ensure that the SVCHOST.EXE instance is only hosting one service - if wuauserv is found to be a service inside of the process, the priority is adjusted. Note also that no error handling is implemented.
I'll try to format the code so it looks nice, but I fear I will be limited...
Here's the code for the VBS / WMI script:
Const BELOW_NORMAL = 16384
Set objWMIService = GetObject("winmgmts:\\.\root\CIMV2")
Set colServices = objWMIService.ExecQuery( _
"SELECT * FROM Win32_Service where name='wuauserv'")
For Each oService in colServices
Set colProcesses = objWMIService.ExecQuery( _
"SELECT * FROM Win32_Process where ProcessId=" & oService.ProcessId )
For Each oProcess in colProcesses
oProcess.SetPriority(BELOW_NORMAL)
Next
Next
Here's the code for the PowerShell script:
(gps -id (get-wmiobject win32_service where {$_.name -eq "wuauserv"}).ProcessId).PriorityClass="BelowNormal"
The different values for the priority parameter of the SetPriority method of the Win32_Process WMI class can be found in the documentation for the SetPriority method.
The different values for the PriorityClass in the PowerShell script are "Normal", "Idle", "High", "RealTime", "BelowNormal", or "AboveNormal". Or, to get a list of the available options, one can use the following PowerShell command:
[ENUM]::getNames("System.Diagnostics.ProcessPriorityClass")
Once the script is in place and working, one can cause it to be invoked at will, or via scheduled task at specific times, or after logon, or any other way that one can get something to happen when Windows boots or a user logs on.
»
Posted by
«/\/\Ø|ö±ò\/»®©
at
5/01/2007 08:06:00 PM
Labels: Automatic Updates, CPU Utilization, netsvcs, Process Explorer, Processes, Shared Services, SVCHOST, troubleshooting, Windows, Windows Update, WUAUSERV
Alex Ionescu has posted some publications at his blog. I've only had an opportunity to go through the three-part series on Windows XP / 2003 User-Mode Debugging Internals, but I found them to be quite interesting and I hope to go through the rest of the publications which cover topics like Process Internals, VB File Format, NTFS ADS, and Subverting Windows 2003 SP1 Kernel Integrity Protection.
One thing (probably trivial) that I am curoius about in the User-Mode Debugging Internals papers is the analysis of NtDebugActiveProcess. Alex comments in his analysis in part 3 "Don't allow debugging the initial system process". The check for the initial system process is made, and STATUS_ACCESS_DENIED is returned if indeed it is the initial system process that is the subject of the debug attempt. I am curious as to why, prior to returning in this case, the process is not dereferenced (ObDereferenceObject(Process);)? Is it simply the nature of the system process that this is not required, though perhaps it might be considered good practice to call ObDereferenceObject(Process) in this case? Or is there some other reason?
Does anyone have any thoughts on the above?
»
OK... I admit it. I'm jumping on the whole "tagging" thing (or as Blogger likes to call it, "Labels") a bit late. Shortly after converting to the "new" Blogger, I made a rather unconscious decision to ignore the field that allows for tagging new items. So there are many posts that were made with the new blogger that don't have tags. I plan on tagging a few at a time, but with 140+ posts, this could take a bit of time.
»
Previously (Part 1: Introduction - What's using my CPU?), I kicked off what I expect to be a multi-part series on determining what is causing excessive CPU consumption, outside of the normal "which process has the highest value in the CPU column in Task Manager".
Before I get into things, a little bit of background may prove useful or mildly entertaining. Over on "Sysinternals Forums", there were recently two similar problems that both involved excessive CPU utilization that was not attributable to a specific process. I became involved in both problems and attempted to use similar techniques to get additional information with the hopes of ultimately being able to pinpoint the problem. What may make this mildly entertaining is that in both cases, there was limited or no success in detetmining the cause of or solution to the problem. In the end, one problem was resolved by disabling the floppy disk controller, and the other problem appears to be as of yet unresolved. (In the latter case, the poster did admit that the system was experiencing hardware problems - the chipset fan was dying and there were diagnostic beep codes during / after POST. These hardware problems could be related to the problem.) Despite the lack of success in determining the cause of the problems I do feel that I learned a bit about this type of problem and gained some insight into the use of some tools that can come in handy in this situation.
In the two cases, the problem consisted of the CPU spending a lot of time servicing interrupts and deferred procedure calls (DPCs). What are interrupts and DPCs? "Windows Internals, Chapter 3 - System Mechanisms" says:
Interrupts ... are operating system conditions that divert the processor to code outside the normal flow of control. An interrupt is an asynchronous event (one that can occur at any time) that is unrelated to what the processor is executing. Interrupts are generated primarily by I/O devices, processor clocks, or timers.
A deferred procedure call (DPC) is a function that performs a system task—a task that is less time-critical than the current one. The functions are called deferred because they might not execute immediately.It is interesting to note that one may have a problem with excessive CPU use but may not be able determine it by using Windows' Task Manager. This is because for whatever reason, Task Manager adds time the CPU spends servicing interrupts and DPCs to the "System Idle Process". Microsoft's / Sysinternals' Process Explorer includes separate "artificial" processes for interrupts and DPCs so that one can see how much time the CPU spends dealing with each. Per Process Explorer's help file, "high CPU consumption by these activities can indicate a hardware problem or device driver bug".
»
Posted by
«/\/\Ø|ö±ò\/»®©
at
4/16/2007 11:57:00 PM
Labels: CPU Utilization, DPCs, Interrupts, Sysinternals
In the past, I've written about both high CPU utilization by SVCHOST.EXE as well as the 0x8ddd0009 Windows Update / Microsoft Update error, so I thought I would mention this...
MS KB 932494 (When you use Automatic Updates to scan for updates or to apply updates to applications that use Windows Installer, you experience issues that involve the Svchost.exe process) references problems that are addressed by MS KB 916089 (FIX: When you run Windows Update to scan for updates that use Windows Installer, including Office updates, CPU utilization may reach 100 percent for prolonged periods) and MS KB 927891 (You receive an access violation when you try to install an update from Windows Update after you apply hotfix package 916089). However, even after applying the patch associated with 927891 (which replaces the patch associated with 916089), 932494 indicates that the following problems remain:
1) Certain 100 percent CPU issues are still present when you use the Svchost.exe process.I (as well as others) have speculated in the past that 916089 (and its succedent patches) can also help with the 0x8ddd0009 error message that one might receive from Windows Update / Microsoft Update.
2) An access violation may occur in the Svchost.exe process.
Posted by
«/\/\Ø|ö±ò\/»®©
at
3/19/2007 08:15:00 PM
Labels: 0x8ddd0009, Automatic Updates, CPU Utilization, SVCHOST, Windows Update, WUAUSERV
Recently, I have been involved in attempting to diagnose problems with excessive CPU utilization. Often times, this type of thing is relatively easy to identify - at least as far as pointing the finger at the thing that is consuming CPU cycles. Task Manager can be used for this - simply sort the "CPU" column in descending order and note the process that is at the top of the list. One can use a similar technique with Process Explorer.
In the past (here and here), I've given examples that demonstrate various techniques that can be used to try to determine what a process is doing when it is consuming so much CPU. Sometimes, you can do something about it - if you have the debugging symbols, perhaps there is something in the stack of the thread or threads in the process that is consuming the CPU that will lead you to some setting, feature, or configuration piece that can be manipulated so as to avoid the problem. Or perhaps just knowing the module name is enough information to identify the problem software - a recently installed add-in / plug-in, or a new utility, perhaps. Sometimes you are forced to work around the problem - you don't have any control over it and don't want to stop using the program, or have no choice but to keep using the program.
But what happens when the excessive CPU utilization is not attributable to a "standard" process? In the coming series of articles, I hope to explore some of the things that can be done to diagnose and troubleshoot this type of scenario. Stay tuned...
»
Posted by
«/\/\Ø|ö±ò\/»®©
at
3/06/2007 08:35:00 PM
Labels: CPU Utilization, Sysinternals, troubleshooting
I'll make this one brief...
Sorry for the lack of updates lately - I'm working on a number of other things and haven't found a lot of time to write. I have something kind of fun planned that may be a three or four parter but it will probably be a bit slow in coming. It will also be a learning experience for me, so that should be cool. I will post things as I finish them, but there may be revisions to the content when the later parts are posted. I hope to have the first one (introduction) up by the end of the coming weekend.
I appreciate your patience, understanding, and continued readership. Thank you.
»
I've written about Sysinternals' Process Monitor utility before:
Posted by
«/\/\Ø|ö±ò\/»®©
at
2/18/2007 11:44:00 AM
Labels: Process Monitor, Sysinternals, utilities
Previously (Troubleshooting Performance Issues with Automatic Updates / How to Isolate A Shared Service Hosted by SVCHOST.EXE) I had detailed some steps that one could follow to isolate a shared service hosted by SVCHOST.EXE, in the context of the Windows Update Automatic Updates service. There are a couple of other ways to isolate a shared service, with different implications.
The intention / desire of a service to be "shared" or not is typically indicated when the service is created - the fifth parameter to CreateService is dwServiceType, which for our interests can be, among other things, SERVICE_WIN32_OWN_PROCESS (0x10) or SERVICE_WIN32_SHARE_PROCESS (0x20). Once a service has been created, the dwServiceType setting can be changed by calling ChangeServiceConfig with the appropriate parameters.
Windows XP and Server 2003 ship with a utility program called "SC.exe". (I seem to recall using SC.EXE on NT 4.0, after it was included in some resource kit, but I could be mistaken. The DLL Help Database listing for SC.EXE puts the earliest version as having shipped with Visual Studio .NET 2002.) SC presumably stands for "Service Controller". At any rate, one can use SC to change the configuration of a service, including the "service type" - "shared" or "own". So, using wuauserv - the Windows Update Automatic Updates service - as a guinea pig, one could execute from a CMD prompt:
sc config wuauserv type= ownto cause the service to run in its own process. (The service will need to be restarted for this to happen.) To change it back to a shared service, use the following command:
sc config wuauserv type= shareNote that in both commands, the space after the '=' character is critical. For this change (back to "shared") to take effect, the system will likely need to be rebooted as the "original" SVCHOST group that this service was a part of is already running. This is also the case when un-doing the configuration to make the service run in its own SVCHOST group.
Posted by
«/\/\Ø|ö±ò\/»®©
at
2/08/2007 09:02:00 PM
Labels: Automatic Updates, Shared Services, SVCHOST, troubleshooting, Windows, Windows Update
Some additional questions have been raised here and elsewhere about what precisely causes the "Unspecified Potential Security Risk" dialog - the one from Internet Explorer that looks like:
Internet Explorer
This page has an unspecified potential security risk.
Would you like to continue?
The dialog is displayed when the setting "Launching applications and unsafe files" is set to "Prompt" for the security zone that Windows / Internet Explorer believes itself to be operating in.
Changing the setting to "Enable" for the specific zone eliminates the dialog, while changing the setting to "Disable" produces a "Security Alert" dialog stating that "Your current security settings do not allow this action."
»
Posted by
«/\/\Ø|ö±ò\/»®©
at
2/01/2007 09:25:00 PM
Labels: error message, internet explorer, security
...or,
How to Isolate A Shared Service Hosted by SVCHOST.EXE
There are a number of articles in the Microsoft Knowledge Base about performance issues with Windows Update / Microsoft Update, as well as other problems related to the scanning mechanisms used by automatic-type update services. There are some fixes, and fixes for some fixes, but no "ultimate" solution. Stepping back a bit, how can you even determine if Automatic Updates is causing performance issues on your system?
The Automatic Updates service is not a stand-alone process, so it is not sufficient to simply look for which process is consuming the most CPU time or the most memory. Rather, Automatic Updates is integrated into the "netsvcs" SVCHOST service hosting instance. On the systems that I have examined, this instance hosts over 20 services - 25 services on the system I am using to write this. How can you see what services are running inside of a process? One way is to use "tasklist /svc", and examine the "Services" column. Another way is to use Process Explorer - simply hover the mouse pointer over a process and any services that are contained in the process are listed in a tooltip. Or, view the Process' "Properties" page and examine the "Services" tab for more details.
This sharing of services in one process isn't a bad thing - Windows has been doing this for some time. There are times when it makes sense, and times when it doesn't. Basically, processes are expensive and the more you have the more resources they consume. If you are able to share services in the address space of a process, you are conserving resources. But if the services have different security needs, for example, then you should probably split them into two separate processes to "isolate" the functionality that requires greater privileges.
Back to the task at hand... The fact that services can share a process is nice, but this really gets in the way of troubleshooting a service you suspect may be causing problems. So it can be useful to extract a shared service and make it run in its own process. With services hosted by SVCHOST, the configuration is controlled in the registry. Microsoft doesn't publicly document the interfaces for SVCHOST.EXE as it doesn't want people writing services and making them run in the same address space of processes that host Windows built-in services - if the service is poorly written it can cause SVCHOST.EXE to crash, and subsequently kill all of the other services running in that instance of SVCHOST.EXE. That doesn't mean you can't manipulate the built-in Windows services to use a configuration you desire, though...
The SVCHOST services are controlled by registry settings in [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SvcHost]. (Standard warnings about editing the registry apply.) Each REG_MULTI_SZ in this key represents a SVCHOST group containing a list of one or more services to run in an instance of SVCHOST.EXE. So if one wishes to isolate the Automatic Updates service, one needs to find which group it is in. The "name" of the Automatic Updates service is "wuauserv" - Windows Update Automatic Updates service. This service resides in the "netsvcs" group. So, since the desire is to create a new SVCHOST instance to run the service in, remove wuauserv from the list in the netsvcs value. Then, create a new REG_MULTI_SZ value and give it an appropriate name, such as AutomaticUpdates. Add wuauserv to this value.
Next, navigate to [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet \Services\wuauserv] and change the ImagePath (which specifies the program and arguments the Service Control Manager is to use to invoke the service) from:
%systemroot%\system32\svchost.exe -k netsvcs
to:
%systemroot%\system32\svchost.exe -k AutomaticUpdates
That's it. Stop and restart the Automatic Updates service (net stop wuauserv / net start wuauserv) and you should see a new instance of SVCHOST.EXE that contains only the Automatic Updates service. Now you can monitor the performance of this process, drop its priority (Task Manager or Process Explorer), etc.
The same technique can be applied to isolate other SVCHOST hosted services as well. However, some caution and investigation should be applied on a case-by-case basis- it should be noted that some services may have some dependence on residing in the same address space as another service. This may or may not be intentional; if intentional I suspect that it probably has to have some relation to performance. If not intentional, it is likely a bug.
»
Posted by
«/\/\Ø|ö±ò\/»®©
at
1/28/2007 09:20:00 PM
Labels: Automatic Updates, netsvcs, Shared Services, SVCHOST, troubleshooting, Windows, Windows Update
A quick one this week...
Ran into an interesting posting at shell: revealed about features of Longhorn that didn't make the cut. The post paints the picture that after the Longhorn reset (described here), a lot of features were yanked, and then goes on to describe some rather humorous things that just make you think... "What if?"
»
I don't know how I missed it (well, I suspect it's related to quirks in the method(s) in which Microsoft makes notifications of new KB articles available), but it seems that Microsoft has released an update to Internet Explorer 7 to address the performance issues with the Phishing Filter that I had previously (here and here) encountered.
The KB article (The computer may respond very slowly as the Phishing Filter evaluates Web page contents in Internet Explorer 7) is dated December 12, 2006, and contains links to download pages for various versions of Windows that Internet Explorer 7 can run on. Your copy of Windows has to pass the Windows Genuine Advantage (WGA) check before Microsoft will allow you to download the fix. Once downloaded, installation is straightforward; depending on what programs you have open at the time, you may be required to reboot after the installation finishes.
It is interesting to note that the Cause section (below) explains exactly the conditions I was operating in, and the behavior I observed.
Posted by
«/\/\Ø|ö±ò\/»®©
at
1/18/2007 09:18:00 PM
Labels: fix, internet explorer, phishing filter
Oh, my. Two weeks in a row with ambiguous security-related messages from a web browser.
This week, we have the following:
Internet Explorer
This page has an unspecified potential security risk.
Would you like to continue?
If it wasn't for the fact that I wasn't browsing the web - I was trying to open a ZIP file on a network share - I probably would have said "No". But since I really needed to get into the ZIP file, I decided to take my unspecified potential chances. I think I'm OK.
»
Posted by
«/\/\Ø|ö±ò\/»®©
at
1/17/2007 09:14:00 PM
Labels: error message, internet explorer, security
I was going through some CHM help files the other day and I wound up copying one of the links to the clipboard and tossing it into Maxthon. I wasn't even really aware of what I was doing (just plodding along mindlessly) so I was rather surprised when I was presented with the following dialog:
Security Warning !
Using MK: protocol in browser may cause puritanical security problems.
Do you really want to enable this protocol during this session?
Of course, I had no desire to cause puritanical security problems, so I went with the default "No". The URL I had copied was in fact a "Microsoft Infotech" protocol link in the form of:
mk:@MSITStore:f:\file.chm::/Whatever/Whatever.html
The InfoTech protocol has changed several times over the last few years to reduce security vulnerabilities in HTML help. See MS05-026: A vulnerability in HTML Help could allow remote code execution and MS04-023: Vulnerability in HTML Help could allow code execution for more information.
Another issue that is seen rather frequently is the inability to open CHM / HTML Help files from a network path (UNC path or mapped drive). The article "You cannot open remote content by using the InfoTech protocol after you install security update 896358, security update 840315, or Windows Server 2003 Service Pack 1" discusses various registry settings that can be manipulated to allow the display of content in CHM files in this scenario.
»
Posted by
«/\/\Ø|ö±ò\/»®©
at
1/10/2007 08:34:00 PM
Labels: chm, error message, infotech, Maxthon, security
Unfortunately, I forgot what website I was visiting when I encountered the following dialog:
Assertion Failed: Unrecognized tag mtpstoolkit:RatingBehavior
Break into debugger?
I have no concrete idea what the dialog is related to, but I suspect it has to do with some AJAX framework. Interestingly, googling mtpstoolkit (groups search here) currently proves to be rather fruitless. The stack of the thread "owning" the dialog (with a large number of calls in jscript.dll) seems to support the AJAX theory:
ntoskrnl.exe!KiSwapContext+0x2e
ntoskrnl.exe!KiFastCallEntry+0xf8
ntdll.dll!KiFastSystemCallRet
USER32.dll!NtUserWaitMessage+0xc
USER32.dll!InternalDialogBox+0xd0
USER32.dll!SoftModalMessageBox+0x938
USER32.dll!MessageBoxWorker+0x2ba
USER32.dll!MessageBoxIndirectW+0x56
ieframe.dll!SHFusionMessageBoxIndirect+0x26
ieframe.dll!CDocHostUIHandler::ShowMessage+0x128
ieframe.dll!CDocHostUIHandler::Exec+0xe6
ieframe.dll!CDocObjectHost::OnExec+0xcb1
ieframe.dll!CDocObjectHost::Exec+0xd7
mshtml.dll!CreateHTMLPropertyPage+0x2503b
mshtml.dll!CreateHTMLPropertyPage+0x22f72
mshtml.dll!CreateHTMLPropertyPage+0x8980
mshtml.dll!CreateHTMLPropertyPage+0x3f40c
mshtml.dll!DllGetClassObject+0xc53d3
mshtml.dll!DllGetClassObject+0xca51f
mshtml.dll!DllGetClassObject+0xca498
mshtml.dll!DllGetClassObject+0xca353
jscript.dll!IDispatchExInvokeEx2+0xac
jscript.dll!IDispatchExInvokeEx+0x56
jscript.dll!InvokeDispatchEx+0x78
jscript.dll!VAR::InvokeByDispID+0x7e
jscript.dll!CScriptRuntime::Run+0x1675
jscript.dll!ScrFncObj::Call+0x8d
jscript.dll!NameTbl::InvokeInternal+0x40
jscript.dll!VAR::InvokeByDispID+0xfd
jscript.dll!VAR::InvokeByName+0x165
jscript.dll!VAR::InvokeDispName+0x43
jscript.dll!VAR::InvokeByDispID+0xb9
jscript.dll!CScriptRuntime::Run+0x16c9
jscript.dll!ScrFncObj::Call+0x8d
jscript.dll!NameTbl::InvokeInternal+0x40
jscript.dll!VAR::InvokeByDispID+0xfd
jscript.dll!VAR::InvokeByName+0x165
jscript.dll!VAR::InvokeDispName+0x43
jscript.dll!VAR::InvokeByDispID+0xb9
jscript.dll!CScriptRuntime::Run+0x1675
jscript.dll!ScrFncObj::Call+0x8d
jscript.dll!NameTbl::InvokeInternal+0x40
jscript.dll!VAR::InvokeByDispID+0xfd
jscript.dll!VAR::InvokeByName+0x165
jscript.dll!VAR::InvokeDispName+0x43
jscript.dll!VAR::InvokeByDispID+0xb9
jscript.dll!CScriptRuntime::Run+0x1675
jscript.dll!ScrFncObj::Call+0x8d
jscript.dll!NameTbl::InvokeInternal+0x40
jscript.dll!VAR::InvokeByDispID+0xfd
jscript.dll!VAR::InvokeByName+0x165
jscript.dll!VAR::InvokeDispName+0x43
jscript.dll!VAR::InvokeByDispID+0xb9
jscript.dll!CScriptRuntime::Run+0x1675
jscript.dll!ScrFncObj::Call+0x8d
jscript.dll!NameTbl::InvokeInternal+0x40
jscript.dll!VAR::InvokeByDispID+0xfd
jscript.dll!VAR::InvokeByName+0x165
jscript.dll!VAR::InvokeDispName+0x43
jscript.dll!VAR::InvokeByDispID+0xb9
jscript.dll!CScriptRuntime::Run+0x1675
jscript.dll!ScrFncObj::Call+0x8d
jscript.dll!NameTbl::InvokeInternal+0x40
jscript.dll!VAR::InvokeByDispID+0xfd
jscript.dll!JsFncCall+0x8e
jscript.dll!NatFncObj::Call+0x41
jscript.dll!NameTbl::InvokeInternal+0x40
jscript.dll!VAR::InvokeByDispID+0xfd
jscript.dll!VAR::InvokeByName+0x165
jscript.dll!VAR::InvokeDispName+0x43
jscript.dll!VAR::InvokeByDispID+0xb9
jscript.dll!CScriptRuntime::Run+0x1675
jscript.dll!ScrFncObj::Call+0x8d
jscript.dll!NameTbl::InvokeInternal+0x40
jscript.dll!VAR::InvokeByDispID+0xfd
jscript.dll!VAR::InvokeByName+0x165
jscript.dll!VAR::InvokeDispName+0x43
jscript.dll!VAR::InvokeByDispID+0xb9
jscript.dll!CScriptRuntime::Run+0x1675
jscript.dll!ScrFncObj::Call+0x8d
jscript.dll!NameTbl::InvokeInternal+0x40
jscript.dll!VAR::InvokeByDispID+0xfd
jscript.dll!VAR::InvokeByName+0x165
jscript.dll!VAR::InvokeDispName+0x43
jscript.dll!VAR::InvokeByDispID+0xb9
jscript.dll!CScriptRuntime::Run+0x16c9
jscript.dll!ScrFncObj::Call+0x8d
jscript.dll!NameTbl::InvokeInternal+0x40
jscript.dll!VAR::InvokeByDispID+0xfd
jscript.dll!JsFncApply+0xc4
jscript.dll!NatFncObj::Call+0x41
jscript.dll!NameTbl::InvokeInternal+0x40
jscript.dll!VAR::InvokeByDispID+0xfd
jscript.dll!VAR::InvokeByName+0x165
jscript.dll!VAR::InvokeDispName+0x43
jscript.dll!VAR::InvokeByDispID+0xb9
jscript.dll!CScriptRuntime::Run+0x1675
jscript.dll!ScrFncObj::Call+0x8d
jscript.dll!NameTbl::InvokeInternal+0x40
jscript.dll!VAR::InvokeByDispID+0xfd
jscript.dll!CScriptRuntime::Run+0x16c9
jscript.dll!ScrFncObj::Call+0x8d
jscript.dll!CSession::Execute+0xa1
jscript.dll!NameTbl::InvokeDef+0x179
jscript.dll!NameTbl::InvokeEx+0xcb
mshtml.dll+0x2234
mshtml.dll!DllGetClassObject+0x24151
mshtml.dll!DllGetClassObject+0x77fb6
mshtml.dll!DllGetClassObject+0x7925f
mshtml.dll!DllGetClassObject+0x6f679
mshtml.dll!DllGetClassObject+0x9f5de
mshtml.dll!DllGetClassObject+0xb63c7
USER32.dll!InternalCallWinProc+0x28
USER32.dll!UserCallWinProcCheckWow+0x150
USER32.dll!DispatchMessageWorker+0x306
USER32.dll!DispatchMessageW+0xf
avant.exe+0x5df02
avant.exe+0x5df5b
avant.exe+0x39941f
Anyone know what precisely mtpstoolkit is a part of?
»
Posted by
«/\/\Ø|ö±ò\/»®©
at
1/02/2007 09:36:00 PM
Labels: AJAX, mtpstoolkit, RatingBehavior
[Added 2007-01-18: Fix Available for Performance Problems with Internet Explorer 7's Phishing Filter ...]
Previously, I wrote about sluggish behavior with Internet Explorer 7. I had used Process Explorer to help pinpoint the cause of the sluggishness - in this case, it was Internet Explorer 7's (anti)phishing filter. I could also have used a relatively new tool from Microsoft's Windows Sysinternals - Process Monitor.
In Process Monitor, it is easy to get inundated with all of the data that the tool collects. Filters are very critical to enabling one to find the desired information, and the implementation of filters in Process Monitor is top notch. For this exercise, after starting Process Monitor and checking "Generate Profiling Events" on the "Options" menu, I captured events while exercising the web application with the Phishing Filter set to "Turn off automatic website checking" and "Enabled" for the Security zone the web application was in. After capturing events for a minute or so, I set the following filters:
-Process Name is iexplore.exe then Include
-Event Class is Registry then Exclude
-Event Class is File System then Exclude
-Event Class is Process then Exclude
This displayed all "profiling" events for the iexplore.exe process. I double-clicked an event to bring up the "Event Properties" dialog and clicked on the "Stack" tab, which had the following information:
ntdll.dll!KiFastSystemCallRet
kernel32.dll!WaitForSingleObject + 0x12
ole32.dll!GetToSTA + 0x6f
ole32.dll!CRpcChannelBuffer::SwitchAptAndDispatchCall + 0xf6
ole32.dll!CRpcChannelBuffer::SendReceive2 + 0xb9
ole32.dll!CAptRpcChnl::SendReceive + 0xab
ole32.dll!CCtxComChnl::SendReceive + 0x113
RPCRT4.dll!NdrProxySendReceive + 0x43
RPCRT4.dll!NdrClientCall2 + 0x1fa
OLEAUT32.dll!IDispatch_RemoteInvoke_Proxy + 0x1b
OLEAUT32.dll!IDispatch_Invoke_Proxy + 0xb6
ieapfltr.dll!ATL::CComPtr
ieapfltr.dll!FieldContainer::VisitInput + 0x1b9
ieapfltr.dll!FieldContainer::VisitAllElements + 0x21d
ieapfltr.dll!FieldContainer::ExtractFieldCount + 0x10e
ieapfltr.dll!FieldContainer::InitFieldCount + 0x9
ieapfltr.dll!PageDetails::Init + 0x315
ieapfltr.dll!PageDetails::Factory + 0x59
ieapfltr.dll!HeuristicsFeatures::InnerExecute + 0x15b
ieapfltr.dll!HeuristicsFeatures::Execute + 0x55
ieapfltr.dll!ProcessingThread::RunPageAnalysis + 0x1b4
ieapfltr.dll!ProcessingThread::RunUrlAndPageAnalysis + 0xdb
ieapfltr.dll!ProcessingThread::Analyze + 0xd3
ieapfltr.dll!ProcessingThread::AnalyzeFrame + 0x249
ieapfltr.dll!ProcessingThread::EnumerateFrames + 0x2e5
ieapfltr.dll!ProcessingThread::EnumerateFrames + 0x249
ieapfltr.dll!ProcessingThread::Evaluate + 0x1ec
ieapfltr.dll!ProcessingThread::Execute + 0x78
ieapfltr.dll!ProcessingThread::Process + 0x24e
ieapfltr.dll!ProcessingThread::Start + 0x72
ieapfltr.dll!Evaluator::ContinueProcessing + 0x21f
ieapfltr.dll!Evaluator::ContinueProcessingWrapper + 0x21
ntdll.dll!RtlpWorkerCallout + 0x70
ntdll.dll!RtlpExecuteWorkerRequest + 0x1a
ntdll.dll!RtlpApcCallout + 0x11
ntdll.dll!RtlpWorkerThread + 0x87
kernel32.dll!BaseThreadStart + 0x37
With this information from Process Monitor, one could come to a similar conclusion - the Phishing Filter in Internet Explorer 7 seems to cause Internet Explorer 7's performance to degrade in certain environments.
»
Posted by
«/\/\Ø|ö±ò\/»®©
at
12/26/2006 10:14:00 PM
Labels: internet explorer, phishing filter, Process Monitor, Sysinternals, troubleshooting
[Added 2007-01-18: Fix Available for Performance Problems with Internet Explorer 7's Phishing Filter ...]
I like Internet Explorer 7. I've installed it many, many times and on
many systems. I've never had a problem with it. That is, until I had to spend some time working with a web-based application on an Intranet. I had to go through several iterations of repetetive steps in this application. It was the kind of work where it would have been more fun to write a program to achieve the end result, but it would probably have taken more time to write the program than it would to go through the tedious process. That, and the fact that I didn't immediately have access to some of the information that would be required to write the app, prevented me from taking the fun route. So I was stuck copying, clicking, pasting, and... WAITING.
The problem wasn't the responsiveness of the web server - the problem was localized to my system. As I was working on a laptop, I could hear the fan kick into high gear as CPU utilization hit 100%... and stayed there. When I paused for a bit, the CPU usage went back down. So, interacting with the web application was causing the behavior. The task took about 90 minutes to complete, and when I was done, Process Explorer showed iexplore.exe as having used nearly 90 minutes of CPU time. I didn't have this problem with Internet Explorer 6! In communicating with the vendor of the web application, they indicated that they hadn't had problems of this sort in any of their experiences with IE7 or with other customers.
I surmised that there was likely a setting in Internet Explorer 7 that was affecting the performance. But IE7 has no shortage of settings, and to try each one was not a task that I wanted to undertake. I fired up IE7, loaded the web-based app, and started working. Then, while the CPU was taxed, I went to Process Explorer, hit the properties of the iexplore.exe process, and checked the "Threads" tab. There were 89 threads, most having a start address of "ndtll.dll!RtlpWorkerThread", and all vying for CPU time. It appeared that a new thread was created for each request that was made, which seems rather "wasteful". At any rate, RtlpWorkerThread is a private "run-time library" worker thread threadproc function, presumably the threadproc used when one uses the Thread Pool API. The stack of one of these threads at the point that I captured it (obtained with Process Explorer and properly configured debugging symbols) is rather deep:
ntkrnlpa.exe!KiSwapContext+0x2e
ntkrnlpa.exe!KiSwapThread+0x46
ntkrnlpa.exe!KeWaitForMultipleObjects+0x284
ntkrnlpa.exe!NtWaitForMultipleObjects+0x2a2
ntkrnlpa.exe!KiFastCallEntry+0xf8
ntdll.dll!KiFastSystemCallRet
ntdll.dll!ZwWaitForMultipleObjects+0xc
kernel32.dll!WaitForMultipleObjectsEx+0x12c
ole32.dll!CoWaitForMultipleHandles+0x100
ieapfltr.dll!AntiPhishingMutex::AntiPhishingMutex+0x91
ieapfltr.dll!AntiPhishingHashTable::Find+0xaf
ieapfltr.dll!CacheManager::FindUrlInUrsCache+0xa5
ieapfltr.dll!AntiPhishDataSeeker::MatchRollUps+0x2cf
ieapfltr.dll!AntiPhishDataSeeker::MatchRollUpsInCache+0x43
ieapfltr.dll!AntiPhishDataSeeker::FindOMOTarget+0x2d
ieapfltr.dll!PageDetails::CountTargetRollups+0x34
ieapfltr.dll!PageDetails::Init+0x1da
ieapfltr.dll!PageDetails::Factory+0x59
ieapfltr.dll!HeuristicsFeatures::InnerExecute+0x15b
ieapfltr.dll!HeuristicsFeatures::Execute+0x55
ieapfltr.dll!ProcessingThread::RunPageAnalysis+0x1b4
ieapfltr.dll!ProcessingThread::RunUrlAndPageAnalysis+0xdb
ieapfltr.dll!ProcessingThread::Analyze+0xd3
ieapfltr.dll!ProcessingThread::AnalyzeFrame+0x249
ieapfltr.dll!ProcessingThread::EnumerateFrames+0x2e5
ieapfltr.dll!ProcessingThread::EnumerateFrames+0x249
ieapfltr.dll!ProcessingThread::Evaluate+0x1ec
ieapfltr.dll!ProcessingThread::Execute+0x78
ieapfltr.dll!ProcessingThread::Process+0x24e
ieapfltr.dll!ProcessingThread::Start+0x72
ieapfltr.dll!Evaluator::ContinueProcessing+0x21f
ieapfltr.dll!Evaluator::ContinueProcessingWrapper+0x21
ntdll.dll!RtlpWorkerCallout+0x70
ntdll.dll!RtlpExecuteWorkerRequest+0x1a
ntdll.dll!RtlpApcCallout+0x11
ntdll.dll!RtlpWorkerThread+0x87
kernel32.dll!BaseThreadStart+0x37
As you can see, after the thread pool plumbing is out of the way, the first function in the stack is ieapfltr.dll!Evaluator::ContinueProcessingWrapper - a function in ieapfltr.dll. ieapfltr.dll describes itself as "Microsoft Phishing Filter", though I suspect IEAP is an acronym for Internet Explorer Anti-Phishing. At any rate, it certainly seemed that the settings surrounding the (anti)phishing filter would be a good place to start.
I went into "Internet Options" in the Control Panel (Start Run inetcpl.cpl) and hit the "Advanced" tab. Toward the bottom was a setting for the Phishing Filter where there were three options:
-Disable Phishing Filter
-Turn off automatic website checking
-Turn on automatic website checking
Mine was set to "Turn off automatic website checking". I changed it to "Disable Phishing Filter" and hit OK, and re-tried the web application. The application was responsive as ever, and the "excess" threads that were previously being created were nowhere to be seen. Changing the setting back to "Turn off automatic website checking", and hitting the web application again caused iexplore.exe to consume as much of the CPU as it could. It appeared that I found the cause of the sluggish performance.
It is worth noting that in the "Internet Options", on the Security tab, each Internet Explorer Zone has its own setting for the Phishing Filter. If one selects a Zone, and clicks the "Custom level..." button, about 75% of the way down is a setting for "Use Phishing Filter" that has 2 options - Disable or Enable. The setting on the Advanced tab overrides this - if the Security zone setting is set to "Enable" and the Advanced setting is set to "Disable Phishing Filter", the Phishing Filter is disabled for all zones. However, if the Advanced setting is set to "Turn off automatic website checking" or "Turn on automatic website checking", one can exercise more granular control over each Security zone by choosing to enable / disable the filter where it makes sense.
»
Posted by
«/\/\Ø|ö±ò\/»®©
at
12/19/2006 06:13:00 PM
Labels: internet explorer, phishing filter, Process Explorer
Finally got through watching some good overview videos on MSDN's Channel 9.
Doron Holan talks about the Kernel Mode Driver Framework (KMDF) in this Channel 9 Video Segment. Check out the state machine diagrams!
Peter Wieland goes over the User Mode Driver Framework (UMDF) in this video segment. There's even some discussion about writing a driver with managed code (C# / VB.NET).
»
In How does this warrant a KB article?, I pondered the existence of a Microsoft KnowledgeBase article that discussed how to set the SmtpMail.SmtpServer property of the System.Web.SmtpMail class.
In my travels, I encountered a blog posting in the "The CDOs and CDONTS of Messaging Development" blog - MYTH: SmtpMail.SmtpServer.Insert(0,"127.0.0.1") Actually Does Something. This posting is interesting because it's possible that it prompted the aforementioned KB article (922777: You receive an error message when you try to send an e-mail message by using the System.Web.Mail namespace in the .NET Framework 1.0). It's also interesting because it talks about the source of the infamous code - a Code Project article.
»
It was maddening, I tell you. I like to write C# code in a C# source file, not inline in a script tag. So I went about modifying Global.asax to allow me to do so:<%@ Application language="C#" CodeBehind="Global.asax.cs" Inherits="Global" %>I then went about defining a class called "Global" in Global.asax.cs. I added the code I needed and proceeded to build the ASP.NET app in Visual Studio 2005. But I got an error:Global.asax(1): Build (web): Could not load type 'Global'.Of course, I was perplexed. Why not? Why couldn't the type be loaded?
I thought for a bit, but then went about doing some more coding. Eventually, I had to address the problem, though. How? On a whim I placed Global.asax.cs in the App_Code ASP.NET folder. Once I did that, I was able to build the app.
»
SVCHOST / MS Update CPU Utilization Problems?