Wednesday, November 19, 2008

Which w3wp.exe is the one I want?

If you have every tried to debug a web application running on Windows Server 2003 you will be faced with which w3wp.exe process do you attach to remotely. I have figured out a few ways. In order of ease:
  1. User Name - If you change the App Pool Identity to something other than Network Service (like your personal user account... temporarily of course) you should be able to open Windows Task Manager and see name next to one of the w3wp.exe process. I highly recommend stopping and restarting the Application Pool (not just recycle it). The best part is you can also see the User Name in Visual Studio when are in the attach to process window and choosing the process.
  2. CPU Time - If you open Windows Task Manager, now recycle the App pool. The CPU Time should go to zero. When you hit a page on the site, it should show some small value greater than zero depending on how much cpu the page actually takes. This will allow you to get the PID (you may have to add the column to Windows Task Manager) which you can see when you are in Visual Studio and attaching to the process.
  3. You can also use Sysinternals (now Microsoft owns it so....) Process Explorer. Using this tool, you can right click on the w3wp.exe in its list of processes and look at the Command Line that was used to launch the process. The last parameter is the name of the App Pool. Assuming you are using different app pools for each web site, this will allow you to get the PID, and use that to attach to the process just like the other scenarios.
I hope this helps. I find it generally frustrating that it is so difficult to determine which process is the one I need. Oh well, this seems to work reasonably well.

Friday, November 14, 2008

Can't access Account Settings in Outlook 2007

If you are using Outlook 2007 and have some controlling system administrators they may have locked you out of Account Settings in Outlook 2007. You will know they have locked you out because you will get a message like the following when you go to Outlook 2007 | Tools | Account Settings. This feature has been disabled by your system administrator. For more information, contact your system administrator. This is unfortunate because this is an easy place to add RSS Feeds, etc. To temporarily (until the next Group Policy refresh most likely) enable your access again there is a very easy registry change you can do. In fact, you can put the registry change in a file and just double click it to make the change. Once the change is applied you should be able to open up Outlook 2007 and go to Tools | Account Settings. The registry key you need to change is the following:
HKEY_CURRENT_USER\Software\Policies\Microsoft\Office\12.0\Outlook\Setup\ModifyAccounts

You need to set it to 0 to enable access, and 1 to block access.

If you want to be able to just double-click a file to make the change do the following.

  1. Open notepad
  2. Copy and paste the following into notepad Windows Registry Editor Version 5.00 [HKEY_CURRENT_USER\Software\Policies\Microsoft\Office\12.0\Outlook\Setup] "ModifyAccounts"=dword:00000000
  3. Save file with a .reg file extension. For example: unlockOutlook.reg
Keep in mind this is a group policy so you will likely need to make the change (or double-click the file you created) each time you want to access the Account Settings. For more great Outlook hacks check out: http://wiki.yobi.be/wiki/Outlook#All_in_one_registry_file

Monday, November 10, 2008

Release the memory after using a SPWeb object

It is important to clean up after you are done with a SPWeb. Below is a snippet of code that connects to the top level site of SharePoint and loops through all the webs (recursively). The important thing to note here is that after we do whatever we want to do with the web, we call the Dispose() method on the SPWeb. If you don't do this and your site if big, you will run out of memory. Since this code needs to run on your SharePoint server, it is definitely not a good thing to use up all your memory. :)

using (SPSite site = new SPSite("http://sharepointserver"))
{

   SPWebCollection webs = site.AllWebs;
   foreach (SPWeb web in webs)
   {
       DoSomethingWithWeb(web);
       web.Dispose();
   }
}