Monday, April 21, 2008

Deploying WSS/Moss 2007 to an Existing Install of Project Server 2007

An Angry Error

My team has been running Project Server 2007 for quite some time. While it was originally set up to allow project managers to sync their MS Project timelines in one place it eventually became our team portal for storing all team calendar/project/document data.

The problem with this was that there are quite a few WSS/MOSS features that the rest of us wanted to collaborate with that weren't available with the stock Project Server 2007 install.

As such we decided to install MOSS 2007 on the machine. There's pretty good documentation on how to go about doing this. I was walking through the document steps and I ended up installing MOSS which went fine. But when it came time to run the SharePoint Products and Technologies Configuration Wizard, I ran into this angry error (below) and that's what this blog entry is about.

System.UnauthorizedAccessException: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)) at Microsoft.SharePoint.SPGlobal.HandleUnauthorizedAccessException (UnauthorizedAccessException ex)

Error

The Fix

The solution ended up being quite simple (although exhaustive). I needed to add my credential as a Site Collection Administrator to EVERY site collection in the farm. I'm guessing that during the config process the Wizard tries to walk through all the site collections do setting detection among other things? I know the fix isn't pretty, but it's what got me over the finish line.

In case you forgot how to do this:

  1. Open up the SharePoint Central Administration site.
  2. Navigate to Application Management and click on Site collection Administrators.
  3. From there you set your credential as the Site Collection Administrator for each Site Collection in each Web Application.
  4. Run the SharePoint Products and Technologies Configuration Wizard again. You'll probably get prompted as to whether you want to overwrite your default site or simply not create a default site. Afterwards you the wizard should finish properly.
  5. I'd recommend going through the rest of the TechNet article to ensure that you're following the rest of the right steps, but hopefully you're out of the woods for now.Success

That's it. Hope she helps.

Best,
Tyler

Tuesday, April 15, 2008

Managing Blocked File Types in SharePoint 2007

Not Allowed

The other day I was trying to upload a file with a particularly hostile file extension into a SharePoint document library. When uploading it through Windows Explorer I would get an error like:

Cannot copy [FileName.Ext]: The parameter is incorrect.

When I tried to upload the same file through the browser UI I got a slightly better error:

The following file(s) have been blocked by the adminitrator: [Path/FileName.Ext].

Allowed

SharePoint manages a list of file types per web application that are not allowed to be uploaded or downloaded. It also affects their behavior on server. For example if you were unpacking a .ZIP in a document library files that had blocked extensions would not be unzipped. A possible solution is to remove this file extension as a blocked type. To do this:

  1. Open up the SharePoint Central Administration web site.
  2. Under Operations click on Blocked File Types under the Security Configuration section.Managing blocked file types in SharePoint central administration.
  3. Select the Web Application that you want to allow/block the file type for and add/remove the extension from the list.Add/Remove your blocked file type from the web application list.
  4. Click OK. When you revisit your document library you should be able to upload those types of files.

That's it. Hope that helps someone.

Best,
Tyler

Thursday, April 10, 2008

Walkthrough: Installing Adobe (v6) PDF iFilter for SharePoint 2007 (Moss/WSS)

Purpose

Out of the box SharePoint will index many types of content. This includes a lot of popular file formats (.ppt, .docx, .doc, .xlsx, .xls, etc...). A list of these file types can be found here. You'll notice that a pretty popular file type (.pdf) is NOT in this list. For the SharePoint search to be able to index .pdfs you need to install a PDF IFilter (Index Filter) that will help the indexing service process PDF files and when building a search index. There are a couple PDF IFilters available from a series of different vendors, but the most popular is probably the one from Adobe. You can download the Adobe PDF IFilter here.

Walkthrough

  1. Stop the IIS Admin Service: Start->Run->Services.msc->Locate the IIS Admin Service and stop it.
  2. Download the Adobe PDF IFilter and install it on your indexing server.
  3. Install this GIF (pdficon) or any icon of your choosing to "C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\IMAGES"
  4. Edit the DocIcon.xml file at "C:\Program Files\Common Files\Microsoft Shared\Web server extensions\12\Template\Xml\DOCICON.XML" and add the following text under the <ByExtention> tag.
    <Mapping Key="pdf" Value="pdficon.gif"/>
  5. Recycle the application pool of the Shared Service Provider OR do an IISRESET if you're lazy.
  6. Open the SSP Admin site (Central Administration->SharedServices1). Click on Search Settings->File Types->New File Type) and add a pdf file type.
  7. Perform a full crawl on content sources. Search Settings->Content Sources and Crawl Schedules, click on the Content Source you want to perform a full crawl on. Check the Start Full Crawl check box at the bottom and then click OK. Wait for the crawl to finish.Starting full crawl after installing PDF IFilter

You're done! PDF content should start showing up in searches now!Search results that find content in a PDF using IFilter.

Troubleshooting

There's been a couple of machines I've done this one where I've had to manually register the PDF IFilter dll (regsvr32 "C:\Program Files\Adobe\PDF IFilter 6.0\PDFFILT.dll") and then recycle the SSP site before the icon would show up. Usually in these cases I also had to do another full crawl after manually registering the PDFFILT.dll. It's probably a good idea to define a new content source with a small set of content (a couple of small pdfs in a document library) for testing.

I also sometimes get errors of the form when indexing large PDFs:

The file reached the maximum download limit. Check that the full text of the document can be meaningfully crawled.

This is because the maximum document size by default is 16 MB. You can increase it with instructions found here.

Hope that helps.

Best,
Tyler

Friday, April 4, 2008

Unit Tests and the InternalsVisibleTo Property

Confusion

The other day I ended up making the decision to strong name a series of assemblies. It also usually means revisiting some config files somewhere and re-referencing the same dll's all over again but with a strong name. Of course there's many benefits to strong naming but that's not what this is about.

What I DIDN'T see coming was how this would throw a wrench into my unit tests. Normally when you create Unit Tests under Visual Studio if you are testing internal (friend in VB) methods it will automagically add the System.Runtime.CompilerServices.InternalsVisibleTo attribute on the assembly that is going to be unit tested. But the moment I strong named the assembly I wanted to run tests on I ended up getting the following error:

Friend assembly reference 'Foo.Bar.Test' is invalid. Strong-name signed assemblies must specify a public key in their InternalsVisibleTo declarations.

I dug through some MSDN documentation and found that it wanted me to do just that, instead of:

[assembly: InternalsVisibleTo("Foo.Bar.Test")]
I was supposed to use a syntax that specified the PublicKey, like so:
[assembly:InternalsVisibleTo("Foo.Bar.Test, PublicKey=32ab4ba45...")]

It took a bit of thinking for this to finally make sense to me. Strongly Named assemblies don't mind exposing their internals to other assemblies, but they'd at least like them to also be strongly named AND have have us specify the public of any assembly that's going to be digging around in its internals.

This means we have to strong name the Unit Test assembly as well.

In addition we still need to get the Public Key off of the Unit Test assembly after we strong name it.

It's important to note that the PublicKey is NOT the PublicKeyToken that you might acquire through Reflector and is part of the strong name. The PublicKey is the value of the public key extracted from the Key Pair/.snk file with the sn.exe utility.

Solution

You can extract the public key from an .snk with the sn.exe tool from the .NET SDK. First we extract just the public key from the key pair (.snk) file into another .snk file.

sn -p Foo.Bar.Test.snk Foo.Bar.Test.PublicKeyOnly.snk
Then we ask for the value of that public key:
sn -tp Foo.Bar.Test.PublicKeyOnly.snk

We end up getting a super LONG string of hex, but that's just what we want, the public key value of this key pair.

We add it to the strongly named project that we want to expose our internals from and we're good to go. Before what looked like:

[assembly: InternalsVisibleTo("Foo.Bar.Test")]
Now looks like.
[assembly: InternalsVisibleTo("Foo.Bar.Test, PublicKey=00240000048000009 40000000602000000240000525341310004000001000100354f0966de4a992baa1ed0f2 faf643f86fd2c74aee8b9dc6c0321f9d658166658ec154aaed70ab4b92a21a3c1e7e53 200232043c0d0b791496fd0201d21f18433ee9507022f2a72829d1dd32b106f86c68e 620d2a39f02f3a8b82aa23196ef7f7f4880020dd340dd2dfecdd1b3051b1e659c9e18c 8e21cc90bc33de306712b86")]

And we're done.

Hope that helps,
Tyler