Thursday, December 31, 2009

Finding Process ID for Debugging

If you do SharePoint development, you'll eventually need to debug SharePoint itself. You'll need to pick one of several w3wp.exe processes from the list. The question is which one?

The answer is a little VB script called iisapp.vbs.

Open a command window, type iisapp.vbs and you get a list like this:

C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN>iisapp.vbs
W3WP.exe PID: 7800 AppPoolId: SharePoint Central Administration v3
W3WP.exe PID: 4428 AppPoolId: SharePoint - 80
W3WP.exe PID: 2872 AppPoolId: SharePoint_Pool
C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN>

The middle entry in this list shows the process ID you need.

Saturday, December 12, 2009

Deleting an InfoPath Form Template

If you work with InfoPath and SharePoint Forms Services, someday, you'll need to delete a form template. There's a catch: Deleting the form doesn't delete the content types created when the form was originally uploaded. This can be important.

When an InfoPath form template is uploaded to SharePoint using Central Administration, SharePoint creates a content type for the form. Published properties of the form are turned into site columns.

There are probably good reasons why this is true, but it can lead to situations where the form template appears to live on your site after you've deleted it. Here's one of them:
  1. Pick a set of properties to publish with your form, then publish the form to your SharePoint server using Central Administration.
  2. Use the form in a forms libary and take note that your properties are available in the library.
  3. Delete the lirbrary
  4. Delete the form template using Central Administration.
  5. Change the form's published properties and republish the form template.
  6. Use the form in a forms library.
  7. Note that the library columns are the old InfoPath properties, not the new ones. Its almost as if the ghost of the old InfoPath template lives on.

There are a couple of ways to deal with this. First, delete the content type and site columns that go with your form.

Second, and probably better, create and manage the site columns as a separate project. When you publish the form template, take care to connect the published properties to your content types.

Wednesday, November 25, 2009

More on Excessive Number of SPRequest Warnings

This is a continuation of a the previous posting and covers what I've figured out since then.

First, I'm increasingly convinced that this warning may be less of an issue than I previously believed. The warning threshold is at 8 open SPRequest objects. Opening the default.aspx page in an un-modified team site page creates 11 such objects, which is enough to trigger the warnings. Since pages are cached, subsequent hits don't make the problem worse. When the thread terminates, it looks like everything gets cleaned up properly. So, there may not be an issue beyond the too-liberal use of SPWeb and SPSite which wastes memory.

Second, contrary to some other blog posts, the issue described in KB932621 (probably) isn't directly addressed in Service Pack 1 or Service Pack 2 and probably isn't needed. See this discussion and this one to retrace my steps. Its probably that this hotfix existed for some period of time. It defintely doesn't exist anymore and I'm not sure there is much reason to ask for it.

Third, this article about best practices includes a couple of very useful registry entries that will help separate real issues from potential issues.

I believe the default warning threshold is much too low and should be raised into the 20-25 range in most real-world SharePoint servers. This can be done by adding this key to the registry:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\HeapSettings

LocalSPRequestWarnCount = desired threshold value (That's a DWORD value)

On development servers, you should think about setting a registry key that tells Sharepoint to log SPRequest objects that are never cleaned up when garbage collection runs The log entries will contain the stack trace where the allocation originally occurred. If you see these, and the stack trace includes your code, run SPDisposeCheck.

Here is the key:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\HeapSettings SPRequestStackTrace = 1

Monday, November 23, 2009

Potentially excessive number of SPRequest Objects

I've seen this error message in just about every SharePoint 2007 server I've worked with:

"Potentially excessive number of SPRequest objects (xx) currently unreleased on thread yy..."

I spent the day on this one and have yet to get to the bottom of things.

First of all, I'm not all that sure how much to be worried about this. After all, if everyone else has it, what's the big deal?

The obvious source for this problem is a truely unfortunate detail about how the SharePoint API works. The unfortunate part is that while the SharePoint API has a nice shiney .Net layer on top, its really just a bunch of old COM code underneath (probably written in C++). COM objects are reference counted instead of garbage collected. Their .Net wrappers (SPWeb and SPSite) implement IDisposable, and the programmer has to either wrap them in a using clause or call the Dispose() method. If one of these objects is holding instances of another, it can be kind of messy to figure out who has the cleanup duties.

If you don't clean up, the objects hang around for an indefinite period of time in memory. Every page hit adds to the party until finally, the web server kills the worker process (because its taking all the RAM on your server). This does bad things to server performance.

The first and obvious place to look for problems is in your own code. I spent the day going over all our code because I figured that it had to be something we did. I mean, Microsoft wouldn't ship anything this bad, would they? (Keep reading)

During that process, I found a tool called SPDisposeCheck that seems to help find these problems. Has a couple of bugs, but it helped me find about 20 of these problems in our code.

Unfortunately, the development server was still spitting out tons of these messages and leaking like crazy (more that 20,000 bytes per request).

So, I started stripping all of our code out of the server. By the end of the day, I was all the way down to a bare-bones MOSS with absolutely no custom code. What's left was all Microsoft-written. It still leaks like crazy and still spits out lots of errors on every request.

While I was preparing this blog, I ran across this post:

Posters on this forum talk about KB932621, which has something to do with bugs in the Navigation controls on SharePoint that generate the "excessive" SPRequest objects messages. Strangely, I can't find this KB article on Microsoft support.

The posting is about 2 years old. Is this fixed in SP2? Have to keep digging to find out. I'm wondering if I'm going to have to burn a support ticket?

Or maybe I should do what everyone else does, which is ignore it.

Tuesday, November 17, 2009

Setting Master Page in Site Definition

There's a lot of information about this on the MSDN site and in the general internet.

There are at least 4 ways to attach a master page to a SharePoint site definition:

  • Install the master page as a separate feature, then identify the feature in the site's onet.xml. Here's a how-to.
  • Include the master page with the rest of the site definition files, then identify the master in the onet.xml file. Here's another how-to.
  • Write a feature receiver and use code that sets the master page when the site definition is activated. Here's a CodeProject Link with how-to.
  • Install the master page as a separate feature, then staple the feature to the site definition using a feature stapling feature. A link to feature stapling.
  • Add the master page specification to the site pages (using SharePoint Designer or Visual Studio).

IMPORTANT: Comments added to the second link correct an important flaw in the original post. The URL needs to start with a leading slash! ("/_catalogs/masterpage/custom.master")

The big question on my mind right now is how do you decide when to use these techniques.

As far as I can tell, here are the advantages and disadvantages of these various approaches:

  • If you install the master page as its own feature, you can use it on more than one site definition. If you include the master page with the site definition, the page can only be accessed from that site.
  • If you're more confortable with code than you are with XML, then use a feature receiver.
  • If you want to change the master page for one of the stock SharePoint site definitions (like STS), then feature stapling is your only option.
  • If you can't or don't want to write code, you can use SharePoint Designer.

Tuesday, May 26, 2009

Principle of Least Astonishment

I've been reading code from other programmers lately and I'm feeling the need to vent a little about things that are more complex than necessary.

We all bring a limited amount of intellectual energy to the party. Let's not waste it on efforts to impress one another.

If there are two ways to solve a problem where one is boring and is cool, pick the boring one. Save the cool trick for when you really need it.

So, let's all renew our committment to the principle of least astonishment. It applies to fellow programmers as well as our users.