Thursday, December 20, 2007

A Tool to Help with CAS Policies

When adding Code Access Security policies to a manifest file in a SharePoint feature, determining which permissions to apply can be a hit and miss affair. Add some permissions, activate the feature and read the SecurityException to get an idea of what else is needed.

But help is already on your development machine, in the guise of PERMCALC (official known as the "Minimum Grant Set Determination tool"), a visual studio command line tool that is run from the Visual Studio Command window.

This tool is run against one or more assemblies, and generates an XML file listing the "estimated" permissions that must be granted to access that assembly. It attempts to trace all code paths through the named assembly, and through the libraries called by the assembly. So even if it doesn't give a comprehensive view, it can be a useful check before you start debugging those CAS issues.

An overview of the tool is available on the Microsoft site..

Tuesday, December 11, 2007

SPSiteDataQuery Resources

Useful posts and articles:

SPGridView Requests FileIOPermission When Added to a Web Part

I have been struggling with the SPGridView causing a security exception in a custom web part. Exploring the code with reflector reveals that when the SPGridView loads it tries to register a JavaScript file from the Templates\layouts folder in the 12 hive, and this process involves a call to the MakeBrowserCacheSafeLayoutsUrl method. That method attempts to create a unique file name for the JavaScript file. This requires that the JavaScript file is opened and read, therefore needing FileIOPermissions. If the web part is not explicitly being granted FileIOPermission in CAS, then the rendering fails.

I added the following to the manifest file that configures the CAS settings for my custom web part:

<ipermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" read="C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12;$AppDir$" write="$AppDir$" append="$AppDir$" pathdiscovery="$AppDir$">

Must admit to not being happy with hard-coding the path, but it got the web part working!

If you are wondering about the $AppDir$ parameter, I quote "it refers to the initial folder the application points to, and any subfolders". Not sure what these are for SharePoint - I tried using just $AppDir$ for the Read attribute but that did not supply the necessary access in this case (hence the hard-coded path).

Thursday, December 6, 2007

Displaying Google Search Results in the MOSS Search Center

I thought of a couple of possibilities to meet this requirement, but the only approach I could get to work satisfactorily in a short space of time was to embed a call to the Google AJAX Search API inside a content editor web part.

To achieve this, first you need a Google Search API Key which you can get from a sign up form on the Google Code site. The process creates a key that will work against a specific server URL; surprisingly, the correct key actually permits the search to work from an intranet site, not just from public-facing sites. The page displaying your key also includes some starter code to show how to use that key - nice work, Google!

I modified this code somewhat to restrict search results to New Zealand sites only by applying the following restriction to each Searcher object:

searcher.setSiteRestriction("co.nz");

Had hoped for a more generic way of restricting the search to a country, but that's all I have found so far.

Then the JavaScript code, including references to the search css file "gsearch.css" and to the API launcher, was pasted into a Content Editor control on the search results page in the search center. One addition was a querystring parsing method in JavaScript to read the search term from the "k" querystring parameter in the URL for the search results page, and to use that text in the SearchControl execute call.

Certainly not as flexible or simple a process as that explained by Arpan Shah in his blog post about rendering Microsoft Live search results in SharePoint, but a good starting point to fulfill the client's requirements.

Tuesday, December 4, 2007

Debugging SharePoint Timer Jobs

I am sure it has been written about elsewhere, but here is the way in which I have been debugging timer jobs.

Add the PDB File to the GAC
The PDB file needs to be in the GAC for debugging in Visual Studio. You can add this file through a feature manifest file, but you are unlikely to want to deploy the PDB to the GAC on your production server, so a better way on the dev server is to directly place files in the GAC. To do this, map a drive in windows explorer to

\\[your server name]\c$\windows\assembly

This bypasses the windows explorer shell special handling for this folder, and allows you to copy and paste files as normal without using GACUTIL.

In the GAC_MSIL subfolder, find the subfolder corresponding to the name of your assembly. Below there will be one or more version subfolders. Find the latests version subfolder., and copy your timer job dll and pdb file (built in debug mode!) to this folder.

If this copy action is denied, open the Services administrative tool, and STOP the Windows SharePoint Services Timer service. Apply an IISRESET from the command line, and then attempt to copy the files again - resetting those two services should remove the lock on the dll. After copying the files, make sure to restart the SharePoint Timer service!

I did have one occasion where the Timer Service "hung" whilst attempting to restart. I found that ending OWSTIMER in the Windows Task Manager cleared this hiccup.

Debugging In Visual Studio
Set a breakpoint in your timer job code, and then open the "Attach to Process" dialog from the Debug menu. Check the box at the bottom of the dialog titled "Show Processes from All User", and select OWSTIMER.EXE from the list of available processes. Click the Attach button.... and hopefully your breakpoint should display as a nice fat filled dot!

An outlined breakpoint (an empty circle) rather than a filled breakpoint means VS cannot match your code against the running code, and so something in the above process has not worked for you. Worked for me, though! Perhaps you have copied your dll and PDB files to the wrong GAC subfolder?

Triggering the Job
Now you just need to trigger your timer job. One suggestion for this is to modify the schedule of the job to occur frequently - have a look at this post on blah!bLaH!BLOG!! for how to do that.

I have a design pattern in place where the schedule for custom timer jobs are configured in a configuration list in the WSS site. When the feature containing the timer job is activated, a feature receiver reads the configuration data from the list and sets the timer job accordingly. Works nicely when you want to manipulate schedules and other data relating to the timer job.

One Last Timer Job Tip...
If you need to persist data across executions of your timer job, here's how from James Mann.

Wednesday, November 28, 2007

Filtering a SharePoint View from the QueryString

Clever little tip from Aggarwal Saurabh - you can filter the contents of a SharePoint list view by appending a couple of querystring values to the address.

For example, if you have a list view including a field named "ProductID", you can filter a preset list view to only show items for a Products with ID "123" by adding the following querystring to the page URL:

?FilterField1=ProductID&FilterValue1=123

Could be handy!

Tuesday, November 6, 2007

Why does my modal dialog box open another browser on submit?

Currently I am creating an application where a modal dialog box opens when the NewForm.aspx page for a WSS list is opened, to search against an external data source and pass the results back to the form (I'll let you know if this proves to be a viable design pattern!).

The default behaviour of the modal dialog has been driving me a little crazy - when the form in the ASP.Net page in the modal dialog box is submitted by clicking on a button in that page, that same form was opening in a new browser window. The dialog was also remaining open.

Finally came across the solution tucked away in a forum answer by Ken Dopierala Jr. His tip:

Remember, when you post back to a Modal page you must put: <base target="_self"> in the <head> section of the HTML on that page.

And that is all it needed to take the nastiness away, just adding that simple tag into the PlaceHolderAdditionalPageHead placeholder of the WSS page being presented in the dialog. Thanks, Ken!

Saturday, October 27, 2007

Creating a new form in a list by copying an existing form (in code)

To copy an existing form in a WSS list, and to add a new content editor web part to that list, use the SPFile class (not the SPForm collection of the list):

//Copy the NewForm.aspx to NewForm_new.aspx
string formPath = "Lists/ClientTest/NewForm.aspx";
string newformPath = formPath.Replace(".aspx", "_new.aspx");
SPFile form = web.GetFile(formPath);
form.CopyTo(newformPath, false);

//Get a reference to the new form, and create a new content editor web part containing onload JavaScript
SPFile copiedForm = web.GetFile(newformPath);
SPLimitedWebPartManager wpManager = copiedForm.GetLimitedWebPartManager(PersonalizationScope.Shared);

//Create the new web part
ContentEditorWebPart wpContent = new ContentEditorWebPart();
XmlDocument xmlContent = new XmlDocument();
XmlElement el = xmlContent.CreateElement("El");
el.InnerText = "";
wpContent.Content = el;
wpManager.AddWebPart(wpContent, "Main", 0);

The JavaScript adds an onload handler to the page, allowing for behaviours to modify the content of the standard list form for example.

Thursday, October 18, 2007

Error in Custom Document Library View

When creating custom document library definitions using the view files output by the SharePoint Solution Generator, you may see the following error on the custom view pages in an instance of the libary:

An error occurred during the processing of ....... Only Content controls are allowed in a content page that contains Content controls.

This is caused by invalid text in the ASPX file - the solution generator adds a comment XML node to the top of each view file, and this needs to be deleted before deploying that view.

Checkin Page Shows Error For Document Library

Have been very busy creating lots of solutions to define a raft of lists and document libraries. One technique I have experimented with is as follows:
  • Manually define the site containing the lists
  • Use the SharePoint Solution Generator to create schemas for the lists
  • Run my own tool across these schemas to generate site column and content type definitions. The tool also removes some of the invlaid attributes in the schema field definitions that are created by the solution generator (I'll publish the tool here sometime soon)
  • Create solutions and features in Visual Studio using these XML definitions.
This has been saving me lots of manual effort in creating all the necessary XML. My reason for not using the VSeWSS projects for list definitions is I prefer control over the feature and manifest files, so that I can add other elements where necessary.

I came across an issue with a document library created using one of the custom list definitions. Everything seemd to work in the document library except for checking in a document - the checkin.aspx page simply displayed an error stating

"Value does not fall within the expected range"

Don't ya love that one!! Lots of investigation uncovered the cause - a malformed content type. The document library used one custom content type, and one of the field elements in the field section of the document library schema.xml file had a mispelt name attribute. Amazing that I could still add a document, and could edit the metadata values!

Thursday, August 30, 2007

Visio Stencil of SharePoint Design Shapes

When creating site and application designs for SharePoint, I have wanted to illustrate the elements that comprise the solution's architecture.

Diagrams at this level are very valuable for explaining the proposed design to a client, and also for summarising the elements involved ("a picture is worth....").

So I have created a Visio stencil containing a few useful shapes.

See an example of the shapes, and download the stencil, from here

Wednesday, August 22, 2007

Debugging SharePoint Custom Code

Great article about debugging SharePoint applications. It also suggests designing code to facilitate debugging, which seems a very sensible idea to me (particularly when combined with the idea of designing to "fail fast", thereby ensuring that exceptions are not hidden by the code)

One MOSS site I developed recently includes several event handlers and timer jobs. Each of these includes a common class to write error messages to a custom list in the site when exceptions occur. Having a central location within the site to monitor error message has proven effective - one advantage is that I can set up alerts in case of exceptions.

Using the facilities native to SharePoint (liist, alerts, etc) simplifies development and gives huge flexibility in using the resulting data.

Wednesday, August 8, 2007

Email and SharePoint are not Competitors

A discussion following on from a presentation I recently attended (on the use of SharePoint in business) raised the opinion that email is a competitor to SharePoint in terms of business use. The basis of the argument was that people in an organisation either can use SharePoint for their collaboration or they can use email.

I disagree. SharePoint is now very much email-enabled, with the ability to send alerts or emails from custom code, and to receive emails into lists. The ideas in the discussion may have been based on the belief that users are required to interact with the data contained in a SharePoint site only through the site's web pages.

Certainly the users will need to perform some actions through web pages, but it is possible without much work at all to implement a business process in SharePoint in such a way that the users can continue to use emails for many of the operations they perform. An email sent to a SharePoint list can be interpreted by event handlers on the list, which could act on information in the email and add or edit data in the list.

What I have found is that architecting solutions in SharePoint requires a different vision than when developing in ASP.Net. One of the key points is to build on SharePoint's strengths - think about using lists for storing data (for example, store temporary data for an application in a list rather than in a database table).

Strange Results When Adding Web.Config Values

SharePoint provides a programmatic way of editing existing values and adding new values to a web application's web.config file - through the use of the SPWebConfigModification class (defined in the Microsoft.SharePoint.Adminstration namespace).

There are plenty of posts around explaining how to use this class, the basic pattern for adding a custom value being the following:

        private void AddWebConfigEntry(
string keyName, string entryValue)
        {
            SPWebConfigModification modification 
= new SPWebConfigModification
                 (string.Format("add[@key=\"{0}\"]", keyName)
                 , 
"configuration/appSettings");
            
modification.Owner Constants.FEATURE_NAME;
            
modification.Sequence 0;
            
modification.Type SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;
            
modification.Value entryValue;
            
_webApp.WebConfigModifications.Add(modification);
            
_webApp.Update();
        
}

Wen I first wrote and used this function, I found that the key was correctly added to the web.config file, but was not being removed by a similar deletion function I wrote. And everytime I called this AddWebConfigEntry function, a duplicate entry was written to the file.

Turned out that I had missed the escaped double quotes in the first argument of the SPWebConfigModification constructor call. What made this a tricky effect to fault-find was the fact that the new web.config entry was being created.

So the morale of this tale is - be VERY careful with the arguments to that constructor!

Tuesday, July 17, 2007

Internet Explorer Default XSL

To view the default XSL used by IE, browse to res://msxml.dll/DEFAULTSS.xsl in Interner Explorer. This works in versions of IE prior to IE9 - I have not found an equivalent for IE9

Monday, July 9, 2007

MOSS Install - Tips from an MS Field Engineer

Tips from a Microsoft premier field engineer on how to achieve a "... less painful experience ..." when faced with a MOSS install - http://sharepoint.microsoft.com/blogs/fromthefield/Lists/Posts/Post.aspx?ID=9

(and here's another useful post on configuring Alternate Access Mappings)

Sunday, July 8, 2007

Calling a Custom Javascript Function on Page Load

A simple way to add a custom Javascript function to the list of scripts that run at page load is as follows:
<script type="text/javascript">
_spBodyOnLoadFunctionNames.push("YourFunctionName");
</script>

Thursday, July 5, 2007

Displaying Site Data in a SharePoint Page

To display the name of the current site in a master page or page layout within SharePoint, add the following control to the source of the page:

<SharePointWebControls:ProjectProperty Property="Title" runat="server"/>

This display the title of the site. The ProjectProperty SharePoint Web Control is useful for displaying properties of the current web site. Other fields such as the site description can also be displayed this way

Note that Microsoft must have used the name "project" at some stage for a SharePoint site, given the name of this control and also the name of the site Title and Description settings page (which is prjseng.aspx)

Adding a CSS File Link to a MasterPage

Use the following to add a reference to a stylesheet in a WCM publishing site's Style Library document library:

    <SharePointWebControls:CssRegistration ID="CssRegistration1" 
      name
="<% $SPUrl:~sitecollection/Style Library/style.css %>"
       runat="server"/>

Note that some of the default styles may still override those in the referenced stylesheet, so you may need to add the CSS as the Alternative CSS URL on the "Site Master Page Settings" form

Wednesday, July 4, 2007

Field Controls in a Layout Page not Displayed in Edit Mode

I was creating a new page layout associated with a content type that I had just modified (removed some fields and added others). SharePoint Designer showed the edit controls ocrrectly in the layout page.

But when I went to create a new page in the site using this page layout, only some of the field edit controls were displayed on the new page. No errors were displayed on the page, it was just failing to display some of the controls.

Tracked this is to the content types associated with the pages document library. Document libraries keep local copies of content types, so the pages library was storing the old set of fields for the content type I had changed. An important proviso here is that the custom content type that caused the problems is being modified through a feature rather than manually in the site settings pages. Perhaps if I had modified the content type directly rather than through a feature then the changes would have been propagated to the local copy of the content type in the document library?

Tuesday, July 3, 2007

Removing User Permissions From a List Item

Programmatically modifying the item-level permissions in a list involves manipulation of the Role Assignments collection for that item.

This example shows how to remove a specific role definition from each of the members of a user collection:
   /// <summary>
        /// Remove a role definition from each of the members of a user collection for a list item
        /// </summary>
        /// <param name="item">The List Item</param>
        /// <param name="userVals">The collection of users who are to have the role definition removed</param>
        /// <param name="def">The role definition to remove</param>
        
internal static void RemoveRoleDefinitionFromUsers(SPListItem item, SPFieldUserValueCollection userVals, SPRoleDefinition def)
        {
            
if (userVals != null)
            {
                
foreach (SPFieldUserValue userVal in userVals)
                {
                    SPUser user 
userVal.User;
                    
SPRoleAssignment role item.RoleAssignments.GetAssignmentByPrincipal((SPPrincipal)user);
                    if 
(role != null)
                    {
                        
if (role.RoleDefinitionBindings.Contains(def))
                        {
                            role.RoleDefinitionBindings.Remove(def)
;
                            
role.Update();
                            
item.SystemUpdate(false);
                        
}
                    }
                }
            }
        }

Thursday, June 28, 2007

Dependencies in Custom SharePoint Permissions

An event handler I have written applies item-level permissions to modified list items - specific users are granted custom permissions.

This was working fine until I enabled versioning on the list manipulated by the handler. After making that change I noticed that the specific users were now seeing the access denied page in SharePoint when attempting to view items with the managed permissions.

The code was assigning SPBasePermissions.EditListItems and SPBasePermissions.ViewListItems rights for the users. After experimenting in the Edit Permissions Level administrative page in the site settings, I noticed that checking certain boxes caused other boxes to be checked - there are clearly some dependencies behind the scenes that should be applied when assigning custom permissions.

The outcome of the experimenting was that with versioning enabled on the list, the view versions permissions was required. Edit rights on an item will be granted to a user by applying the following set of SPBasePermissions to the role definition:

SPBasePermissions.EditListItems SPBasePermissions.ViewListItems SPBasePermissions.OpenItems SPBasePermissions.ViewVersions SPBasePermissions.ViewPages SPBasePermissions.Open

Viewing rights are granted with the same set, minus the EditListItems member.

Wednesday, June 27, 2007

Tuesday, June 26, 2007

How to Display the "New" icon against a List Item

To show the standard SharePoint New standard icon SharePoint icon against new list items in a data view web part (or other XSLT web parts), use the following snippet:

<xsl:if test="ddwrt:IfNew(string(@Created))">
    <img src="/_layouts/1033/images/new.gif" alt="New" />
</
xsl:if>

Comparing Dates in SharePoint XSL

Here's a way to peform a date comparison in the XSLT definition of a data view web part:

<xsl:if test="number(translate(substring-before(ddwrt:FormatDate(@Date_x0020_Raised ,1053 ,5), ' '), '-', ''))+2 < number(translate(substring-before(ddwrt:TodayIso(), 'T'), '-', ''))">
        
<img src="_layouts/images/ewr210s.gif" />
</
xsl:if>


This compares the date in the "Date Raised" field with the current date, and if the "Date Raised" is more than 2 days ago then an image is displayed.

Monday, June 25, 2007

Handling Multivalue and Multiselect Field Values in SharePoint

Having written my own regular expression to parse the values from a multiselect lookup field, I then found a post from Mark Arend that offers regular expressions for all the various "decorated" field types in SharePoint (choices, lookup, Person or Group and Hyperlink fields). Very handy!

Thursday, June 14, 2007

Building an Accessible Internet Site with WCM: Setting Up the Solution

Latest project is to create an Internet site using MOSS that complies with accessibility web standards.

First step was a LOT of research. I found plenty of useful articles by Heather Solomon, Zac Smith, Cameron Moll and others, plus dashings of negative comments about quite how non-standard is the HTML pumped out by SharePoint. Sounds like a fair bit of work ahead!

During my travels around the web, I came across a nice idea from Phil Wicklund on managing SharePoint development across a team. The great thing about starting a new project is that it gives the opportunity to apply best practices, so I am combining Phil's approach of reproducing the 12 hive folder structure, but will be deploying via a feature rather than via Xcopy. The downside of this is that deployment during development is slower, but I prefer to always build the WSP file as this sorts out any deployment issues very early in the development cycle. Having a package deployable from the command-line is closer to allowing some form of continous integration, too.

Tuesday, June 12, 2007

MOSS Internet Sites

I was preparing a list of MOSS public-facing web sites, but no point - 'cause here's a comprehensive list by Na-Young Kwon

Tuesday, May 29, 2007

Using Parameters in the SelectCommand of a Data View Web Part

The SelectCommand attribute of the SPDataSource element within a SharePoint DataView web part can use parameters supplied to the web part - and these parameters can come from a varity of sources, including the querystring in the page request.

This opens the way to easily control the data displayed in the data view; for example, via an ID supplied in the querystring.

The following code snippet shows some of the DataFormWebPart elements that use a value in the querystring to select a single list item to be displayed (the parameter is named SelectedRisk). Notice how the parameter is referenced in the SelectCommand:

<DataSources>

    
<SharePoint:SPDataSource runat="server" SelectCommand="<View><Query><Where><Eq><FieldRef Name="ID"/><Value Type="Counter">{SelectedRisk}</Value></Eq></Where></Query></View>" ...>

        
<SelectParameters>

            
<WebPartPages:DataFormParameter PropertyName="ParameterValues" ParameterKey="SelectedRisk" DefaultValue="0" Name="SelectedRisk"></WebPartPages:DataFormParameter>

        
</SelectParameters>

    
</SharePoint:SPDataSource>

</DataSources>

<ParameterBindings>

    
<ParameterBinding Name="SelectedRisk" Location="QueryString(ID)" DefaultValue="0"/>

</
ParameterBindings>

Querying in CAML Relative to Today's Date

Found little information when searching for ways to perform date queries using CAML relative to today's date - only one reference to the use of OffsetDays from the article Customise the Content Query Web Part . Surprising the lack of information on this technique.

Here's the example from that article:

<Where>
  
<Gt>
      <FieldRef Name="Created" Nullable="True" Type="DateTime"/>
      <
Value Type="DateTime"><Today OffsetDays="-7"/></Value>
  
</Gt>
</Where>

Simple script to Remove and Redeploy a Feature

This script deactivates and deletes an existing feature, then redeploys this feature - it is useful when modifying features during development:


REM Add the 12 Hive bin folder to the path for access to STSADM
@set PATH=C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN;%PATH%

REM Configure local values
set siteURL=[site URL here]
set featureName=[Name of the feature]
set WSP=[Name of the WSP file, including the WSP extension]

REM Go to the folder containing the WSP file
cd [Full path to the folder holding the WSP file]

REM Remove the solution
stsadm -o deactivatefeature -name %featureName% -url %siteURL% -force
stsadm -o retractsolution -name %WSP% -immediate
stsadm -o execadmsvcjobs
stsadm -o deletesolution -name %WSP% -override
stsadm -o execadmsvcjobs

REM Add the solution
stsadm -o addsolution -filename %WSP%
stsadm -o execadmsvcjobs
stsadm -o deploysolution -name %WSP% -immediate -allowgacdeployment
stsadm -o execadmsvcjobs
stsadm -o activatefeature -name %featureName% -url %siteURL% -force

Sunday, May 20, 2007

Changing the URL of a SharePoint Site Collection

Noticed that a site collection had a poor URL - to change the URL, backup the site and then restore using stsadm command-line operations:

To backUp:
stsadm -o backup -url {existing site collection URL} -filename {name of file}

To restore:
stsadm -o restore -url {new site collection url} -filename {name of file}

Thanks to Jose Barreto for saving me the task of rebuilding the collection from scratch

Thursday, May 10, 2007

Getting Users from Multi-select Person or Group Fields

The following code illustrates how to extract user information for all users listed in a multiselect Person or Group field (in this case extracting all the users listed in the "Control Owners" field of the first list item in the "Controls" list) :

using (SPWeb web = new SPSite(WEB_URL).OpenWeb())
{
    StringBuilder sb 
= new StringBuilder();    
    
SPList list web.Lists["Controls"];

    
SPFieldUserValueCollection userVals (SPFieldUserValueCollection)list.Items[0]["Control Owners"];
    foreach 
(SPFieldUserValue userVal in userVals)
    {        SPUser user 
userVal.User;
          
sb.AppendLine(string.Format("{0}", user.LoginName));
    
}
}

Wednesday, May 9, 2007

Starting From Scratch

Spent a few interesting hours today working with Dave Mateer and Michael Smithson on a new web application for Treasure Hunts in Christchurch.

The idea behind this project of Dave's is to explore topics like scrum, architecture, enterprise library, asp.net drag-and-drop controls by developing an actual web application - far more likely to learn useful stuff when the target is an actual live application than just by "playing" with the technologies.

We made a good start this morning, discussing stories for the application and spiking a tiered architectured. Found the hosting at www.openhost.co.nz to be very usable. Slotted the Enterprise Library v3 into the solution to gain easy DAL access to the database (and to get re-acquainted with it's strengths).

We cut the initial code using pair programming - I've never tried this technique properly before, and found that once over the initial discomfort of having my poor typing skills scrutinised (you know the feeling? Spelling and keyboard skills disappear as soon as someone is watching over your shoulder!), it was good to have improvements pointed out as the lines of code grew. Maybe one day AI will reach the stage that our PCs can make verbal suggestions as they "watch" what we type - though then again that's a worrying thought.

Dave, Michael and others are to continue working on the application until Sunday afternoon. Good luck, guys! I reckon it will be a useful little application when finished - I certainly plan to do one of the treasure hunts with my family.

Dave is blogging about the experience at http://treasuresprint.blogspot.com/

Tuesday, May 8, 2007

SharePoint ListTemplate IDs

Here are the SharePoint 2007 ListTemplateIDs for use in event receivers (amongst others!):
List Template IDList Type
100Generic (custom) List
101Document Library
102Survey
103Links List
104Announcements
105Contacts
106Events
107Tasks
108Discussion Board
109Picture Library
110Data Source
111Site Template Gallery
113Web Part Gallery
114List Template Gallery
115Form Library
119Wiki Page Library
120Generic (custom) List in Datasheet view
150Project Tasks
200Meeting Series List
201Meeting Agenda List
202Meeting Attendees List
204Meeting Decision List
207Meeting Objectives List
211Meeting Things to Bring List
212Meeting Workspace Pages List
300Portal Sites List
1100Issue Tracking

The LCID and FormatFlag in the ddwrt:FormatDate method

The following images illustrate the date strings output by setting the LCID and FormatFlag parameters in the ddwrt:FormatDate(szDate, lcid, FormatFlag) method. Note that the use of an LCID of 1053 and a FormatFlag of 5 gives a sortable string value.

I have added the code used to generate these lists in this post.

en-US (LCID 1033)

de-DE (LCID 1031)

es-ES (LCID 1034)

en-GB (LCID 2057)

Adding Custom Build Steps to a Visual Studio Project

Developing a solution to deploy a timer job involves modifying the CSPROJ file (an MSbuild file) to call the MakeCab utility - this creates a WSP file.

I found that adding an Import statement referring to the custom Targets file (in this case named BuildSharePointPackage.targets) from within the CSPROJ file didn't always produce the right output.

The cause was that MSBuild executes the last build target in order of appearance of Import statements. The csproj file included:
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<
Import Project="BuildSharePointPackage.targets" />

The BuildSharePointPackage.targets file did not call any of the standard compile statements in the Microsoft.CSharp.targets file used to build C# projects, so the dlls were not getting rebuilt, and old versions os the dlls were being placed in the WSP file.

The solution was as follows:
  1. Set the DefaultTargets attribute in the Project element of the csproj file to equal the Name attribute of the Target element in the custom targets file:
    <Project DefaultTargets="BuildMossPlus" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  2. Add a DependsOnTarget attribute to the Target element in "BuildSharePointPackage.targets":

    <?xml version="1.0" encoding="utf-8" ?>
    <Project DefaultTargets="BuildMossPlus" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      
    <PropertyGroup>
        
    <MakeCabPath>"C:\Program Files\Microsoft Cabinet SDK\BIN\MAKECAB.EXE"</MakeCabPath>
      </PropertyGroup>
      
    <Target Name="BuildMossPlus" DependsOnTargets="$(BuildDependsOn)">
        
    <Exec Command="(SOME COMMAND)"/>
      </
    Target>
    </Project>


(with help from the MSBuild Team Blog)

SPSchedule String Formats (the FromString method)

When establishing timer jobs by defining an SPSchedule in a feature receiver (as per Andrew Connell's excellent article), the schedule can be entered using the FromString method of the SPSchedule class - see this post by Mark Arend for the acceptable string formats.

Note that this is a static method!

There is a lot of choice and flexibility in the permitted formats - some examples are "every 15 minutes", "hourly between 10 and 12" and "monthly at 1 09:00:00"

Tuesday, May 1, 2007

Connecting to Two Web Parts with a Different Parameter for Each

Had a solution requiring a single drop-down list in a dataview web part to filter the contents of two other data view web parts, each of which required a different field as the input parameter - i.e. the Controls web part was to be filtered by Control Refs and the Gaps web parts was to be filtered by Gap Refs. The two fields (Control Refs and Gap Refs) are multi-select lookup columns in the Risks list.

After much experimentation (and a fair bit of cursing!), I found the answer.

The dropdown dataview uses the following code for each row. The important points to note are the concatenation of the two required field values in the fields variable, and the concatenation of the two consumer GUIDs in the GenFireCOnnection call.

<option>
    
<xsl:attribute name="value">
        
<xsl:variable name="cursel">dvt_curselkey={<xsl:call-template name="dvt.gencurselkey"><xsl:with-param name="RowPath" select="." /></xsl:call-template>}</xsl:variable>
        
<xsl:variable name="fields">@Control_x0020_Refs=<xsl:value-of select="ddwrt:ConnEncode(string(@Control_x0020_Refs))" />#@Gap_x0020_Refs0=<xsl:value-of select="ddwrt:ConnEncode(string(@Gap_x0020_Refs0))" /></xsl:variable>
        
<xsl:text>javascript:</xsl:text>
        
<xsl:value-of select="ddwrt:GenFireConnection( concat( 'g_1a7694bc_1a99_427e_aece_bcbfdf0ba2b9#g_c79865fa_2833_4543_aefe_0a8f466211aa*', $fields),string($cursel))"></xsl:value-of>
        
<xsl:text>;</xsl:text>
    
</xsl:attribute>
    
<xsl:if test="$dvt_curselkey=@ID">
        
<xsl:attribute name="selected">true</xsl:attribute>
    
</xsl:if>
    
<xsl:value-of select="@Risk_x0020_Ref" /> - <xsl:value-of select="@Title" />
</
option>

Data Source Details in SharePoint Designer Fails to Show List Data

I have a list with a calculated value which is based on two other text values. Having entered a few test items in the list, the Data Source Details pane in SharePoint Designer was reporting an error with retrieving data for that list.

Further investigation revealed that one of the paths through the formula for the calculated column was returning a number rather than a string. This incorrect data type was causing the failure in the Data Source Details

Friday, April 27, 2007

Why Use the Custom Zone for Administrators

The model logical architecture released a while ago by Microsoft for a corporate MOSS deployment includes a configuration that really had me wondering "Why?" - that is the use of the custom zone for administrative access to all the sites.

One answer I have come up with - by assigning a policy to the custom zone for the SharePoint administrator user group, and granting full control in this policy, then the administrators are guaranteed to have full control over all sites and content in the delpoyment. Note that this is assuming an AD group named "SharePoint Administrators" exists in the domain.

The permissions applied in a policy override all other permissions in sites, so even if a user with site admin rights had removed all explicit permissions for the SharePoint Administrators user group from their site, the policy enforces access.

Sunday, April 22, 2007

Usernames in Data View Web Parts

Data View web parts by default offer the "friendly" name in the UserID parameter - if the logon username is required, find the ParameterBinding element with the name of UserID in the Data view's XSL, and change the Location attribute value from CAMLVariable to ServerVariable(LOGON_USER)

Tuesday, April 17, 2007

Modifying the Run Times of Recycle Bin Timer Jobs

See http://www.sharepointblogs.com/mattg/archive/2007/03/08/starting-timer-jobs-manually-recycle-bin.aspx for this.

And whilst on the subject of timer jobs, here's how to create one - http://andrewconnell.com/blog/archive/2007/01/10/5704.aspx

Viewing Information Management Auditing Logs in MOSS

In the site in which an information management policy is active, activate the Reporting site collection feature. This will enable the link to the Audit Log Reports page in the site settings.

Log reports page URL: _layouts/reporting.aspx?Category=Auditing

Adding a Loopback Connector

Microsoft Loopback Adapter
a. Click Start, Control Panel, and open the Add Hardware wizard.
b. Click Next. Wait a moment while the wizard scans for hardware.
c. Select: Yes, I have already connected the hardware, click Next.
d. Scroll to the bottom of the list and select Add a new hardware device. Click Next.
e. Select: Install the hardware that I manually select from a list (Advanced). Click Next.
f. Select: Network adapters. Select: Microsoft. Select: Microsoft Loopback Adapter.
g. Click Next. Click Next again. Wait a moment. Click Finish.


Configure the Loopback Adapter
h. Click Start, Control Panel, and open the Network Connections utility.
i. Right-click the Microsoft Loopback Adapter connection and select Properties.
j. Double-click Internet Protocol (TCP/IP).
k. Now configure an address for this adapter. Select: Use the following addressIP Address: 10.50.50.1Subnet mask: 255.255.255.0Default gateway: You can ignore DNS. Click OK. Click OK again.

Post with WSS Field Names

Handy list of WSS field names at http://blog.thekid.me.uk/archive/2007/03/21/wss-field-display-amp-internal-names-for-lists-amp-document-libraries.aspx

Page Fails After Deleting a Connected Web Part

Had this problem a few times when removing a connected web part from a WSS v3.0 web part page using the web part menu in the browser - the deletion operation leaves behind a web part connection definition in the page, and the page then fails to render as the pre-processing notices that the target of this connection is missing.

Haven't yet traced the cause of the problem, as it occurs infrequently. I have a feeling that it is caused by custom code in other web parts on the page that attempt to fire that connnection - perhaps the connection definition is not removed because an element still uses it (even though that element was manually added in code).

Thursday, March 29, 2007

Don't Use the 3GB Switch With SharePoint

According to the knowledge base article 933560, use of the /3GB switch is not supported on servers running SharePoint 2007

How to Track New Sites Created in SharePoint

As the "site created" event isn't offered in the set of exposed events, it seems that the way to log, audit or carry out some other action on the creation of a new site is to use Feature Site Template Association.

The post entitled Customizing MOSS 2007 My Sites within the enterprise by Steve Peschka explains how to do this with a nice example. Includes an explanation of how to run .net code, too, using "feature provisioning code callout".

Phew, so much to learn!

Wednesday, March 28, 2007

Governance of a SharePoint Environment

I am in the process of writing a governance document for a major SharePoint deployment. Along the way I am finding that the more I research this area, the more there is to consider. Just as well several days have been budgeted for the task!

Here are some of the materials I have found useful:
As I find other useful stuff, I'll add it here.

Thursday, March 15, 2007

Formating Dates, Times and Currency in Data View Web Parts

If you find that the format of dates, times and currencies are incorrect in your data view web parts, you probably will need to modify the Locale ID being applied in the XSL format statements. For example, the formatdate() XSL method may have the default "English-United States" LCID of 1033.

Note that to change the formatting in other views - for example in a list view - adjust the locale in the Regional Settings page of the Site Settings.

Use the Locale ID (LCID) from the following table to apply regional formatting:
Locale Description LCID Locale Description LCID
Afrikaans 1078 Icelandic 1039
Albanian 1052 Indonesian 1057
Arabic - United Arab Emirates 14337 Italian - Italy 1040
Arabic - Bahrain 15361 Italian - Switzerland 2064
Arabic - Algeria 5121 Japanese 1041
Arabic - Egypt 3073 Korean 1042
Arabic - Iraq 2049 Latvian 1062
Arabic - Jordan 11265 Lithuanian 1063
Arabic - Kuwait 13313 FYRO Macedonian 1071
Arabic - Lebanon 12289 Malay - Malaysia 1086
Arabic - Libya 4097 Malay – Brunei 2110
Arabic - Morocco 6145 Maltese 1082
Arabic - Oman 8193 Marathi 1102
Arabic - Qatar 16385 Norwegian - Bokmål 1044
Arabic - Saudi Arabia 1025 Norwegian - Nynorsk 2068
Arabic - Syria 10241 Polish 1045
Arabic - Tunisia 7169 Portuguese - Portugal 2070
Arabic - Yemen 9217 Portuguese - Brazil 1046
Armenian 1067 Raeto-Romance 1047
Azeri - Latin 1068 Romanian - Romania 1048
Azeri - Cyrillic 2092 Romanian - Moldova 2072
Basque 1069 Russian 1049
Belarusian 1059 Russian - Moldova 2073
Bulgarian 1026 Sanskrit 1103
Catalan 1027 Serbian - Cyrillic 3098
Chinese - China 2052 Serbian - Latin 2074
Chinese - Hong Kong SAR 3076 Setsuana 1074
Chinese - Macau SAR 5124 Slovenian 1060
Chinese - Singapore 4100 Slovak 1051
Chinese - Taiwan 1028 Sorbian 1070
Croatian 1050 Spanish - Spain 1034
Czech 1029 Spanish - Argentina 11274
Danish 1030 Spanish - Bolivia 16394
Dutch - the Netherlands 1043 Spanish - Chile 13322
Dutch - Belgium 2067 Spanish - Colombia 9226
English - Australia 3081 Spanish - Costa Rica 5130
English - Belize 10249 Spanish - Dominican Republic 7178
English - Canada 4105 Spanish - Ecuador 12298
English - Caribbean 9225 Spanish - Guatemala 4106
English - Ireland 6153 Spanish - Honduras 18442
English - Jamaica 8201 Spanish - Mexico 2058
English - New Zealand 5129 Spanish - Nicaragua 19466
English - Phillippines 13321 Spanish - Panama 6154
English - South Africa 7177 Spanish - Peru 10250
English - trinidad 11273 Spanish - Puerto Rico 20490
English - United Kingdom 2057 Spanish - Paraguay 15370
English - United States 1033 Spanish - El Salvador 17418
Estonian 1061 Spanish - Uruguay 14346
Farsi 1065 Spanish - Venezuela 8202
Finnish 1035 Sutu 1072
Faroese 1080 Swahili 1089
French - France 1036 Swedish - Sweden 1053
French - Belgium 2060 Swedish - Finland 2077
French - Canada 3084 Tamil 1097
French - Luxembourg 5132 Tatar 1092
French - Switzerland 4108 thai 1054
Gaelic - Ireland 2108 Turkish 1055
Gaelic - Scotland 1084 Tsonga 1073
German - Germany 1031 Ukrainian 1058
German - Austria 3079 Urdu 1056
German - Liechtenstein 5127 Uzbek - Cyrillic 2115
German - Luxembourg 4103 Uzbek – Latin 1091
German - Switzerland 2055 Vietnamese 1066
Greek 1032 Xhosa 1076
Hebrew 1037 Yiddish 1085
Hindi 1081 Zulu 1077
Hungarian 1038    

Wednesday, March 14, 2007

Office 2007 (including SharePoint) Resources

See Erika Ehrli's top ten list for a set of valuable Office resources - links to articles, blogs and whitepapers. Including a link to the Office 2007 Developer Posters which are pretty handy.

Javascript in the Onload Event for a SharePoint Page

The simple way to add JavaScript behaviours to a SharePoint page is to add a script block with the for and event attributes set to the relevant object and event.

For instance, to insert a value from the querystring into the page title, add the following script to the top of the PlaceHolderMain Content Place Holder block:


    <script type="text/javascript" language="javascript">
    function getQueryStringValue(qsName) {
        
var querystring = window.location.search.substring(1);
        var 
qsPair querystring.split("&");
        for 
(var i=0;i<qsPair.length;i++) {
            
var pair qsPair[i].split("=");
            if 
(pair[0].toLowerCase() == qsName.toLowerCase()) {
                  
return pair[1];
            
}
        } 
        
return '';
    
}    
    </script>
    <script type
="text/javascript" language="javascript" 
for="window" event="onload">
        
document.title 'Details for ' + getQueryStringValue('supplier') + document.title;
    
</script>

Tuesday, March 13, 2007

Supplying the WebID to the Lists.asmx Web Service in SharePoint 2007

Useful tip from Ishai Sagi on how to supply the optional WebID argument when calling the Lists web service - by first making a call to the SiteData web service.

Monday, March 12, 2007

Create a Dynamic Title in a Data View Web Part Without Code

Well, sort of - this is a bit of a cheat, but the effect is satisfying in cases where users require no control over web parts on a page. All that is required is a little extra XSL. The beauty of this approach is that no web part needs to be written in C# or VB.Net, and that any data available in the data view can be used in the title.

First, set the Chrome Type for the web part to None. Then add a new row to the table in the Data View. The contents of the cell in the row will become the title.

The trick is to apply the standard Web Part title bar CSS styles to the new table. The fragment below shows the styles that need to be applied to the row and to the contents of the cell:

<tr valign="top" class="ms-WPHeader">
    
<td nowrap=""><h3 class="ms-standardheader ms-WPTitle"><span>Matching Suppliers</span></h3></td>
</tr>

Thursday, March 8, 2007

Displaying a Document Icon in a Data View

To display the correct document icon in a dataview, use the following XSLT source:

<a target="_self">
   
<xsl:attribute name="href">
      
<xsl:value-of select="@FileRef"/>
   </
xsl:attribute> 
   
<img border="0">
      
<xsl:attribute name="src">
         /_layouts/images/
<xsl:value-of select="ddwrt:MapToIcon(string(@HTML_x0020_File_x0020_Type),string(@File_x0020_Type))"/>
      </
xsl:attribute> 
   
</img>
</a>

The MapToIcon method derives the correct icon name from the supplier document type (but note it returns only the icon file name, not the path).

Wednesday, March 7, 2007

Filtering a List by a Partial Match

On a SharePoint site I have been creating, a requirement is to display a list of Suppliers filtered by the first few letters that have been entered into a search box. One method to achieve this is using a Form Web Part and a Data View Web Part.

Add a Form Web Part to the page - in my case it is called "Search By Supplier". Next, in SharePoint Designer, add a Data View Web Part (called "Suppliers" in this case) that contains the Supplier Name column. A parameter is next added to the Data View Web Part - I have named it SupplierNameStart. This parameter will be used to tie the Web Part connection to a filter.

A new filter is added next to the Data View - the filter criteria is set so that the "Supplier Name field starts with [SupplierNameStart].

The final task is to create the web part connection. The wizard steps are as follows:
  1. Create a connection for the form web part. The "Search By Supplier" web part is to Provide Form Values To another part.
  2. The web part needs to Connect to Another Web Part on this Page
  3. Select the Suppliers web part as the target, and the target action to be Get Parameters From
  4. Choose columns - The column in the "Search By Supplier" web part is the text box name (in the HTML source of the Form Web Part). This column should be associated with the input of "SupplierNameStart" to the Supplier Web Part (i.e. the parameter).
And thus the supplier list is filtered by the letters entered into the form (when the go button is clicked)

Sunday, February 25, 2007

Creating a Form to Edit FIelds in a SharePoint List Item

Copy and paste the EditForm.aspx page associated with the SharePoint list. Then delete the existing List Form control (as this can not be editted in the designer view) and on the SharePoint Designer menus choose Insert/SharePoint Controls/Custom List Form...

The Custom List Form Web Part displays all editable fields in the list, and these can then be moved, deleted, other appended or can be modified to be non-editable items by opening the Common FormFields Tasks dialog for each field. This allows the form control for each field to be rendered as formatted text.

SharePoint Designer Data Source Library Fails to Display Lists

Had an issue today where the Data Source Library pane in SharePoint Designer would not display any lists or document libraries from the current site, or from other sites I tried to add.

Eventually fixed this by removing all external data sources, open default.aspx page on the site, and refreshing the Data Source Libraries several times!

Monday, February 19, 2007

Office Tips from a Microsoft Partner Presentation

Just spent half a day at a Microsoft Resellers’ Roadshow – included some very informative presentations on Vista, Office and SharePoint. Even the licencing presentation was clear (others such presentation I have attended in the past have certainly been lacking clarity, due in a large part from the complexity of the programs. Well done to Carlos Martinez for that!).

A couple of little tips that came from the seminars;

  • The Office Migration Planning Manager (OMPM) is a handy tool for converting Office 2003 documents to OpenXML format. That conversion is not necessary for using those documents in Office 2007, of course, but it could be useful for reducing document sizes. Also can just be convenient for business analysis work, to determine the number of Office documents stored by a company – could also be used, I guess, in capacity planning exercises in calculating the size of document stores to be indexed by SharePoint search. The presenter gave an example of what to expect in terms of performance from that tool – it took 2 hours to analyse 16,000 documents for him. Note that it does not have to carry out the conversion, and can be used just for the analysis.
  • Group Schedules in Outlook can be a great time saver. They allow the schedules for a set of individuals and resources to be saved as a group for easy reuse when scheduling across this same combination of people and resources (outlined here).
  • Check the suitability of Vista on PCs across a network using the Application Compatibility Toolkit.

Thursday, February 15, 2007

Small Steps Web Site Launched

Have today completed and gone live with a new version of the company website at http://www.smallsteps.co.nz Still all static HTML at the moment, but I was focussed on applying the philosophy from the guys at 37 Signals. Basically I wanted to get something small live on the site fast, and tweak later. Will start using master page soon.

More experimention with CSS went into it's creation, along with a few design decisions made on the fly when various block elements appeared in unexpected places due to CSS rules - and the "accidents" made the design look better! I used a great book by Dave Shea and Molly E. Holzschlag (The Zen of CSS Design) to help me along the way.

Tuesday, February 13, 2007

Web Standards, and Testing Across Multiple Browsers

I have just finished converting a site from being table-based to being CSS-driven and standards compliant. The brief was to confirm to XHTML 1.1 and WCAG 1.0. Once the new design was in place, I needed to test the site against multple browsers, including mbile device browsers.

I experimented with two options;

  • Cross-browser testing was done using the service at BrowserCam, which I was very impressed by. The free trial on that site allows for testing across a sizeable combination of browsers and operating systems (from FireFox 1.5 on Linux, through Safari 2.0 on OSX10.4, right up to IE7 on Vista with most other combinations you'd ever need in between), and the pricing looks very reasonable compared with the difficulty of actually hosting the numerous combinations.
  • Mobile browser testing using the online Opera Mini simulator at http://www.operamini.com/demo/?url= Just add the URL you want tested in the query string, and you'll see your page presented in the Opera Mini. Note that there are some other mobile browser testing options.

Another option I have not yet tried is the BrowserShots site (currently in a 'Technology Preview' state).

The goodness of web standards shone through during the cross-browser testing. The site rendered well in all combinations of platform and browser apart from IE5.2 on the Mac (which seems to have problems with background images). And the site even worked well in Opera Mini once I had hidden an image and some promotional text using a stylesheet tailoerd for handheld media.

Which all goes to show that applying XHTML, semantic markup and all those other best practices really does work!

Tuesday, February 6, 2007

How to Package (aka Export or backup) a SharePoint 2007 Web Site

To move or save a web site, the following articles give various options and the advantages/disadvantages of those options:
The options boil down to Exporting to a web package (good at duplicating a site structure, but unable to save list data), backing up (included all data, but unable to save certain customisations such as workflows and alerts) or creating a Site Template (can include list data, but bad at replicating site columns and content types to a new site based on the template).

Error when a Connected Web Part is Deleted

Caused an error on a development site today by deleting two web parts without first deleting the connection between them. This action seems to have left an orphaned connection within the page source, as the default.aspx page then failed to open, instead showing the following error:

"Cannot find the connection provider web part for..."

To remove the error, it was necessary to open the default.aspx in code view in the SharePoint Designer, and to delete the WebPartPages:SPWebPartConnection element completely.

Saving and Deploying a Custom Content Type

If a SharePoint 2007 site includes site columns and a content type, saving that site as a site template and then creating a new site using that template does not recreate the content type.

Therefore it seems that the site columns and content type must be deployed as a feature. Luckily Mark Collins at Share This Point has written a great guide to using features for site columns and content types.

Monday, February 5, 2007

Customising the New and Edit Forms for SharePoint 2007

I was planning to customise the newform.aspx page for a document library in order to prepopulate a few fields, but was saved several hours of frustration thanks to the discussion threads on Jan Tielens' Blogging and Kristian Kalsing.

The story seems to be that modifying the forms for document libraries breaks the "Attach File" button.

Here's looking forward to a fix....

WSS Default Master Page Contents

A list of the placeholders on a default master page, plus a little other useful stuff about master pages, at http://msdn2.microsoft.com/en-us/library/ms467402.aspx

How to Reference the SharePoint Assemblies

(Thanks to .Net Geeks)

To develop against the SharePoint assembly on a machine that is not a server, check out the following:

Setting a Reference to the Microsoft.SharePoint Assembly

After creating a project, add a reference to the Microsoft.SharePoint assembly to import its namespaces and implement IntelliSense features in the Object Browser and Code Editor.
To add a reference to the Microsoft.SharePoint assembly

  1. In Solution Explorer, right-click the project, and then click Add Reference on the shortcut menu.
  2. On the .NET tab of the Add Reference dialog box, select Windows SharePoint Services in the list of components, and then click OK.
    To run or debug code that uses the Microsoft.SharePoint assembly, you must run the code on the server running Windows SharePoint Services. If you are using Visual Studio 2005 on a remote computer, you cannot run or debug code that uses the object model. However, you can set a remote reference to the assembly to write code and see the Microsoft.SharePoint assembly represented in the Code Editor. To add a remote reference in this way, do the following:
    Click the Browse tab and navigate to Microsoft.SharePoint.dll in Local_Drive\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\ISAPI folder on the server running Windows SharePoint Services. You may instead want to copy Microsoft.SharePoint.dll from this folder to a local drive on the remote computer, and then open this local copy of the DLL. Click Open.

(from http://msdn2.microsoft.com/en-us/library/ms479423.aspx)

Welcome

So much to learn, so here I go....

As I find useful things relating to SharePoint (MOSS and WSS 3), .Net, workflows and the application of all these things to business needs, I'll note them down here. Will be of value to me, and maybe you'll learn something, too.