Force Left Nav To at least 200 Pixels wide
Force Body To at least 500 Pixels high
SharePoint MindsharpBlogs > James Curry > Posts

 Single Post

Sep 26
Published: September 26, 2009 23:09 PM by  James Curry

Recently I came up with a simple way to add a Help Desk link to every page in a SharePoint farm. The method I used was a Farm scoped feature that changes the My Links control so that it displays a Help Desk link next to the standard SharePoint help icon.


One of the nice things about the method uses is that it requires no compiled code and no DLL. The solution consists entirely of an ASCX user control that is based on the standard My Links user control with the addition of the Help Desk Link. While the Help Desk link isn’t the prettiest that could be easily rectified by a person who isn’t stylistically challenge. (Meaning someone other than me!) It is also easy to change the text or if your familiar with .ASCX controls or .ASPX pages add an image or something fancy.

The actual link is comprised of only a handful of lines of code:

<td class="ms-globallinks">
   <asp:LinkButton ForeColor="Blue" Font-Bold="true" Font-Size="Larger" runat="server" ID="HelpLink" Text="Help Desk" PostBackUrl=""></asp:LinkButton>

For the sake of simplicity the three lines above were simply added to a copy of the MyLinks.ascx control which I named Mindsharp_HelpLink_MyLinks.ascx.

The entire control looks like this:

<%@ Control Language="C#" %>
<%@ Register Tagprefix="OSRVWC" Namespace="Microsoft.Office.Server.WebControls" Assembly="Microsoft.Office.Server, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Register Tagprefix="SPSWC" Namespace="Microsoft.SharePoint.Portal.WebControls" Assembly="Microsoft.SharePoint.Portal, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Import Namespace="Microsoft.SharePoint" %>

<td class="ms-globallinks"><SPSWC:MyLinksMenuControl id="MyLinksMenu" runat="server" /></td>
<td class="ms-globallinks"><asp:Literal id="hlMySiteSpacer" runat="server" /></td>
Only alter the codes contained between these comments.
Everything else is required to provide default MyLinks functionality

Change the Text property to alter the displayed text.
Change the PostBackUrl property to set the URL of your help desk.

Move the order of the <TD> to move the Help Desk link to the left of the My Links control.
<td class="ms-globallinks"><asp:LinkButton ForeColor="Blue" Font-Bold="true" Font-Size="Larger" runat="server" ID="HelpLink" Text="Help Desk" PostBackUrl=""></asp:LinkButton></td>
Only alter the codes contained between these comments.
Everything else is required to provide default MyLinks functionality

As noted in the comments in the User Control you  can adjust the order of the Help Desk link by changing the order of its <TD> element in the user control’s table.

To actually display the control we need a control feature.  SharePoint features require two types of files, a header file named Feature.xml and an Elements.xml file that does all the real work.

The feature header file, named the usual Feature.xml. looks like this:

<?xml version="1.0" encoding="utf-8" ?>
<Feature xmlns=""
         Title="Mindsharp Help Link"
         Description="This feature will add a Help Desk link to the every page of every site in the farm."
    <ElementManifest Location="Elements.xml" />

This Scope=”Farm” property specifies that the feature will affect the entire Farm. That is, it will affect everywhere in your SharePoint implementation. If you would like more granular control you can change the Scope to the following values:

SCOPE Area of Effect
Scope=”Web Application” Effects an entire SharePoint Web Application and all Site Collections and Sites contained within the web application.

Note: This scope will require Central Admin access to activate.
Scope=”Site” Effects an entire Site Collection and all sites within the site collection.

Note: This scope will require Site Collection Administrator privileges to activate.
Scope=”Web” Effects a single site only.

The Farm scope has some nice advantages. It only needs to be activated and deactivated in one place. Also, it will effect any future web applications, site collections, or sites that are created after it is activated.

One nice touch that I like to add to features is a custom icon. I like to display the Mindsharp, Summit 7 Systems, or a customer logo in the list of features. This feature displays the Summit 7 Systems logo as specified by the ImageUrl property. You can specify your own custom image by placing the appropriate image file in the images folder and referencing it in the ImageUrl property. I would recommend placing it in a subfolder as I did with my Summit 7 logo. The ImageUrl property is relative to the SharePoint IMAGES folder in the 12 hive. 

Therefore my custom icon is located in C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\IMAGES\S7S and is named s7sMini.jpg.

Feature header files are never very exciting because all the real work gets done by feature receiver or an Elements.xml file.  The control’s Elements.xml file looks like this:

<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="">
  <Control Id="GlobalSiteLink2" Sequence="99" ControlSrc="~/_controltemplates/Mindsharp/Mindsharp_HelpLink_MyLinks.ascx" />

The Control element makes this feature a Control Feature. Control Features place user controls within predefined regions called Delegate Controls. Our control targets the GlobalSiteLink2 which is normally occupied with the MyLinks.ascx user control that was used as the basis for the Help Desk Link user control. You could also override the behavior of the My Sites user control (MySiteLink.aspx) located at ControlId=”GlobalSiteLink1” or perhaps use the Small Search Input Box located at ControlId=”SmallSearchInputBox”. To learn more about the Control Ids and how they work open a copy of any SharePoint Master Page and search for “DelegateControl”. Be careful not change any of Microsoft’s master pages doing so is strictly not supported. You can copy a Microsoft master page and use it as a basis for customization.

The ControlSrc property specifies a the location of the user control that will be displayed. Microsoft has provided a default location for SharePoint user controls and have locate our user control in a subfolder there:

C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\CONTROLTEMPLATES\Mindsharp

The 12\TEMPLATE\CONTROLTEMPLATES\Mindsharp file location maps ~/_ControlTemplates/Mindsharp/  Microsoft has created a virtual directory for user controls and /_ControlTemplates can be appended to any SharePoint URL making our Help Desk Link available everywhere in SharePoint.


No SharePoint project is complete without packaging as a Windows SharePoint Services Solution Package (WSP) and this one is not an exception. Although I often use WSPBuilder to create solution packages this one was so short (and I didn’t want an unneeded assembly in my WSP) that I simply created my own DDF and Manifest.xml files. (Actually, I cheated a bit I started with a WSPBuilder Manifest.xml file and altered it.)

The Manifest.xml file looks like this:

<?xml version="1.0" encoding="utf-8"?>
<Solution xmlns:xsi="" xmlns:xsd="" SolutionId="cf27bd35-26a0-45a2-9000-4371d6dcd7a1" xmlns="">
    <TemplateFile Location="CONTROLTEMPLATES\Mindsharp\Mindsharp_HelpLink_MyLinks.ascx" />
    <TemplateFile Location="Images\S7S\s7sMini.jpg" />
    <FeatureManifest Location="Mindsharp_HelpLink\feature.xml" />

The WSP.DDF file which I used in conjunction with MAKECAB looks like this:

;WSP CAB Generation

;Define the output directory and CAB file name (with a wsp extension)

;Include the following files in the CAB Root

;Include Feature files (must be in AltHeader\ folder in CAB)
.Set DestinationDir="Mindsharp_HelpLink\"

;Include the User Control
.Set DestinationDir="CONTROLTEMPLATES\Mindsharp\"

;Include Images
.Set DestinationDir="Images\S7S\"

To automate the generation of my WSP I added the following to my Visual Studio Post Build Events:

cd "$(ProjectDir)"

:: Create a WSP CAB
MakeCAB  /f WSP.DDF /d CabinetNameTemplate="$(ProjectName).wsp" /d DiskDirectory1="$(ProjectDir)wsp"

xcopy "$(ProjectDir)wsp"  C:\WSP\  /yes

The Post Build Events automatically build the Windows SharePoint Services Solution Package to a folder within my Visual Studio project named WSP.  The Post events then copy the solution package to C:\WSP.

Why do the double copy? Because solutions have to be added from the command line using STSADM.exe –o AddSolution and doing so is much more enjoyable when the file is near the root of the C: drive.

(Bonus content: Check out more on Post Build events, written by The Bleeker himself, at

That’s about it for this post except for a few last things: 

The whole Visual Studio Project with WSP (in convenient .ZIP format) is located here:

This post and the accompanying project are intended for educational purposes only, use at your own risk!

Thanks to Jason, Steve, Andrew, Adam, and Jerry all down in beautiful Huntsville, Alabama.  See (most of) you at SharePoint Conf in Vegas!

Guzel paylasım..

 Add Comment

* Required Field
Your Name *
Your Blog Url
Message Subject *
Message Body *