Monday 17 December 2007

Using the SharePoint Content Deployment Wizard

So if you've read the earlier posts about the tool (Introducing the SharePoint Content Deployment Wizard and When to use the SharePoint Content Deployment Wizard) and figure this is a useful tool, let's go onto the next level of detail. Generally speaking the Content Deployment Wizard 'just works', but if you want to know more about the different options, read on. This post contains reference information and a guide to some deployment scenarios at the end.

Firstly, let's remind ourselves of some of the fundamental things to remember when moving content using the Content Migration API (the underlying SharePoint API used by the tool):

  • dependencies of selected content (e.g. referenced CSS files, master pages) can be evaluated - in the tool they are automatically included in the export - check 'Exclude dependencies of selected objects' to disable this
  • all required content types, columns etc. are automatically included in the export
  • in contrast to STSADM export, it is possible to retain GUIDs during deployment (where objects are not being reparented) - check 'Retain object IDs and locations' to enable this
  • no filesystem files (assemblies, SharePoint Solutions/Features etc.) are deployed - these must already be present on the target for the import to succeed)
  • the following content does not get captured by the Content Migration API - alerts, audit trail, change log history, recycle-bin items, workflow tasks/state

In particular it's the 2nd and 3rd points which make the API (and the Wizard) a good way to deploy content in SharePoint.

What can be deployed?

The Content Deployment Wizard allows any content to be selected for export - site collections, webs, lists/document libraries, folders, right down to individual list items and files. Objects in the treeview can be added to the export by right-clicking them, which for a web, brings up a menu shown below:



These are explained:-

  • 'include all descendents' - exports the container and anything beneath it
  • 'exclude descendents' - exports the container only
  • on webs only, the 'include content descendents' option is shown - this will include all immediate content such as lists/libraries, but will exclude all child webs of the web.

Note that on the import, the Wizard will bring in all the contents of the selected .cmp file(s) - there is no option to partially import a package. Hence if different import options are required for different content, the exports should be broken into separate chunks.

Export options

On the export settings screen, numerous options can be applied to exports:

  • 'Exclude dependencies of selected objects' - by default the Content Migration API will automatically include dependent objects of whatever you select. This can include CSS files, master pages, images and the like, but also list items which are displayed on a page included in the export. This can be turned off with this checkbox so only the objects you select are exported.
  • 'Export method' (options are 'ExportAll', 'ExportChanges') - for now ExportAll is the option to select, ability to export changes only will come in a future release
  • 'Include versions' (options are 'LastMajor', 'CurrentVersion', 'LastMajorAndMinor', 'All') - should be self-explanatory
  • 'Include security' (options are 'None', 'WssOnly', 'All')' - note that since security is defined at the level of a web, selecting one of the include security options for a smaller object (e.g. list) actually exports security for the entire web. Both 'WssOnly' and 'All' export SharePoint item-level object permissions, so if you're using SharePoint groups to manage security for example, both the actual permissions and groups will be carried over, and you can add a different set of users/AD groups on the destination. See Migrating Security Information on MSDN for more details.

Import options

On the import we also have several options, some of which correspond to options selected on the export:

  • 'Import web URL' (actually shown on the 'Bind to site' screen) - this is used for reparenting operations only. If you are just moving content from source to destination but are not changing the location in the structure, this textbox can remain blank. Alternatively, for operations where a web or list is being imported but the parent web will not be the exact same web on the destination, the URL of the new target web URL should be entered.

    Note that the later option to 'Retain object IDs and locations' should not be selected when reparenting, since we are changing the location in this case.
  • 'From single file'/'From multiple files' options - the Wizard always exports with file compression enabled, so when exporting content over 25MB, files are split into several files at this threshold. When importing from such an export, select the 'From multiple files' option and browse to the folder. In the textbox, enter the 'base filename' - this should be the name of the first file without the number e.g. 'MyExport.cmp' rather than 'MyExport1.cmp'. 
  • 'Retain object IDs and locations' - this setting requires particular consideration. Duplicate GUIDs are not permitted in one database (i.e. SP web application), so the choice often depends on what you are importing. If you are taking a site from development to production, the object GUIDs will not yet exist on the destination, so I check the box to ensure the objects are assigned the same IDs in both environments, and all linkages are preserved. If you are reparenting a list or web, you will leave the box unchecked, so that new GUIDs are assigned are the location can therefore be changed.

    I highly recommend reading the content listed in the 'Useful links' section at the end of the article to properly understand this setting.
  • 'Include security' - this allows security information in a package to be imported, assuming one of the options to include security was selected on the export
  • 'Version updates' - allows control over whether new versions should be added to existing files, or whether the existing version should be replaced etc.
  • 'User info update' - allows control over whether 'last modified' information should be imported. Often this only makes sense if the same set of users exist in the source and destination

Scenarios quick reference

The following table lists the most common settings for a given deployment task:

Deployment item

Typical settings

Entire site collection
  • Site collection should first be created on the destination.
  • When exporting, select 'include all descendents'.
  • When importing for the first time, ensure 'retain object IDs and locations' is checked.
  • Select one of the 'include security' options if you wish to deploy object permissions and users
Web
  • When exporting, select 'include all descendents'.
  • When importing for the first time, ensure 'retain object IDs and locations' is checked if web will have same parent as on source.
  • If web will have a different parent, do not check retain object IDs and locations' and ensure 'import web URL' is specified
Document library/list
  • When exporting, select 'include all descendents'.
  • When importing for the first time, ensure 'retain object IDs and locations' is checked if list will have same parent as on source (i.e. not reparenting).
  • On subsequent imports, ensure 'import web URL' is specified if not importing to the root web, and do not check 'retain object IDs and locations'
File/list item
  • Ensure the parent library/list exists on the destination
  • Do not check 'retain object IDs and locations' if the item already exists on the destination

 

So hopefully that's some useful reference information. On a final note, the next beta version with much improved treeview performance should be ready over the next week or so!

Useful links

Friday 14 December 2007

When to use the SharePoint Content Deployment Wizard

Following my introduction to the tool last time, today I want to try to help position the tool for people who aren't sure if it could be useful to them or for what scenarios - if you only take one thing away from my postings on the Content Deployment Wizard it should be this.

I see the 'value-add' of the Content Deployment Wizard over existing deployment methods such as STSADM export/content deployment in Central Administration to be:

  • ability to "cherry-pick" content to deploy using a treeview - this is from entire site collection down to individual list item or file. (This is the big one since the standard SharePoint tools do not supply a method to do this)
  • ability to control whether object GUIDs are retained - this is required for scenarios where the destination should be a mirror-image of the source, such as staging/production environments for the same site
  • ability to move certain objects (limited to webs and lists in the initial release) to a new location on the import target, known as 'reparenting'

I would suggest the tool could well have a place in your SharePoint toolbox, but it's likely to be something you use every now and then, rather than all the time. The two main scenarios where I use the tool are:

  • at the end of the development phase when I need to move a site from development to staging/production. Here, the tool allows me to be sure that all relationships/linkages between objects will be preserved (so no problems with ListViewWebParts/DataViewWebParts/InfoPath forms for example)
  • any odd occasions where I have a need to move a particular document library/list, or a particular set of files (e.g. master page, page layouts, CSS etc.). This assumes by the way, that the files were not deployed with a feature - I wouldn't recommend mixing the deployment methods like that.

N.B. It should also be possible to use the tool for ongoing updates to specific files/list items through different environments in a development/test/staging/production situation. An example of this is deployment of just master pages, page layouts and CSS files on a WCM site (meaning all other content authored by the client [e.g. in the 'Pages' library] does not get overwritten on the target) but I haven't had the opportunity to try this on a real project yet.

Some areas where the tool cannot be used (i.e. the tool does not yet support this usage) are:

  • exporting only changes since a certain timestamp (change token) from a site
  • importing individual list items/files to a new location on the target (reparenting)

On the last point, the 'new location' would be a document library or list, since these items have to be in such a container - they cannot exist at the root of a web. Currently the tool supports reparenting webs and lists, but not individual list items/files. What is currently possible with individual list items/files, is moving selected items from a source to a target where the structure is the same (e.g. move Doc2 and Doc5 from "Team documents" on the source to "Team Documents" on the target). Usefully, whenever a file is exported/imported using the tool, the associated list item is also deployed, meaning metadata updates to column values are deployable.

Hopefully that might help you understand where the Wizard fits in. If you're thinking the Wizard could be useful to you from time to time, stay tuned for my next post which will have more detailed 'usage' information. 

Wednesday 5 December 2007

Introducing the SharePoint Content Deployment Wizard

Regular readers might have spotted I've been slightly quieter than usual over the past few weeks - actually I've not been slacking, but working on a tool which you might find useful from time to time. As I've discussed in numerous posts, deployment of SharePoint artifacts is something that's perhaps more complex than it should be, and the standard tools provided don't always simplify this picture. Personally, over my past few MOSS projects, there have been several times when I've thought:

  • I just need to move this document library from A to B
  • I just need to move these selected files (e.g. master page, page layouts, CSS etc.) from A to B
  • I just need to move this web from A to B
  • I just need to move this site collection from A to B
  • I just need to move these 20 list items from A to B

If only there was an easy way! CMS 2002 users may remember the SDO export mechanism which allowed you to use a treeview to select exactly which content you wished to move, but unfortunately there's no similar tool for MOSS. Sure, we have Content Deployment and STSADM export etc., but the lowest level of granularity is a web, and if you don't want to overwrite the whole thing neither option can be used. The only other option is to write code which uses the Content Migration API. This is fine for projects which have the appropriate development skills and time, but otherwise things can be tricky.

Enter the SharePoint Content Deployment Wizard.

The tool provides a wizard-like approach to deploying content between SharePoint sites. The selected content is exported using the Content Migration API (PRIME), giving a .cmp file (Content Migration Package) which can be copied to other servers.

Since pictures are often more useful than words, let's look at using the tool. Click to enlarge any of the images below:

EXPORTING CONTENT

Welcome screen (click any image to enlarge):


Select action (import or export) and provide site URL:

 

For export, use the treeview to select which content you wish to deploy. On container objects such as webs, there are options about whether descendent objects should be included:

 

Select options around security, dependencies, versions and name of the export file:
 
 
 
The details are shown back for confirmation, and when 'Finish' is clicked the export will begin:
 
 
 
IMPORTING CONTENT
 

Browse to the .cmp file we exported in the previous steps, and select options around security, versions and, importantly for some scenarios, whether object IDs should be retained:
 
 

The details are shown back for confirmation, and when 'Finish' is clicked the import will begin:
 
 
 

And that's the gist of it. This is the first beta of the tool and I'm sure there will be issues. Regardless, when using any tool which makes this kind of change to your data you should always take a backup before performing the import. Depending on what you're doing, it could be difficult to revert back to the previous state otherwise.

Some other notes:

  • the tool must be installed locally on the server which hosts the site
  • not all features of the Content Migration API are supported by the tool
  • the next beta (mid-December) will properly support large sites - currently the site bind operation can be slow for large sites since the treeview is built in one operation
  • it must be run under an account which has the appropriate permissions to the SharePoint site - use the Windows 'Run as..' feature to do this if necessary (shown below in the image below- right-click on the .exe and select 'Run as..')


 
In the next post, I'll cover details on different usages of the tool and the effect of different options. The tool also supports reparenting (e.g. importing a web or list to a different parent on the target) and I'll talk about this.

You can download the tool now from www.codeplex.com/SPDeploymentWizard. All feedback (particularly bug reports) welcome, either post here or on the Codeplex site.

Sunday 25 November 2007

Part 2 : Blending publishing/collaboration functionality in SharePoint

A couple of months ago I wrote an article on some of the issues around building sites which are not pure publishing or collaboration solutions, but which mix features of the two. I mentioned at the time that I would follow up on these issues and any others we came across at the end of the project, so here it is.

As a quick recap, we said that characteristics of a site which blends publishing/collab features could be:

  • site has completely bespoke look and feel/navigation
  • users will work with document libraries, discussions, calendars etc.
  • site templates or definitions are used to create several sites with the same content/functionality
  • custom workflow is used to support a business process (other than standard content publishing), perhaps with InfoPath forms

    So let's cover some of the issues you may face in projects like this:

    Look and feel of system pages

    This refers to the fact that whilst pages you create will happily use your custom master page, any 'system' pages in the '_layouts' directory will not share this look and feel by default since they reference a separate master page, 'application.master', which is also stored on the filesystem in '_layouts'. Such pages are often seen due to the use of collaboration functionality in our site, examples being when a user uploads or edits metadata for a file, starts a workflow etc.

    In fact this turned out to be less of an issue than I anticipated because:

    • a quick test showed that the use of a HTTP module to switch the master page of these pages works fine. Several people have documented this approach, and I note that Ted Pattison has provided a Codeplex feature for those who would prefer not to write their own code for this. (N.B. though not strictly supported, the idea behind the HTTP module approach is that it is better than modifying files installed with SharePoint such as 'application.master', and can be disabled with a switch if we need to fall back in line with official support.)
    • our client decided this was a low priority item, that we may or may not deal with further down the line

    On this subject, I see that Microsoft have themselves released KB article How to customize application pages in the Layouts folder in SharePoint Server 2007 and in Windows SharePoint Services 3.0. Bizarrely, the proposed solutions are modifying the standard files but taking backups of the originals, or duplicating the 'layouts' virtual directory in IIS - the HTTP module idea is not mentioned. Without dwelling on this too much, this seems crazy to me and I'm not the only one. I still much prefer the HTTP module solution and will use this on my projects where it is required, though will be sure to regression test thoroughly.


    Use of InfoPath with forms authentication

    This is an interesting illustration of blending the two types of functionality - collaboration solutions may well use InfoPath for forms, but publishing sites typically use forms auth for a customized/branded login experience. Straight away we ran into problems using InfoPath with forms auth - essentially the link to create a new instance of an InfoPath form in a forms library would disappear (example link shown below [Windows auth enabled here]):



  • It took a while for me to track down that this is related to the 'Client Integration' switch in Central Admin. For a forms auth site, this gets set to 'off' by default, but defaults to 'on' for windows auth sites. Unfortunately, resolving the problem isn't as simple as flicking the switch back, since what the switch does is remove certain links and disable ActiveX controls which integrate with the browser for link-handling. With the switch enabled again, the InfoPath link reappears on the content type, but when a link to say, a Word document is followed, the browser now shows the basic prompt to download or save the file. This means the more sophisticated 'do you want to check out or open as read-only' prompt is lost and users must work with documents offline and upload to SharePoint at the end of editing, rather than being able to save back directly to the SharePoint repository. In other words, unacceptable to most for a SharePoint 2007 collaboration solution.

    In the end I found others in the same position, but didn't find a solution in a short timeframe. Microsoft support tells me "they were unaware of any instances of of these two features working together in this way", so the disappointing conclusion is that these two bits of functionality don't play well together. Our client thus decided to accept windows authentication (our authentication store was always going to be AD rather than SQL anyhow). However, I'm actually convinced it would be possible to get this working given more time - I think the way forward would be to amend the site design to have a link to the InfoPath form in the standard content of a page rather than relying on SharePoint to supply the link. The information supplied in How to: Use Query Parameters to Invoke Browser-Enabled InfoPath Forms would be used here. I'm sure this must be possible and others have done it, I'd be interested to hear from anyone who has.


    Overidden control not appearing on standard collaboration pages

    Our client had requested some customizations to the search box, and going through our bug list towards the end of development, I realised that our customized version was present on pages we had created, but not existing list pages such as [MyList]/Forms/AllItems.aspx or similar. This seemed strange given that all pages were using our custom master and shared the same header! Digging deeper, this is caused by the fact that SharePoint uses a delegate control to load the search box .ascx file, and to properly override the control across the site, we needed to create a Feature to specify that our .ascx file should be used in preference to the standard control. If we had directly replaced the existing control on the filesystem this would not be required, but when adding custom files in order to avoid modifications to existing files, this extra piece is required. One to look out for when building sites of this nature.


    Summary

    I read some blogs/discussion threads earlier this week which suggest customizing SharePoint in this way is nigh on impossible, but our project (and surely many others) prove this isn't the case. As is often the case with such a functional platform, there's perhaps a greater chance of success if you understand the nuts and bolts of what SharePoint is doing, but extensive customizations to collaboration-focused sites are inherently possible!

    Sunday 11 November 2007

    Change a SharePoint site's URL

    Something you may find yourself tasked with at some point, is changing the URL of an existing SharePoint 2007 site. This is a fairly interesting scenario, and it's fair to say the relationship between SharePoint and IIS makes this more complex than for a standard .Net site. However, there are several possible solutions. The first things many of us would think of as potential approaches would probably be:

    • extending the web application onto another URL
    • using Alternate Access Mappings somehow

    Depending on your site both could be valid methods, but as with anything SharePoint-related, there are different things to watch out for with the different approaches. As an example, extending the web application wasn't the right approach for our scenario for the following reasons:

    • the site shouldn't actually exist at the old URL, but a redirect was required
    • InfoPath forms don't seem to deal well with the 'extended web application' configuration. (Problem detail - on one URL everything will be fine, but if the two web applications use separate site collections, on the other you're likely to see security errors when opening forms. This is because the form templates are referenced in the other site collection - a document library can only have one URL to the document template, and publishing a form to a content type stores an absolute link in the content database.)

    Additionally some quick tests with Alternate Access Mappings didn't seem to give the expected results for me, so I decided on another approach since I knew it would work and didn't have much time for experimentation. So this was my process:

    Changing a site's URL by recreating the site (downtime required)

    1. Stop old IIS site.
    2. Create new web application in SharePoint, bind to new IP address in IIS.
    3. Apply SSL certificate if appropriate.
    4. Create new site collection for this web application using the blank site template.
    5. Export content using the SharePoint's content migration API (I have a tool which does this, which will shortly be on Codeplex) ensuring all security data is exported. Alternatives to this step include STSADM -O BACKUP and STSADM-O EXPORT. *
    6. Import content into the new site collection, ensuring to include security.
    7. Amend any absolute URLs in .udcx data connection files used by InfoPath.
    8. Republish any InfoPath forms to the new site.
    9. Configure search:
      1. Ensure new URL is a content source.
      2. Update any crawl rules which use absolute URLs.
      3. Update 'authoritative pages' as appropriate.
      4. Start full crawl.
      5. Update scopes.
      6. Go to Site Settings > Site collection administration > Search scopes, add any custom scopes to search dropdown (if using standard search web parts).
      7. Ensure search web parts use relative URLs/do not reference old site URLs.
    10. If a redirect from old URL is required, create new IIS site to implement this:
      1. Create new site in IIS and bind to old IP address.
      2. On 'Home directory' tab, specify content should come from 'A redirection to a URL' and enter the URL.
    11. Ensure DNS/firewalls are configured appropriately for new URL, remembering to allow appropriate time for DNS propagation.
    12. Perform testing.

    * N.B. Between the content migration API and STSADM export, I prefer the former since this allows control over whether object GUIDs are retained (more information in STSADM export, Content Deployment, Content Migration API, Features/Solutions - deployment options compared). STSADM backup/restore is discussed in next section.

    Considerations to this approach

    • When using the content migration API or STSADM backup/restore, the following items are not included - alerts, workflows, recycle bin state or site collection properties. These must be migrated/recreated separately.
    • Regression testing is absolutely required since the site is effectively recreated

    As a way to improve on the first consideration, another option would be STSADM backup/restore (though I've not tried this approach). Notably this method does collect data for the items which the other approaches exclude, however due to the nature of our site, none of these were significant problems.

    So this method was successful, and hopefully this information allows folks to see some of the pros and cons without having to spend the time going through it themselves. However, I also note an approach based on Alternate Access Mappings suggested by Faraz Khan. Since this was only published in the few days before this article it was too late for my scenario, though I'd encourage you to take a look. Note that Faraz also points out considerations such as certain links not being updated to new URL without fix-ups, though this doesn't seem to be a major issue. It does echo my point about there being different things to watch out for with the different approaches, but both methods provide valid techniques for changing a SharePoint site's URL.

    Thursday 1 November 2007

    Master pages/page layouts deployed as Feature not updating

    Since Deploying master pages and page layouts as a Feature has been the most heavily commented article on this blog, and several of the posters seem to have run into the same problem, I wanted to write a quick post with some more information from my experiences on this.

    So this is something of a non-standard post, feel free to tune out if it doesn't affect you ;-)

    Anyway, I decided to do some more testing to see if either I'd got something wrong or if perhaps I was doing something differently to the people having problems. My test was basically to knock up a publishing site with a master page and page layout (associated with a custom content type as it often would be), then go through the update process. This is what I found:

    • making updates to the files (outside of the 12 folder) and then XCOPYing these to overwrite the files in the 12\TEMPLATE\features\MyFeature\ directory successfully updated the site. No need to deactivate/activate the Feature.
    • using a Solution package to deploy the files (when using Features this is generally what I do since I'm in a farm environment) - again this updated the site correctly when I upgrade the Solution (stsadm -o upgradesolution). This is to be expected since underneath the exact same thing is happening as in the previous test. (However, I also noticed occasionally the directory would complete disappear even after the solution upgrade had completed, or was there but still locked by another process, meaning the files could not be accessed even in Windows Explorer - this is slightly irritating but running the Solution upgrade again always succeeded.)
    • after causing the file to be customized (e.g. modifying or even just checking out with SPD), any subsequent updates to the files via the Feature/Solution did not appear on the site (though further updates in SPD are fine).

    In short, this is all what I expected. Assuming the file has not been customized, anything which updates the copy on the filesystem will cause an update to the site. If it has been customized, updates on the filesystem will not (since the file has now been added to the content database, and the filesystem version is no longer used). If you've not come across this before, Considerations when using Features to deploy SharePoint files - ghosting/unghosting may help.

    So, I'm guessing that if your master pages etc. are not updating when you overwrite the Feature files, it's because the files have become customized somehow. Unfortunately it's not so easy to tell for publishing files - for other files, SharePoint Designer provides a handy blue dot next to the file in it's Explorer view if the file is customized, but alas this doesn't happen for master pages/page layouts. The blue dot can be seen next to the AllItems.aspx file below (click to enlarge):



    Unfortunately this also means reverting to the file on the filesystem is not straightforward either (we can't right-click the file in SPD and select 'Reset to site definition' as we can with other SharePoint files). So this can be a pain if you do want to keep your page layouts referenced from the filesystem (e.g. because performance is critical), but you've ended up in this state. It is possible to revert the files using the API though. I've not needed to do this myself, but the property to check is SPFile.CustomizedPageStatus and if this returns SPCustomizedPageStatus.Customized, then the SPFile.RevertContentStream() method can be used - this should cause SharePoint to henceforth use the version on the filesystem (though note you may lose some updates which had been made after the file was unghosted (customized) - you will need to re-apply these to the filesystem file after the reversion. And remember, don't use SPD for this or you'll be back where you started!)

    So far, so (reasonably) straightforward.

    However, one poster (deelpunt) had an interesting question about updating page layouts with web parts. As far as I can see, updating all page instances to have web parts in web part zones by updating the layouts will not be possible. This is because if web part zones are used, the web part is associated with the page instance rather than the page layout. Indeed, this can be the power of the architecture. It is possible to either:

    • have default web parts added to a zone when a page instance is created from a page layout. This can be done by deploying the page layout using a Feature, and using the AllUsersWebPart tag. This would not affect pages already created however.
    • add web parts to all the pages by adding them directly to the page markup in SPD, rather than in a zone. Of course, this then means the settings for the web part can only be modified by the page designer in SPD, rather than site users.
    • use the API to iterate through all pages in the site to add/modify webparts using SPFile.GetLimitedWebPartManager(). Needless to say, this is the kind of operation which requires a lot of care and planning in production!

    As I've mentioned before, because of these issues the web part zone architecture is often not the best choice for scenarios such as WCM site development, since here we want our changes to apply across all pages which use the layout.

    Hopefully this has been of some use. As always, leave a comment if you've had different experiences to those detailed here, I'd definitely be interested to hear.

    [I also wanted to say sincere apologies to the commenters on the original post (and any others I've been slow in replying to) that it took a couple of weeks for me to come back. Something to do with my project going live and moving house at the same time, hopefully normal service now resumed ;-) ]

    Monday 29 October 2007

    STSADM export, Content Deployment, Content Migration API, Features/Solutions - deployment options compared

    Back in May I wrote a post titled SharePoint deployment options : Features or Content Deployment?, which discussed some thoughts on what was the "right" way to move assets from development to production (and perhaps environments in between) during the site development process in SharePoint. Having now worked on other projects and consciously used different deployment methods on each, I'm rapidly coming to the conclusion that the "right" way to do deployment varies according to circumstances. So I thought what might be useful is an analysis of the whole range of deployment options, with information which might help you decide more easily on how you will complete this crucial step of the process.

    So let's run through the options and their characteristics. Note by the way, that none of the options use 'destructive synchronization', where all content is first deleted before import.

    Using STSADM export/import

    Description:

    Uses STSADM commands to generate a file (export) which can then be transferred to the target for import. One of the simplest ways of moving content from one place to another, although unlikely to be suitable as a continuous deployment mechanism. Examples:

    stsadm.exe -o export -url http://localhost -filename C:\Export.cab -includeusersecurity -versions 4 -overwrite

    stsadm.exe -o import -url http://localhost/sites/newsite -filename C:\Export.cab -includeusersecurity

    Good for:

    • Moving an entire site/web as a one off
    • Quick deployment tests
    • Reparenting webs (can be into a different site collection)

    Considerations:

    • Content on target will be overwritten if already exists
    • Granularity down to web only
    • Object GUIDs are not preserved (so some things will need to be 'fixed up' e.g. anything that references a list by GUID - ListViewWebPart, using lists with InfoPath forms)
    • Not a backup/restore tool - although it's the option which is most like backup/restore, things like alerts, audit trail, recycle bin items, security state, workflow tasks/state are not exported
    • Not transactional

    Using Content Deployment via Central Admin *

    Description:

    Configured via 'Content Deployment paths and jobs' in Central Admin ('/_admin/deployment.aspx'). A path defines the source/target and authentication details, specific jobs define exactly which content should be deployed and how often. Quick deploy functionality allows users with permissions to specify important content which should be deployed more regularly than existing job schedules configured by administrators (quick deploy items are deployed every 15 mins).

    Good for:

    • Moving entire site collections/webs on a scheduled basis e.g. in an authoring/production or authoring/staging/production topology
    • Deploying only incremental changes, e-mail notifications of success/failures
    • Allowing site owners to have some control over content deployment via Quick Deploy
    • Automatically deploying dependencies of content selected for deployment, even if in different site (e.g. page layouts/content types/site columns/referenced images etc.)
    • Automatically transferring the deployment package to the target environment (via HTTP[S])
    • Not transactional

    Considerations:

    • Content on target will be overwritten if already exists
    • Granularity down to web only
    • No differentiation between site content (e.g. pages/images) and site 'infrastructure' (e.g. master pages, page layouts)
    • Object GUIDs are preserved
    • Blank site template should be used for source and destination site collection (see http://support.microsoft.com/kb/923592)
    • Also not a backup/restore tool (see above)

    Using the content migration API *

    Involves writing code which uses the content migration API (known as PRIME) to export then import content - the API is easy to use.

    Good for:

    • Complete flexibility over deployment options
    • Granular control over what gets deployed (down to item level)
    • Ability to preserve object GUIDs (so that list GUIDs do not need to fixed-up)
    • Ability to select options for security, versioning and user roles

    Considerations:

    • Blank site template should be used for source and destination site collection (see http://support.microsoft.com/kb/923592)
    • Not transactional
    • Also not a backup/restore tool (see above)
    • Need development skills to write code

    Using Features/Solutions

    The focus of this blog for several articles. Involves defining XML configuration files which SharePoint uses to add artifacts in the correct way on the target. This can be significantly more complex than simply developing in SharePoint Designer but can allow for better management throughout a solution's lifecycle.

    Good for:

    • Iterative development/deployment
    • Deployment of assemblies and filesystem files (none of the other methods deal with this)
    • Ability to deploy assemblies/filesystem files to all servers in a farm with Solution packages
    • Possibilities for continuous integration

    Considerations:

    • Developer is responsible for evaluating and deploying dependencies (e.g. underlying content types).
    • Updates to content types, list definitions, site columns etc. deployed via a Feature must be done with the API - modifying original Feature files and then reprovisioning is not supported
    • Can be very time-consuming due to lack of assistance from current tools

    * Some additional notes on using Content Deployment or content migration APIs:

    - appropriate Features will automatically be activated on the target, but they must be present (i.e. installed) for content deployment to work (N.B. publishing feature should not be enabled on target for first deployment)

    - using Content Deployment or content migration API with RetainObjectIdentity option should not be combined with STSADM -export/import, since the latter will allocate new IDs!

    So clearly there can be a few aspects to consider in choosing how to go about deployment for your project. In many scenarios where Features/Solutions aren't the most appropriate option, I favor using the content migration API, mainly due to the flexibility which isn't provided in any of the other options. Of course it does mean writing code, but as I mentioned last time, I'll soon share the mini-app I wrote so you don't have to!

    Some useful references:

    Sunday 14 October 2007

    Deployment using STSADM export or content migration API

    Having focused on deployment using Features for several articles, back in May I wrote an article titled SharePoint deployment options : Features or Content Deployment?, which explored some of the decisions around deployment strategies for SharePoint projects. There are a variety of methods which can be used to move SharePoint artifacts and content from one place to another, and I think it's fair to say there's still a certain amount of confusion around deployment for many SharePoint developers. I certainly wouldn't claim to have all the answers, but after delivering another project last week, it seems like a good time to go over some of the experiences and reflect on the different approaches.

    Needless to say, as far as deployment strategies go in general, the best idea is to have one! I see many newsgroup posts from people approaching the end of the development phase asking how they should move their work to the live servers. The problem I find with leaving deployment until the end of the project, is that none of the approaches are completely straightforward (particularly depending on what your solution consists of), and so if your project is to be delivered on time, it's important to know what steps you might need to go through.

    As a sidenote, let's clarify some potentially confusing terminology here:

    • Content Deployment - the "paths and jobs" functionality which can be used to move content, surfaced by screens in Central Admin
    • Content Migration API - the underlying API (sometimes referred to as PRIME) which actually is used for both STSADM export and Content Deployment (in slightly different ways), in addition to the 'Manage Content and Structure' tool and in migrations from CMS2002

    This time round I had decided to use the content migration API to deploy our solution, and it worked well for our circumstances. This is a contrast to developing with Features which I've done in the past, and the main reasons for choosing this approach were: 

    • no need for iterative deployment - although our overall project is phased, for this component we were able to develop the solution and then deploy everything from our development environment. (This approach will not work for subsequent deployments since content our client has generated on the live site would be overwritten on each deployment - more on this in an upcoming post.)
    • ability to retain object GUIDs - this simplified deployment significantly for our project, since if our lists were allocated new GUIDs on deployment (as happens with STSADM export/import), our components which referenced these lists (ListViewWebPart, InfoPath forms etc.) would not hook up properly on the deployment target. This would add a lot of "fix-up" steps to the deployment process if we were to use STSADM export.
    • no direct HTTP access from source Central Admin to target Central Admin - this is a prerequisite to use the Content Deployment functionality (paths and jobs) in Central Admin, but what we needed was a file we could copy to the live server. The content migration API provides this ability and also gives a compression option for large amounts of data.
    • automatic inclusion of database dependencies - as with STSADM export, (but not with Features), SharePoint will analyze and collect all dependencies such as fields, content types, master pages etc. for us.

    The API is fairly simple to use and you may have seen Stefan's series of excellent articles on the subject - these serve as a good companion to the MSDN documentation.

    It's important to remember that any non-database assets (e.g. user controls, assemblies etc.) need to be deployed manually to the target environment - these will not be included by use of something like STSADM export or the content migration API. In our case, since the live environment was a single server (and versioning would be handled by our main source control system), these were deployed by XCOPY since deployment using Solution packages did not offer any compelling advantages here. 

    Whilst we're talking about filesystem files, it's useful to be aware that if you see 404 errors on the target after performing (e.g.) an STSADM import, chances are you've forgotten to deploy something like a user control. The 404 is actually coming from the referenced file rather than the actual page, so don't assume something has gone wrong with the import - a check on 'View all site content' and the import log will probably confirm all the site pages are present!

    Hopefully this has given some food for thought on an approach you may not have considered. I guess my main message here is that whilst STSADM export is extremely simple, it may not provide the complete answer to all your deployment challenges due to changing GUIDs. In upcoming posts I'll provide a more direct comparison of deployment strategies (extending my 'Features or content deployment' post), and also share my mini-app which provides a front-end onto the content migration API.

    [P.S. Sincere apologies to people who left comments whilst I was on holiday which are still not published - I'll publish these and respond over the next few days.

    C.]

    Wednesday 12 September 2007

    Annual holiday

    Just a note to regular readers to say it's time for my annual holiday, so no posts or replies to comments for 2 or 3 weeks. I'm off to San Francisco (which is where Suzanne is from), so it should be a nice break.  I am taking a SharePoint virtual machine, but am under strict instructions the only times I'm allowed to use it are on the plane journeys! Fine by me actually.

    More posts when I get back..

    C.

    Sunday 9 September 2007

    Blending publishing/collaboration functionality in SharePoint

    Most often when creating SharePoint solutions, the requirements often map fairly well to one of the out-of-the-box site definitions which can be used to create new sites. If we're creating heavily-branded internet/intranet sites (WCM sites), we'll probably start with the 'publishing site' template. If we are deploying SharePoint in a document management/collaboration scenario, we'll probably start with the 'team site' template, and so on. Where it gets interesting it when the project requirements effectively have a mix of this functionality. Characteristics of such a site might include:

    • site has completely bespoke look and feel/navigation
    • users will work with files stored in document libraries
    • site templates or definitions are used to create several sites with the same content/functionality
    • custom workflow is used to support a business process (other than standard content publishing), perhaps with InfoPath forms

    Such requirements present a few challenges, and a current project of mine fits into this category. At a high level, one consideration is that site users will also use 'system' pages provided by SharePoint in many scenarios (e.g. working with document libraries/lists, workflow etc.) and this doesn't happen in most WCM sites. This can lead to situations where there is a disparity between the look and feel of the 'published view' of the website and the 'system' areas. I don't intend to provide answers to all the issues here, but I do want to discuss a few as some food for thought. I'll probably revisit this post at the end of the project and provide a better insight into the issues and solutions, but for now let's cover some high-level decisions:

     

    Approach for master page development

    Options for starting development here include:

    • Using a 'minimal master page' from MSDN or Heather Solomon
    • Modifying a copy of default.master (good starting point for customized team sites)
    • Modifying a copy of blueband.master (good starting point for WCM sites)

    Partly this decision depends on where you are heading. Since the aim in my project is for formatting to be controlled by CSS rather than layout tables, starting with a minimal master page makes more sense (the shipped page layouts use tables). This is an interesting area since there's a lot of rework to be done to eliminate tables in a mixed publishing/collab site (and in fact it often won't be possible to eliminate them completely), and for me the benefit is debatable. Certainly all the 'system' pages which site users will be exposed to use layout tables, so I'm not sure how much is gained by only having some pages using CSS for layout.

    Other things to consider here are the usual questions of how to factor responsibility of content items between the master page and page layouts, how to define content types etc., but these are standard decisions in WCM site development so I won't cover them here.

     

    Use of Content Editor web parts vs publishing RichHtmlField controls

    Most folks in WCM development know there is an overlap in functionality provided by the Content Editor web part and the RichHtmlField control in the Microsoft.SharePoint.Publishing.WebControls namespace, i.e. they can both be used to enter page content such as text/images. However it's important to consider the differences - the RichHtmlField control stores it's content in a column of the list item for the page, whereas the CEWP is a web part and thus stores content in the web part storage architecture. This is important, since if deployment to a different environment is in your project plan or ongoing architecture, things will likely be simpler if you use the field control, since this content will then travel with the page properly.

    Additionally, there are some URL fix-up issues with using the CEWP across different environments, as documented in the HawaiianAir.com write up.

    In summary, I'd recommend considering the CEWP as a means of entering content in non-publishing SharePoint sites only. 

     

    Use of collaboration web parts - in layouts or in WebPartZones?

    In a similar vein, since we are mixing the collaboration features into our site we are likely to need to use certain web parts which we wouldn't in a straight WCM site. In our situation the ListViewWebPart is fairly key to some areas, and is used as a means of allowing users to work with different lists from one page. The first decision here is whether the page layouts should include web parts directly (by adding them in SharePoint Designer), or just web part zones to which the individual parts would be added later through the browser. In most WCM scenarios I prefer to add web parts directly to page layouts since they will not be customized/personalized by end users (the main usage scenario for web part zones), and when web part zones are used, again the web part config is not stored in the page which can make deployment more complex. Using the other approach of adding directly from SPD, config is stored in the actual HTML markup of the page and so travels with the page layout itself.

    However! The ListViewWebPart has some quirks which means it isn't always possible to use directly from the page layout. Specifically, it is only possible to configure the part to consume a list from the current web, and in the case of a publishing page layout, this means the root web since this is where the master page gallery is stored. Since our lists are stored in a child web, this is problematic - the other solution of using a DataView also had issues. Additionally, the ListViewWebPart configuration stores values specific to it's location, meaning the config XML is not very portable (i.e. export web part definition, modify, use). I'd like to think it would be possible with time to work out exactly which IDs do need to be changed, but alas we don't have time on this project.

    As a result, using the ListViewWebPart in a web part zone is actually the best solution in these circumstances as far as I can see. We'll have an extra few steps at deployment, but this will take less time than the alternatives it appears.

     

    Look and feel of system pages

    As mentioned earlier, for a mixed WCM/collaboration site there can be a disparity of the look and feel of the main pages of the site and the 'system' pages users will see, i.e. pages from the '_layouts' directory. Note this happens even if both the site and system master page is set to point at your custom master page, since these pages are set to use 'application.master' (also on the filesystem in '_layouts') which neither of these properties affect. Sure it would be possible to simply replace 'application.master' with your own version, but that's not an elegant solution and would probably be unsupported. Unfortunately it seems that the architecture doesn't provide an easy way to change the master page used by '_layouts' pages - you have to go a level deeper to explore ways of doing this. Many .Net 2.0 developers will know it's possible to switch a master page dynamically in .Net, and to be fair this is what SharePoint does with the maser pages stored in the master page gallery anyway. I'm not aware of a truly elegant solution to this problem, but this discussion on Serge van den Oever's blog presents a viable approach using this technique. 

     

    So those are some of the issues to consider. There are certainly others, including navigation, CSS customization of standard styles (to ensure collaboration web parts integrate well with your look and feel), and possibly the choice of authentication mechanism. I'll cover these and any others which arise in an upcoming post.

    Monday 3 September 2007

    VSeWSS 1.1. CTP - a look at the nuts and bolts

    Regular readers of this blog will know that I've been a reasonably keen advocate of Microsoft's Visual Studio Extensions for Windows SharePoint Services (VSeWSS) for certain SharePoint development tasks. If you read more than a couple of SharePoint blogs, you won't have avoided the news that MS have just released version 1.1 of this tool, as announced here by Alex Malek over on the SharePoint Designer blog. At the time of writing, this is a CTP (Community Technology Preview) meaning it is pre-beta, so bugs can be expected. So today I wanted to run through the changes, so folks who aren't familiar with the tool or haven't had a chance to take a look themselves can quickly get a sense of what's in there.

    In essence, VSeWSS helps by simplifying the process of developing Features for SharePoint - this approach is generally regarded as the way to do SharePoint development in such a way that assets can be more easily deployed to other environments. In previous articles, I detailed how to create and deploy lists and how to create and deploy web parts with VSeWSS. For me, these are probably the scenarios where VSeWSS comes in the most useful, though there definitely are others depending on how you work. However, the most common gripe of developers who used the tool was that since VSeWSS 1.0 regenerated Feature files with each change, it wasn't possible to manually amend the files. This was often necessary to add things not directly supported by the tool, such as Feature receivers.

    So let's run through the different areas where the tool has been improved.


    WSP View

    The big change with this release is that it is now possible to amend Feature files in the development process. Instead of hiding the generation of these files behind the scenes, the tool now makes these bona fide VS project items which can be edited before the Solution package is built. Certainly auto-generation of the final files still happens (that's the point) and there are some files lurking which are needed to support the tool, but VSeWSS now does a good job in presenting to you what you can modify through the WSP View (View > Other windows > WSP View). This is shown below for a project with some different artifacts:



    Some nice things which can be done here are that entire Features can be deleted with a single click (all files will be removed), and the Feature activation order can be changed. Toolbar buttons are provided which modify the sequence of FeatureManifest elements in the manifest.xml file.


    Feature file editing

    So the WSP View provides the mask onto the editable files, but I wanted to drill into why this is useful. Some examples would be:

    • ability to add Feature receivers to a particular Feature
    • ability to rename properties of the Solution package, e.g. to bring VSeWSS-generated Solutions into line with a naming convention
    • ability to refactor Feature elements into a single Feature. This can be useful because by default the tool will create a new Feature each time you use Project > Add new item > Some SharePoint item (e.g. Content type). Often you will want several Feature elements to comprise a single Feature rather than split over several Features.

    Event receivers

    VSeWSS 1.1 also provides some enhancements around event receivers (handlers for events raised by lists). Version 1.0 also provided some support in this area, but the main scenario was adding a list/item receiver at the time the list was being created (i.e. "create list with receiver"). Version 1.1 now makes it easy to add an event receiver to an existing list, which simplifies those scenarios.

    My favorite improvement in this area however, has to go to event receivers on content types. This effectively means that the event-handler code travels with the content type - so your code will run on all lists the content type is associated with. This is interesting as I had no idea this was possible in the WSS 3.0 platform! So I did some digging. I haven't yet done any testing of the results, but what VSeWSS does to support this is add some custom attributes to a standard list event receiver. For those interested, these are defined in the SPDevTools namespace in a file which is added to your project (out of the way in the Properties folder, alongside AssemblyInfo.cs) by the tool. I've not yet worked out exactly what picks up these flags in the Feature activation process, but it's clear that standard list event receivers are actually being used as the generated class derives from SPListEventReceiver. The image below (click to enlarge) highlights the new attribute being applied which supports all this:




    Web parts

    This was where I thought VSeWSS was a winner, and it's good to see the support for web part deployment has been extended further still. With 1.1, a default web part definition file (.webpart) is now generated for you to edit before deployment to add custom property settings. This is useful, since it means that developers can avoid the "deploy web part, add to page, configure, export web part" process which is otherwise required to obtain a configured definition.


    Performance

    One of the first things VSeWSS 1.0 users will notice is that a full IISReset is no longer performed on each deployment. This was something of a pain with version 1.0, since it meant the "edit, deploy, get feedback" cycle took longer than was necessary. So having been used to the IISResets, personally I was pretty pleased to see the message below in the Visual Studio status bar during the first deployment!



     
    What could be better
     

    So those are the good bits, and it's a great step in the right direction. However I'd still like to see the following:

    • fully-featured Solution Generator. I didn't have time to look at this in detail, but the download page specifies that certain items still aren't covered. This ties in with what I remember Alex Malek saying at this year's Tech Ed, that this still wouldn't be "full fidelity".
    • ability to easily add a Feature receiver to a Feature I'm working with. I just want right-click > Add Receiver - this should generate the class and add the attributes to the Feature definition with default values, or perhaps infer the generated type.
    • ability to easily refactor Feature elements in Features, since I often don't want the default of a Feature per element
    • no GUIDs in Feature names (though apparently this will be sorted by final release)
    • ability to deploy a _layouts file (again, this should be there in final release)

    On a "bigger picture" note, I'm reminded of a common view in the SharePoint community which made complete sense when I heard it first from Ted Pattison. Unlike .Net, where Microsoft has gone to great lengths to ensure the tools are in sync with the platform (same team [Scott Guthrie], same timeframe for development phase, same ship date), a different thing is happening with SharePoint. Effectively the tools are 18 months behind the platform, so SharePoint development can be pretty painful at the moment -  however, this shouldn't be taken as a reflection of the platform.

    This release of VSeWSS should help though, and it'll be interesting to see what comes in the future.

    The download link is http://www.microsoft.com/downloads/details.aspx?FamilyID=3e1dcccd-1cca-433a-bb4d-97b96bf7ab63&displaylang=en.

    Monday 27 August 2007

    Adding custom help pages to SharePoint is complex!

    Something I've been curious about for a while now is how to extend the SharePoint help system. A while back I wrote about how to modify 'system' pages in SharePoint by effectively adding new pages - the examples I used were:

    • a custom Recycle Bin page which displays only items deleted by the current user
    • a custom Central Admin page which has a message specific to my fictional organization's administrators

    When implementing customizations like this, I thought it would be useful to be able to add custom help to accompany the new functionality. So today I set about digging around the SharePoint help system to see how to do this. Unfortunately my answer so far is that it's pretty difficult and I haven't figured out all the pieces! However, I thought I'd detail what I found in the hope that either it's still useful to somebody, or that someone who knows can perhaps leave a comment or link and complete the jigsaw.

    So to be clear, I'm talking about how to add custom application help pages here - nothing to do with the 2 .chm files which are the WSS and MOSS SDK references. In site or central admin pages, the application help pages are linked to from help icon on the top bar:

    As you'd expect, this icon (and the link behind it) is provided by the master page for the page. Clicking the link calls a JavaScript function called TopHelpButtonClick() in core.js to open the help window - on most pages a parameter of 'NavBarHelpHome' is passed, though notably pages which link to a page other than the default help page override this value. Since all pages in say, Central Admin share the same master page (and the JS call is in the master page, not the actual page) the code in core.js checks to see if the page itself has specified an override. Individual pages can therefore override the help location specified in the master page using a script block such as:

    <script type="text/javascript" language="JavaScript">

           var navBarHelpOverrideKey = "OSSCentralAdmin";

    </script>


    Core.js will then build a link with this override parameter in rather than 'NavBarHelpHome', meaning that pages can easily link to a custom page rather than the default. In order to link to a custom help page, your page will need to override this value.

    The value used here links to a value in a set of mapping files stored in C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\XML\HELP. In the case of the value shown above, we find that one of the mapping files, 'OssSearchAdmin_HelpKeymap.xml', contains the following:

     

    <helpmap>

        <key>OSSCentralAdmin</key>

        <collectionId>MS.SEARCH.ADMIN.manifest</collectionId>

        <contextId>MS.SEARCH.ADMIN.OSSCentralAdmin</contextId>

    </helpmap>


    The set of mapping files in this directory all contain similar entries, i.e. a corresponding entry for each page which specifies an override to the default help page. Since these files don't appear to follow any naming convention, I'd venture that any XML file with the correct schema can be dropped in here and the help system will pick it up. When it comes to finding what these references point to, things get interesting! An initial search across the '12' directory using Visual Studio 'find in files' yields no results, but as with most of these things it's worth digging further. In the '\12\HCCab\1033\' directory are a set of .cab files which store the help files used in the SharePoint help system. In the example above, the 'MS.Search.Admin.HC.cab' file is the file which is referenced. Looking inside, we see a number of files, one of which is named 'MS.SEARCH.ADMIN.manifest.xml', which you'll notice is the value for the <collectionId> in the mapping above. The contents of one such .cab file look like:



    So a quick recap of so far - we've found how to override the initial help page which is displayed, and how the key specified links to a set of help files packaged as a cab file in the 'HCCab\<localeId>' directory.

    The manifest file is obviously key to how the index of the files in the .cab are linked. Incidentally, for those familiar with building SharePoint solution packages, the schema used here is completely unrelated to the 'manifest.xml' file used there. Looking at the contents of one of these manifest files, the first thing that strikes me is it looks like a system-generated file - for one thing there are many parent/child and link relationships which would be complex to document by hand. An extract looks like:

    <?xml version="1.0"?>

    <helpCollection>

      <name>SearchCentralAdmin</name>

      <id>MS.SEARCH.ADMIN.manifest</id>

      <changedDate>2006-10-13 21:53:57Z</changedDate>

      <createdDate>2006-10-13 21:53:57Z</createdDate>

      <author>Microsoft</author>

      <version>11.0.9413.2</version>

      <lcid>1033</lcid>

      <defaultHelpItem>MS.SEARCH.ADMIN.HA10175815</defaultHelpItem>

      <brandingImage />

      <rootCategory>MS.SEARCH.ADMIN.CH10176169</rootCategory>

      <feedback show="False" />

      <helpItems>

        <helpItem>

          <id>MS.SEARCH.ADMIN.HA10047848</id>

          <parents>

            <parent sortOrder="4" primary="true">MS.SEARCH.ADMIN.CH10176336</parent>

            <parent sortOrder="4" primary="true">MS.SEARCH.ADMIN.CH10176336</parent>

          </parents>

          <relatedItemsPointingToMe>

            <item sortOrder="1">MS.SEARCH.ADMIN.HA10047848</item>

            <item sortOrder="1">MS.SEARCH.ADMIN.ManageSearchService</item>

            <item sortOrder="1">MS.SEARCH.ADMIN.SearchServerSettings</item>

          </relatedItemsPointingToMe>

        </helpItem>

        <helpItem>

          <id>MS.SEARCH.ADMIN.HA10047852</id>

          <parents>

            <parent sortOrder="6" primary="true">MS.SEARCH.ADMIN.CH10176338</parent>

          </parents>

          <relatedItemsPointingToMe>

            <item sortOrder="1">MS.SEARCH.ADMIN.LogSummary</item>

            <item sortOrder="1">MS.SEARCH.ADMIN.LogViewer</item>

          </relatedItemsPointingToMe>

        </helpItem>


    However, one thing which does check out is that the file referenced in the <defaultHelpItem> is indeed the page which is loaded initially when the help window opens. So that's something!

     

    I can't help thinking though, that a help file generator has been used and it would probably be necessary to use the same approach to add custom help pages. When I started delving I mainly expected to find some .chm files generated by nDoc or Sandcastle somewhere, but it does seem like something I'm not familar with has been used. Robohelp perhaps?

     

    If anybody can shed any light on this I'd be interested to hear. In the meantime, I note that others have found alternative ways around the problem, by passing a custom parameter and then modifying core.js to intercept this and open up a completely custom help window, rather than plugging into the existing help system as such. Ragav Jagannathan's post on his approach can be found here - http://ragavj.blogspot.com/2007/04/custom-help-window-can-be-opened-by.html. As Ragav rightly points out, customizing the core.js file is unsupported so you should probably think carefully before going down this route.

    [Update - Nick Swan MSN'd me to point out that there is a document library in the Central Admin website which contains help files. Interestingly, it's the same set of files stored in the HCCab folder on the filesystem! It's difficult to tell from the IIS logs which set of files are actually pulled in, as they seem to be dynamically loaded through the '/_layouts/helpContent.aspx' and '/_layouts/help.aspx' pages. Interesting!]