Thursday, December 28, 2006

Using SPWebConfigModification to modify a SharePoint web application's web.config for all servers in the farm

At some point in your career as a SharePoint developer you may find it necessary to push out a change to a SharePoint web application's web.config file for all servers in the farm. In the simplest of scenarios, it may be realistic to make the change to web.config manually, but if you are creating a packaged application for redistribution or there are many servers in the SharePoint farm, a better approach might be to make the web.config modifications programmatically. The WSS v3 API contains the SPWebConfigModification object which allows you to do just that. For example, if you have been following Daniel Larson's excellent series of articles on implementing AJAX in WSS v3, you know that AJAX requires an additional HttpHandler be added to a SharePoint web application's web.config in order to function properly. Here's the HttpHandler in question:
<add verb="GET" path="ScriptResource.axd" type="Microsoft.Web.Handlers.ScriptResourceHandler, Microsoft.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="false"/>

To push out the AJAX HttpHandler declaration programmatically, the following example console application calls SPWebConfigModification. For the purposes of illustration, I've hard coded the web application's name ("Default Web Site"), but this could have just as easily been passed in as a command line argument:
12/28/2006 - MODIFICATION: Updated code listing with bug fix and added logic to remove the web.config modifcation.

Copy Code
using System;using System.Globalization;using Microsoft.SharePoint.Administration; public class Program { static void Main(string[] args) { string webAppName = "Default Web Site"; // Add AddAjaxHandlerToWebConfig(webAppName); // Remove //RemoveAjaxHandlerFromWebConfig(webAppName); } /// <summary> /// Adds the Ajax HttpHandler to a web application's web.config for all servers in the farm /// </summary> /// <param name="webAppName"></param> private static void AddAjaxHandlerToWebConfig(string webAppName) { AddOrRemoveAjaxHandlerToWebConfig(webAppName, false); } /// <summary> /// Removes the Ajax HttpHandler from a web application's web.config for all servers in the farm /// </summary> /// <param name="webAppName"></param> private static void RemoveAjaxHandlerFromWebConfig(string webAppName) { AddOrRemoveAjaxHandlerToWebConfig(webAppName, true); } /// <summary> /// Adds or removes the Ajax HttpHandler to a web application's web.config for all servers in the farm /// </summary> /// <param name="webAppName">Name of web application</param> private static void AddOrRemoveAjaxHandlerToWebConfig(string webAppName, bool removeModification) { string assmDetails = string.Format(CultureInfo.InvariantCulture, "Microsoft.Web.Handlers.ScriptResourceHandler, Microsoft.Web.Extensions, Version={0}, Culture=neutral, PublicKeyToken={1}", new object[] { "1.0.61025.0", "31bf3856ad364e35" }); SPWebConfigModification modification = new SPWebConfigModification("add[@path='ScriptResource.axd']", "configuration/system.web/httpHandlers"); modification.Owner = "Ajax"; modification.Sequence = 0; modification.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode; modification.Value = string.Format(CultureInfo.InvariantCulture, "<add verb=\"{0}\" path=\"{1}\" type=\"{2}\" validate=\"{3}\"/>", new object[] { "GET", "ScriptResource.axd", assmDetails, "false" }); SPWebApplication webApp = SPWebService.ContentService.WebApplications[webAppName]; if (webApp != null) { if(removeModification) webApp.WebConfigModifications.Remove(modification); else webApp.WebConfigModifications.Add(modification); SPFarm.Local.Services.GetValue<SPWebService>().ApplyWebConfigModifications(); } } }

Real world use cases where this functionality may prove useful include calling SPWebConfigModification from a Window's Installer package Custom Action or perhaps extending stsadm with a custom operation.

Thursday, November 16, 2006

Released! Download WSS v3 and MOSS 2007 RTM

After much anticipation and ballyhoo, the production releases of Windows SharePoint Services 3.0 and Microsoft Office SharePoint Portal Server 2007 are available for download.
Take a deep breath, and download the bits!
WSS v3
Download Details: Windows SharePoint Services 3.0
Download Details: Windows SharePoint Services 3.0 Lanuage Pack
Download Details: Windows SharePoint Services 3.0 x64
Download Details: Windows SharePoint Services 3.0 Language Pack x64
MOSS 2007
Download Details: Microsoft Office SharePoint Server 2007 Trial Version
* The trial keys for MOSS 2007 are listed in this blog post.
After you've got the bits, here are some instructions and howtos on getting up and running:
Version to Version Supported Upgrade Paths
Installing Windows SharePoint Services 3.0 on a Server Running Windows Small Business Server (This document shows you how to install Windows SharePoint Services 3.0 side-by-side with Windows SharePoint Services 2.0)
Installing MOSS 2007 RTM on a farm running MOSS 2007 Beta2 TR (Shane Young [MVP])
Upgrade from TR to RTM Work Around (Shane Young [MVP])
Upgrading from Windows SharePoint Services 3.0 Beta 2 Technical Refresh to Release Version (Joel Oleson)
Upgrading from Office SharePoint Server 2007 Beta 2 Technical Refresh to Release Version (Joel Oleson)
If you would like instructor-led assistance for upgrading to the latest versions of SharePoint, sign-up for our Upgrading From SharePoint 2003 to SharePoint 2007 course.
Once you've got things installed and running, send your information workers to our Applying SharePoint 2007 - Core Features course.
Categories: , , , ,

Wednesday, November 15, 2006

OBA RAP for SCM, ArcStream, and Skyscrapr

Today I was doing some research on the OBA RAP for SCM when I stumbled across ArcStream and Skyscapr

Sound Greek?  Well, the OBA Reference Application Pack for Supply Chain Management is a reference implementation put together by Microsoft to illustrate how we can build Microsoft Office System 2007 based composite solutions.  Microsoft calls these composite solutions Office Business Applications (OBAs) and describes an OBA as being "designed to support cross-functional processes and allow information workers to collaborate" across organizational boundaries.

ArcStream is a relatively new initiative from the East Region Microsoft Developer & Platform Evangelism Team which strives to provide "a constant flow of technical information as well as networking opportunities for enterprise, application, systems and aspiring architects living and working on the east coast".  A few of the key folks involved with ArcStream include Chad Brooks, Bob Familiar, Chris Bowen and Scott Jamison.

Finally, is maintained by the Architecture Strategy Team at Microsoft with the primary goal of "promoting a community-wide discussion about system architecture".  The  site provides access to videos, training, glossaries, ARCasts, and blogs that will help you learn more about technology architecture.

Good stuff! Now if I can just get all the way through Beyond Bullet Points.  So much to read, so little time!

Tuesday, November 14, 2006

The "Features" feature

The first time anyone hears about the "Features" feature in SharePoint, they either laugh or frown at it. I have yet to see anyone without at least some kind of reaction to it. However, once you get past the name, the concept of Features seems really appealing.

Features provide the “light up” functionality within SharePoint. You no longer need to decide on all the components of a site ahead of time. Each "Feature" can be added on and attached to a site after the site is provisioned. Features can be scoped at the Farm, WebApplication, Site Collection or Site level. Want to know more about Features?? Well, take a look at the following presentation and associated code that I used to present at the SharePoint Connections conference.


Intro to Excel Services

Last week, Kevin Pine and I got a chance to present at the SharePoint Connections conference. This conference was able to draw a large number of SharePoint folks from all around the country (actually the world... I saw some people there from the Netherlands). Kevin and I presented 3 sessions at the conference with the attendee count of 200+ for our largest session.
Even though this conference was held in Vegas, we didn't want the phrase "What happens in Vegas, stays in Vegas" to be our mantra. We want our attendees to be able to implement the cool stuff we did in our presentations in their own environment back home. So we decided to post all our presentations and related demo notes to our SharePoint Solutions blog.
This first blog entry is associated with our very first presentation which was focused on Excel Services. Excel Services ships with the Enterprise Edition of MOSS 2007 and provides server based Excel Capabilities to the knowledge worker. Being able to share your spreadsheets by posting them to the Excel Server is a new paradigm, but one which is sure to catch on quickly in the business world. In this presentation, I present the overview of Excel Services and then build a Dashboard which takes advantage of the new scorecarding capabilities in MOSS. You can download the zip file containing the presentation and a sample data spreadsheet by clicking on the link below. Enjoy!
Intelligent Dashboard using Excel Services

Adding Custom Links in SharePoint Portal Server 2003 Top Navigation Bar

In SharePoint Portal Server 2003, there is no easy way to add custom links to the top navigation. All the links in the navigation bar are generated dynamically by the server. Using JavaScript, we can extract the code for the top navigation bar, add custom links, and then re-render the code for the navigation bar.

In the example screenshot below, you will notice that we've added both a text link and a graphical icon link to the toolbar. The text link goes to the Google search engine and the telephone icon goes to a phone list. We can mix and match text and images and add as many extra links to the navigation bar as our user's browsers will comfortably allow. Using this method, all our custom links will appear after the dynamic navigation links that are generated natively by Sharepoint Portal Server 2003. If you have links that you want to always be available to every portal user all the time, this is an easy way to add them.
To add links like this to your portal, add the code below to your OWS.JS file and customize it as needed.

Get the code. Sorry, Blogger didn’t seem to like having JavaScript code in the post. :(

Hopefully, the comments in the code are enough to explain what's going on here. Essentially I’m using JavaScript on the pageLoad event to extract the code for the navbar table. I store it in a string variable, remove the closing tags, add onto the end enough code to create a new table cell (or two), append the closing tags back on, and rewrite the navbar table back to the client. The IF statement that looks for the existance of the navbar keeps the code from generating errors on WSS pages since they don’t contain the same navbar element. If you do have any questions, just let me know.

I was inspired to write this script while learning techniques presented in our Extreme Makeover - Portal Edition class, which is being offered again the first week of December, 2006 in Chicago.

Thursday, November 09, 2006

Another point of view

Regarding Tony's post to this blog this morning, I have a somewhat different view from my vantage point. Tony is a developer and a lot of his work involves product design and quality development. He has some marketing responsibilities as well, but that is not his primary focus.

As President of SharePoint Solutions, I have a lot of responsibility for sales and marketing. And, one of the things I have learned over the years is that the sales and marketing function in most companies is critical. Not only is it critical for the company itself, but it is also critical for the customer. Without sales and marketing professionals and good tools for them to use to get the message out, customers would never find out about products that can help them solve their business problems.

I see the services that MSD2D provides as very important sales and marketing tools that help both the advertiser and the customers. We frequently use MSD2Ds tools and services and they have been extremely effective.

I think Tony does make a good point (although perhaps a little too strongly :)) that it is important to properly label advertisements as such. That may be something MSD2D could do a better job of on the article that normally hits our inboxes each Thursday.

Wednesday, November 08, 2006

Paid Inclusion Controversy, Ethics, SPAM, and MSD2D

In the early part of 2005, Yahoo (NasdaqGS:YHOO) ran headlong into an ethical debate over the inclusion of paid sponsors' links in the results of users' queries to their search engine. The practice of providing context-sensitive advertising based on a user's search query (i.e. paid inclusion) is nothing new, and of course companies such as Google (NasdaqGS:GOOG) make a living on it. However, the moral debate Yahoo encountered was that these paid advertisements were not distinguished in any way from organic results. In other words, users were led to believe that a given item was ranked highly in the results of their search because of relevance, but in fact the item was ranked highly because some company paid for it to be there. The fact that Yahoo would employ such an obviously unethical practice is one reason I continue to use Google.
What does Yahoo's paid inclusion controversy have to with SharePoint? Well, several times per week I receive e-mail messages from a company called Penton Media under auspices of their MSD2D brand. All incoming messages I receive from MSD2D now go directly to my junk e-mail spam folder. Why? Simply put, I block the MSD2D messages due to unethical practices. The main content area of these MSD2D e-mail messages is labeled "Feature Story" and for all practical purposes appears as though it is a SharePoint-related tip from some industry expert. However, the reality of the situation in that these "Feature Story" installments are actually written by paid advertisers to peddle their products and services. In fact, MSD2D requires that any advertiser which wants to run a banner ad in one of their "Special Issue" spam e-mails also submit a "Feature Story" to run concurrent with the more obvious banner advertisement. This practice of deliberately duping the reader is unethical and merits my spam blocker.
So here is my notice to MSD2D and Penton Media: If you want out of my spam blocker and back into my inbox, re-evaluate your advertising ethics. Provide real value by including unbiased content from actual industry experts, even if you have to pay them for it. Label your advertisements clearly with a "Paid Advertisement" heading or some such. You have the largest mailing list in the SharePoint industry, and paid advertisers need you in order to market their products and services. Stop sullying and diluting your brand with questionable practices and subjecting the members of your mailing list to valueless spam.
The contents of this post are my own personal opinion and do not necessarily reflect the views of my employer SharePoint Solutions.

Monday, November 06, 2006

Walkthrough - Windows SharePoint Services 3.0 Tools: Visual Studio 2005 Extensions

Microsoft has today released the Visual Studio 2005 Extensions for Windows SharePoint Services 3.0 (VSeWSS).

"Tools for developing custom SharePoint applications: Visual Studio project templates for Web Parts, site definitions, and list definitions; and a stand-alone utility program, the SharePoint Solution Generator."

Let's take a quick walkthrough of this new toolset for SharePoint developers and see what Santa has brought us!

SharePoint Solution Generator

The first VSeWSS tool we'll take a look at is SharePoint Solution Generator (SPSolGen). SPSolGen is a stand-alone program, so after installation you'll find a link to SPSolGen has been placed in your Start Menu under All Programs.

SPSolGen can take an existing Site Definition or List Definition from WSS and automatically reverse engineer it into a Visual Studio 2005 development project. The value proposition of SPSolGen is that a designer can create a WSS Site from the browser or with SharePoint Designer and then hand it off to a developer for deeper customizations.

By default, SPSolGen will create a subfolder in your My Documents folder and place its output there.

The SPSolGen output project in Visual Studio 2005 Solution Explorer:

New Project Item Templates

If you right-click your new project in Visual Studio and select Add->New Item, you'll be greeted by five new project items:

Item Templates include:

Selecting a new List Definition launches a dialog which allows you to specify a base list type. You can optionally create an instance of the list and include an event receiver class:

The Content Type template lets you select a base type to derive from:

New Project Templates

There are also a few new project templates.

The Team Site Definition project includes an Onet.xml and provisioning receivers:

Over all this is a useful suite of tools from Microsoft, and will provide developers with a good starting point for their SharePoint projects. The reverse-engineering capabilities of SPSolGen are pretty cool. I'm looking forward to using these new templates.

Download Windows SharePoint Services 3.0 Tools: Visual Studio 2005 Extensions

Related Articles:

Anatomy of a SharePoint WSS v3 Feature Project in Visual Studio 2005

Automation in Visual Studio 2005 for WSS v3 Feature Development

Categories: , , , , , ,

Wednesday, November 01, 2006

KMWorld: Design in the Age of Web 2.0 by Jeffrey Veen

I'm out in San Jose this week attending the annual KMWorld 2006 Conference and Exposition. If you're unfamiliar with KMWorld, the show's tag line is "Strategies and Tools for Knowledge Management, Content Management, Intranets and Portals". Hands down the best session I attended on Tuesday was Design in the Age of Web 2.0 by Jeffrey Veen. Jeffrey Veen is a Design Manager for Google and founding partner of Adaptive Path. In addition to possessing solid technical acuity, Veen is a talented and charismatic speaker.

For a definition of the term Web 2.0 I'll defer to Wikipedia and term's originator Tim O'Reilly. In his standing room only presentation, Jeffrey debunked misconsceptions about the term Web 2.0, then spoke to the key elements of Web 2.0 as outlined in Tim O'Reilly's Web 2.0 Meme Map including the role of Ajax in the Web 2.0 equation.

You can download the rather large PDF (~20MB) of Jeffrey's graphic rich presentation from his website here.

Categories: , , , ,

Saturday, October 28, 2006

Presenting Two Sessions at SharePoint Information Worker Conference 2007

In January I'll be presenting two sessions at the SharePoint Information Worker Conference 2007 in Orlando, FL. IWC07 is a three-day SharePoint conference designed specifically for business, web and application professionals who need to stay on the leading edge of Microsoft’s Office System and SharePoint technologies.
Here's a summary of the two sessions which I'll be presenting:

Enabling SharePoint for Extranet Collaboration

Thousands of organizations worldwide are turning to Microsoft's SharePoint Product and Technologies for sharing critical business data with partners, customers and suppliers over the Internet. To achieve business advantage by effectively collaborating with business partners, organizations need to provide access to proprietary content while still maintaining security, audit ability and accountability.
Along with security concerns, companies are facing the challenging process of working with IT resources to get collaborative extranet sites provisioned and accessible. Once online, the ongoing tasks for user management of these collaborative applications must be identified and assigned.
In this session, attendees will be hear about enhancements in SharePoint 2007 and third-party add-ons that open new doors in terms of the possibilities and feasibility of using SharePoint as an Extranet collaboration tool.

Integrating data from business applications using the new Business Data Catalog in SharePoint 2007

The Business Data Catalog (BDC) provides a means to surface business data from line-of-business (LOB) systems into SharePoint 2007 without the need to write custom code. The BDC bridges the gap between SharePoint 2007 and business applications by bringing in key data for use in SharePoint sites, lists, search, and user profiles.
In this session, the I'll demonstrate the use of Business Data web parts and show how these web parts are used to display business data within a SharePoint application. Attendees will also learn about leveraging the Business Data field type to display business data in any SharePoint list and see how SharePoint's Search Center can gather and index data from BDC applications to provide full-text search ability.
Categories: , , , , , ,

Automation in Visual Studio 2005 for WSS v3 Feature Development

I'm anxiously awaiting Microsoft's release of Visual Studio Extensions for SharePoint Services as mentioned by Mathew Cosier here, Mart Muller here, and Wes Preston here. When released, these new extensions should make our lives as SharePoint developers a bit simpler. In the meantime, if you follow a consistent approach when laying out the structure and outputs of your WSS v3 Feature project, it becomes possible to create useful and time-saving tools for automation inside the Visual Studio 2005 IDE. In my development environment I've defined and frequently use tools to add, deploy, upgrade, retract, and delete a WSS Solution Package (wsp). My favorite of these tools is the upgrade operation, as it allows for a quick "build and test" iterative development cycle. Behind the scenes, each of these tools call the appropriate stsadm.exe operation and display the command's result in Visual Studio 2005's Output Window.

As I previously mentioned, for these external tools to be useful across all of your WSS Feature projects requires consistency in how you structure the artifacts and outputs of your project. In an earlier post, I walked you through the anatomy of a WSS v3 Feature project. Three key factors of my example Feature project's anatomy allow my external tools to function and be re-used. Please take a look at my earlier post for the specifics on how these are implemented:

  1. Makecab.exe is called from the Visual Studio project's AfterBuild target to create the WSS Solution Package including the project's freshly compiled assembly.
  2. The WSS Solution Package (wsp) is placed in the Package subfolder by Makecab.exe each time it is rebuilt.
  3. The WSS Solution Package's name is defined by the Visual Studio 2005 $(TargetName) variable.

Let's take a look at specific implementation for each of the external tools I'm using. To define these tools, from Visual Studio 2005 go to Tools->External Tools on the menu bar.

WSP Solution Add

Command: C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN\STSADM.EXE

Arguments: -o addsolution -filename "$(ProjectDir)Package\$(TargetName).wsp"

WSP Solution Deploy Global

Command: C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN\STSADM.EXE

Arguments: -o deploysolution -local -allowgacdeployment -allcontenturls -name $(TargetName).wsp

WSP Solution Upgrade

Command: C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN\STSADM.EXE

Arguments: -o upgradesolution -local -allowgacdeployment -name $(TargetName).wsp -filename "$(ProjectDir)Package\$(TargetName).wsp"

WSP Solution Retract

Command: C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN\STSADM.EXE

Arguments: -o retractsolution -local -allcontenturls -name $(TargetName).wsp

WSP Solution Delete

Command: C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN\STSADM.EXE

Arguments: -o deletesolution -name $(TargetName).wsp

As a bit of review, remember that the WSS Solution Package framework involves two-stage operations for both deployment and retraction. WSP packages must first be added to the solution store and then forward deployed to the Farm. Conversely, WSP packages must be retracted from the Farm and then deleted from the solution store in order to be removed.

Keeping the WSS v3 Solution Framework's deployment mechanisms in mind, doing a WSP Solution Add command followed by WSP Solution Deploy would get your project initially deployed into the SharePoint Farm. Running WSP Solution Retract then WSP Solution Delete would remove your project from the Farm and the solution store. As I mentioned earlier, the command I use most frequently is WSP Solution Upgrade. Upgrade allows me to iteratively cycle my code changes into SharePoint and simply hit refresh in my browser to see the updates.

Having these stsadm.exe call available directly from Visual Studio 2005's IDE has saved me a lot of clicking, typing and time. I'll finish up with a few "where do I go from here" thoughts. If desired, a developer could completely automate the package upgrade process by adding stsadm.exe's upgrade operation to the AfterBuild target of the project. Taking things a step further, stsadm.exe's extensibility can be leveraged to create additional external tools such as AC's WCM Custom Commands for STSADM.EXE.

Categories: , , , , , ,

Tuesday, October 17, 2006

Anatomy of a SharePoint WSS v3 Feature Project in Visual Studio 2005

In a previous post, I published the source code to a WSS v3 Feature which illustrates how to add sub menus to SharePoint's Site Actions menu. In this follow-up post, I'll walk through the anatomy of the Visual Studio 2005 project for this feature.

Artifact 1 - Modified class library project

This is a standard C# Class Library project modified to include the project (artifact 4) and call's BuildFeaturePackage target from the AfterBuild target. Note that this project references Microsoft.SharePoint.dll and System.Web.dll.

1 <Import Project="" />
2 <Target Name="AfterBuild">
3 <CallTarget Targets="BuildFeaturePackage" />
4 </Target>

Artifact 2 - Inclusion of SharePoint's XML Schema Definitions

References to these SharePoint XML Schema Definitions add Intellisense for Elements.xml (artifact 3), Feature.xml (artifact 5) and Manifest.xml (artifact 7).

Artifact 3 - Elements.xml

Element manifest file containing definitions to the feature's elements. This manifest file is referenced from Feature.xml (artifact 5). See this blog post for details on the contents of Elements.xml.

Artifact 4 -

Custom MSBuild project used to create the WSS Solution Package for deployment of the feature. calls MakeCab.exe, which can be downloaded with the Microsoft Cabinet SDK. For the Exec call (line 6) to work, MakeCab.exe is expected to be located in the system path.

1 <?xml version="1.0" encoding="utf-8" ?>
2 <Project DefaultTargets="BuildFeaturePackage" xmlns="">
4 <Target Name="BuildFeaturePackage">
5 <Copy SourceFiles="$(TargetPath)" DestinationFolder="bin" ContinueOnError="false"/>
6 <Exec Command="makecab.exe /F package.ddf /D CabinetNameTemplate=$(TargetName).wsp" />
7 </Target>
9 </Project>

Artifact 5 - Feature.xml

Defines the feature and specifies the location of assemblies, files, dependencies, or properties that support the Feature. See this blog post for details on the contents of Feature.xml.

Artifact 6 - Public/Private key pair

Signs the feature's code-behind assembly so that the assembly can be placed into the Global Assembly Cache (GAC).

Artifact 7 - Manifest.xml

Defines the list of features, site definitions, resource files, web part files, and assemblies to be included in the Solution package. In this case, just a feature and its code-behind assembly are defined.

1 <?xml version="1.0" encoding="utf-8" ?>
3 <Solution SolutionId="{5DA74A52-818A-4bba-B268-AD5E29361489}"
4 xmlns="">
6 <FeatureManifests>
7 <FeatureManifest Location="SiteActionsSubMenuDemo\Feature.xml"/>
8 </FeatureManifests>
10 <Assemblies>
11 <Assembly DeploymentTarget="GlobalAssemblyCache"
12 Location="SiteActionsSubMenuDemo.dll">
13 <SafeControls>
14 <SafeControl Assembly="SiteActionsSubMenuDemo, Version=, Culture=neutral, PublicKeyToken=e9db3057acd9c0f6"
15 Namespace="SiteActionsSubMenuDemo"
16 TypeName="*"
17 Safe="True" />
18 </SafeControls>
19 </Assembly>
20 </Assemblies>
22 </Solution>

Artifact 8 - Package.ddf

Package.ddf is a MakeCab diamond directive file used to define the structure and contents of the solution package.
1 ;*** MakeCab Directive file
2 ;
3 .OPTION Explicit ; Generate errors
4 .Set DiskDirectoryTemplate=CDROM
5 .Set CompressionType=MSZIP
6 .Set UniqueFiles=Off
7 .Set Cabinet=On
8 .Set DiskDirectory1=Package
9 ;
10 ; \
11 ;**************************************************
12 manifest.xml
13 bin\SiteActionsSubMenuDemo.dll
15 .Set DestinationDir=SiteActionsSubMenuDemo
16 Feature.xml
17 Elements.xml
18 ;
19 ;***End

Artifact 9 - SiteActionsSubMenuCustomizer.cs

Referenced from the CustomAction located in Elements.xml (artifact 3), this C# class defines the structure of the sub menus which will be added to the Site Actions Menu. See this blog post for details on the contents of SiteActionsSubMenuCustomizer.cs.

The complete Visual Studio 2005 solution can be download here:

Source: (21.5KB)

For a basic step-by-step walk through on creating, installing and activating custom actions that will be located on the Site Actions dropdown menu, see Darrin Bishop's post Custom Actions - Simple Steps to Add Your Touch to Site Actions.

Categories: , , , , , ,

Thursday, October 12, 2006

Custom Feature: Link to WSS Central Admin from SharePoint Site Actions Menu

This post has been moved to a new location.

Compiling HTML Help Workshop Projects in Visual Studio 2005

Like many other software development shops, we use Microsoft HTML Help Workshop to create compiled HTML help files (.chm) for distribution with our packaged software applications. Although we add the .hhp project files, index files, pages and other help related artifacts to our Visual Studio solution so that they get vaulted along with our application source code into Team Foundation Server, I've always relied on the HTML Help Workshop UI itself to do the actual help file compilation.

In the interest of saving some time and having a few less apps open while I'm developing, I wanted to be able to compile the help project from within Visual Studio itself. Initially, I considered adding a call to hhc.exe from my Visual Studio project's post build event. The downside to this approach would be wasted CPU cycles (and compile time) for all those times when I'm compiling the code but no changes have been made to the help file content. Of course, I could mitigate the wasted cycles by putting some incremental build logic into my Visual Studio project with a bit of MSBuild code, but I really just wanted an on-demand method for compiling the HTML Help Workshop projects when I need to. The solution that seems to meet my requirements the best has been to configure an External Tool from Visual Studio 2005 to call hhc.exe on-demand when I have the .hhp project open. Here's how:

1. In Visual Studio 2005, select Tools->External Tools.

2. When the External Tool dialog pops up, fill-in the values as shown. Note that the macro $(ItemPath) indicates the item currently open in Visual Studio 2005's source editor pane.

3. Now that hhc.exe is configured as an external tool, you can open the .hhp project file.

4. And Select Tools->Compile Html Help.

The output from HTML Help Workshop's compiler will be displayed in Visual Studio 2005's Output window.

Categories: , , , ,

Wednesday, October 11, 2006

Using LINQ with SharePoint List Data

Ever since I sat in on one of Anders Hejlsberg's TechEd sessions about LINQ a while back, I've been wanting to take a look at how to use LINQ with SharePoint List data. Well, timing and priorities have kept me from diving in, but Kevin Hoffman has started the ball rolling with this post about using LINQ with SharePoint.

What is LINQ and why use it with SharePoint List data? Well, LINQ stands for Language Integrated Query, and what LINQ does is add a native querying syntax reminiscent of SQL to .NET Framework programming languages. To illustrate why using LINQ with SharePoint is a compelling approach to programming against List data, I'll borrow a few code snippets from Kevin Hoffman's post:

First, the usual method for enumerating List data:

1 SPSite site = new SPSite("http://server/site");
2 SPWeb web = site.AllWebs[0];
4 List<SPList> hiddenLists = new List<SPlist>(); // Do not use an SPListCollection here
5 foreach (SPList list in web.Lists)
6 {
7 if (list.Hidden)
8 hiddenLists.Add(list);
9 }

Now, the same thing with LINQ:

1 SPSite site = new SPSite("http://server/site");
2 SPWeb web = site.AllWebs[0];
4 var hiddenLists = from list in web.Lists where list.Hidden select list;

Half the code, and good-bye foreach loop! Elegant, no? Take a look at Kevin's post for more details. Thanks for the info Kevin. I'm not sure what book you're working on, but good luck!

Categories: , , , , , ,

Programmatically Manipulating WSS v3 Solution Packages Part 1: Adding a Package to the Solution Store

This is the first installment in a multi-part tutorial I'll be publishing on the topic of how to pragmatically add, deploy, retract and delete Windows SharePoint Services v3 Solution packages. Each installment in this series will be kept very simple and focused on a particular task. These articles are intended for intermediate level SharePoint developers and as such will rely heavily on the code examples themselves to illustrate the necessary patterns and practices. Why keep it short and simple? Because when I'm surfing the web for a code snippet to get a particular job done, I usually don't want to read a bunch of background information. I just want to see some code, grab it, and then move on!

In this first article we'll take a look at how to add a Solution package to the WSS v3 Solution store. If you'd like to build the complete solution along with me as I publish these articles, then create a new C# console application in Visual Studio 2005 and copy/paste the code below into your Program.cs file. If you are just looking for the snippet of code to accomplish adding a Solution package to the WSS v3 Solution store, then skip down to the AddSolution() method listed below (reference line 38) and grab it.

Here's the code:

[Listing 1]

1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4 using System.IO;
5 using System.Text.RegularExpressions;
6 using Microsoft.SharePoint.Administration;
8 namespace solmgr
9 {
10 class Program
11 {
12 static void Main(string[] args)
13 {
14 try
15 {
16 Arguments cli = new Arguments(args);
18 if (cli["add"] != null && cli["lcid"] != null)
19 AddSolution(cli["add"], uint.Parse(cli["lcid"]));
20 else if (cli["add"] != null)
21 AddSolution(cli["add"], 0);
22 else
23 PrintUsage();
24 }
25 catch (Exception ex)
26 {
27 Console.WriteLine("solmgr encountered an error:\r\n");
28 Console.WriteLine(ex.Message);
29 }
30 }
32 /// <summary>
33 /// Adds a solution to the store
34 /// </summary>
35 /// <param name="fname">Solution package file</param>
36 /// <param name="lcid">Locale</param>
37 /// <returns>Newly added SPSolution package</returns>
38 internal static SPSolution AddSolution(string fname, uint lcid)
39 {
40 if (ValidateSolutionName(Path.GetFileName(fname)))
41 return SPFarm.Local.Solutions.Add(fname, lcid);
42 else
43 throw new ArgumentException(
44 string.Format("The solution name {0} was invalid.",
45 Path.GetFileName(fname)));
46 }
48 /// <summary>
49 /// Validates solution package name
50 /// </summary>
51 /// <param name="name">Solution package file name</param>
52 /// <returns>true if solution file name is valid</returns>
53 internal static bool ValidateSolutionName(string name)
54 {
55 Regex regex1 = new Regex("[\\\\/\\*\\?\"<>|]");
56 return !regex1.Match(name).Success;
57 }
59 /// <summary>
60 /// Prints usage information
61 /// </summary>
62 internal static void PrintUsage()
63 {
64 Console.WriteLine("solmgr usage:\r\n");
65 Console.WriteLine("\t-add <solution package>\tAdd solution to store");
66 Console.WriteLine("\t[-lcid <LCID>]\t\tLocale of solution");
67 Console.WriteLine("\r\nexample: solmgr -add mypackage.wsp\r\n");
68 }
69 }
70 }

To handle the parsing of command line arguments in the example above (reference line 16), I'm using R. Griffon's Command Line Parser for C# as published on The Code Project.

In you have any questions, please add a comment to this post and I'll try to answer it as soon as I can. In part 2, I'll illustrate how to remove a WSS v3 Solution from the store.

Categories: , , , , ,