Archive for October, 2008

Deploying Windows Rights Management Services with Microsoft Office SharePoint Server 2007 Step-By-Step Guide

From Microsoft


No Comments


借左件袍咁耐 , 終於影第一 round 畢業相喇…

好耐未同D 大學同學玩喇~~



呀 , 係 , 畢業相而家放係photo album,

呢舊野用左個free 既flash, 不過佢要自己config xml, 唔識load 晒D相 , 好蠢架…

我仲無聊到寫個program 去gen 個個xml~ haha

睇黎要加快MOSS Customization 進度喇, 加油~~

10/11 – 13/11 上堂……

No Comments

10月29日 晴




我都買左個眼鏡… 下星期二有得攞喇…

雖然唔係好長時間 , 不過好開心:p

No Comments

Build-in function to convert text to XML valid format

Actually, depending on the escaping you wish to perform, you can use two functions that are available in .NET which will make sure your text is valid within XML.

The first, is to use the HttpUtility.HtmlEncode. Since most of the HTML encoding (“<“, “>”, “&” and the rest) also needs to be encoded in XML, this function will make sure the text you are entering into an XML Text node will be just fine.

If you need to encode a text that will be used as the name of an element (not its content) you can use XmlConvert.EncodeLocalName which will turn every unsupported character to a special representation that can also contain unicode characters.

No Comments

Using a Config File for Windows SharePoint Services Timer Jobs

One of the biggest problems I’ve had with timer jobs is that you cannot access the membership provider or role providers with them because they do not have a configuration value.  Then if you want to read from a configuration file, you have to point it to one of the web.configs of the site.

Not any more.  I was looking around for a way to add an app.config to the timer service and stumbled upon Jason Huh’s blog post about using the Microsoft Enterprise Library with Timer Jobs.  I figured I would be able to use the same configuration for my projects.

All you need to do is create a config file for OWSTimer.  You can do this one of two ways, you can deploy this using a solution or you can do it manually.

To do it manually, navigate to the hive (Program Files\Common Files\Microsoft Shared\web server extensions\12) and then open up the BIN folder.  Now create a new file named OwsTimer.exe.config.  In this file, you can place your config settings, this works just like an app.config or a web.config file that you would add in visual studio.

I’ve placed an example config file, but the Membership Provider and Role Provider nodes are not filled all of the way out, you can replace this with your own information or just remove the membership and role manager nodes completely.

<?xml version=”1.0″ encoding=”utf-8″ ?>



<add name=”ConnString” connectionString=”ConnectionStringGoesHere” />



<membership defaultProvider=”MembershipProvider”>


<add name=”MembershipProvider” />



<roleManager enabled=”true” defaultProvider=”RoleProvider”>


<add name=”RoleProvider” />





<add key=”SiteUrl” value=”http://sharepointsite”/>

<add key=”ProviderPrefix” value=”RoleProvider”/>



Using this, you will be able to finally use a configuration file with your timer services without having to hard code the site that you are going to read the config settings from.

For more information on deploying this with a solution, check out Jason Huh’s blog post:

No Comments

Creating Custom SharePoint Timer Jobs

A few weeks back I posted about how you can create custom timer jobs for use in the latest release of SharePoint to perform scheduled tasks. However, considering there have been almost 40 comments to the post in the last three weeks, I figured the post needed some clarification (duh, ya think?).

The first thing you need to do is create a class that inherits from the Microsoft.SharePoint.Administration.SPJobDefinition class. To implement this class, you need to create a few constructors and override the Execute() method, like so:

   1:  namespace AndrewConnell.TaskLogger {
   2:    public class TaskLoggerJob : SPJobDefinition{
   4:      public TaskLoggerJob ()
   5:        : base(){
   6:      }
   8:      public TaskLoggerJob (string jobName, SPService service, SPServer server, SPJobLockType targetType)
   9:        : base (jobName, service, server, targetType) {
  10:      }
  12:      public TaskLoggerJob (string jobName, SPWebApplication webApplication)
  13:        : base (jobName, webApplication, null, SPJobLockType.ContentDatabase) {
  14:        this.Title = "Task Logger";
  15:      }
  17:      public override void Execute (Guid contentDbId) {
  18:        // get a reference to the current site collection's content database
  19:        SPWebApplication webApplication = this.Parent as SPWebApplication;
  20:        SPContentDatabase contentDb = webApplication.ContentDatabases[contentDbId];
  22:        // get a reference to the "Tasks" list in the RootWeb of the first site collection in the content database
  23:        SPList taskList = contentDb.Sites[0].RootWeb.Lists["Tasks"];
  25:        // create a new task, set the Title to the current day/time, and update the item
  26:        SPListItem newTask = taskList.Items.Add();
  27:        newTask["Title"] = DateTime.Now.ToString();
  28:        newTask.Update();
  29:      }
  30:    }
  31:  }

As you can see, this job does nothing important but add a new item to a Task list every time it’s executed. Now that you have the job built, you need to get it registered. Unfortunately the only way to do this is through code, but it sure would be one heck of a candidate for a custom STSADM command. Anyway, since we don’t have that today, I like to use the feature activated & deactivated events to install/uninstall my custom jobs.

To do this, you have to create another class that inherits from the Microsoft.SharePoint.SPFeatureReceiver class and implement the FeatureActivated & FeatureDeactivated event handlers like so:

   1:  namespace AndrewConnell.TaskLogger {
   2:    class TaskLoggerJobInstaller : SPFeatureReceiver {
   3:      const string TASK_LOGGER_JOB_NAME = "TaskLogger";
   4:      public override void FeatureInstalled (SPFeatureReceiverProperties properties) {
   5:      }
   7:      public override void FeatureUninstalling (SPFeatureReceiverProperties properties) {
   8:      }
  10:      public override void FeatureActivated (SPFeatureReceiverProperties properties) {
  11:        SPSite site = properties.Feature.Parent as SPSite;
  13:        // make sure the job isn't already registered
  14:        foreach (SPJobDefinition job in site.WebApplication.JobDefinitions) {
  15:          if (job.Name == TASK_LOGGER_JOB_NAME)
  16:            job.Delete();
  17:        }
  19:        // install the job
  20:        TaskLoggerJob taskLoggerJob = new TaskLoggerJob(TASK_LOGGER_JOB_NAME, site.WebApplication);
  22:        SPMinuteSchedule schedule = new SPMinuteSchedule();
  23:        schedule.BeginSecond = 0;
  24:        schedule.EndSecond = 59;
  25:        schedule.Interval = 5;
  26:        taskLoggerJob.Schedule = schedule;
  28:        taskLoggerJob.Update();
  29:      }
  31:      public override void FeatureDeactivating (SPFeatureReceiverProperties properties) {
  32:        SPSite site = properties.Feature.Parent as SPSite;
  34:        // delete the job
  35:        foreach (SPJobDefinition job in site.WebApplication.JobDefinitions) {
  36:          if (job.Name == TASK_LOGGER_JOB_NAME)
  37:            job.Delete();
  38:        }
  39:      }
  40:    }
  41:  }

Now… to get it working, all you need to do is:

  1. Deploy the strongly named assembly to the GAC.
  2. Reset IIS (required for SharePoint to “see” the new timer job in the GAC).
  3. Create a feature specifying the receiver class and assembly that contains the event receivers.
  4. Install the feature.
  5. Activate the feature.

This sample timer job assumes it’s running within the context of a WSS v3 site that has a list created with the Tasks list template in the root web within the site collection (or, just create a Team Site at the root of your site collection).

Once you activate the feature, it should show up on the Timer Job Definitions page in Central Administration / Operations. It won’t appear in the Timer Job Status page until it’s executed at least one time. Wait for five minutes or so (the schedule this sample is using) to see if it’s running. You should start to see items showing up in the Tasks list in the root site in your site collection.

Here’s a Visual Studio 2005 solution that includes everything you need to create a custom timer job. Note that I used the technique I described in this article to modify the Visual Studio project to create the WSP file for me:


Or, you can use this Windows SharePoint Solution Package (*.WSP) to deploy the prebuilt timer job used in this article (handles steps 1-4 above):

» (unpack the ZIP to get the WSP)

To deploy the WSP file, simply add it to the solution store using STSADM (using the following command) and then deploy it to the desired site:

stsadm –o addsolution –filename AndrewConnell.TaskLoggerJob.wsp

Note: if you plan to test the timer job attached in that article, please make sure you also uninstall it. I just realized I never uninstalled mine and my Tasks list had over 30,000 items in it from the last few weeks. Oops! 🙂

No Comments



而家隻手好返好多 , 無咁痛喇…

多謝堂妹妹陪我呢~ 有你照顧好好多~^^

聽日去microsoft tech-ed, 去見識下~!~!~!

No Comments

Creating Hierarchical Menus with a CustomAction in SharePoint

Creating Hierarchical Menus with a CustomAction in SharePoint

It’s a fairly known technique to make use of CustomActions to add elements to the out-of-the-box user interface of SharePoint: you can add menu items to the Site Actions menu, you can add links on the Site Settings page, etc. The following piece of XML is the manifest of a feature that will add a new menu item to the Site Actions menu:

<Elements xmlns=”“>
Title=”Dummy Menu Item”>

For a more detailed description of CustomActions, I recommend following articles:

Another variation on this technique is to provide a reference to a class, instead of having fixed UI element specified in the XML. The following piece of XML points to the class ListSettingsMenu in the DemoCustomAction assembly.

<Elements xmlns=””>

The cool thing is that you now can write code that will render the UI element; it’s even possible to create a hierarchical menu. The following implementation of the ListSettingsMenu class, in combination with the XML from above, is adding one extra menu item to the Site Actions menu (List Settings). This new menu item will contain a sub menu item for every list on the site, these sub menu items will point to the settings pages of the corresponding lists. The ListSettingsMenu class inherits from the WebControl class, by overriding the CreateChildControls method, you can instantiate SubMenuTemplate and MenuItemTemplate instances, and add them to the Controls collection. An instance of the SubMenuItemTemplate class corresponds with a menu item that contains sub menu items. These sub menu items are instances of the MenuItemTemplate class. By setting the Text, Description and ImageUrl properties of these classes, you can specify how the menu items will be rendered in the SharePoint UI. The ClientOnClickNavigateUrl of the MenuItemTemplate class specifies the URL for the menu item itself.

namespace DemoCustomAction
public class ListSettingsMenu: System.Web.UI.WebControls.WebControl
protected override void CreateChildControls()
SubMenuTemplate listSettings = new SubMenuTemplate();
listSettings.Text = “List Settings”;
listSettings.Description = “Manage settings for lists on this site”;
listSettings.ImageUrl = “/_layouts/images/lg_ICASCX.gif”;

foreach (SPList list in SPContext.Current.Web.Lists)
if (!list.Hidden)
MenuItemTemplate listItem = new MenuItemTemplate();
listItem.Text = list.Title;
listItem.Description = string.Format(
“Manage settings for {0}”, list.Title);
listItem.ImageUrl = list.ImageUrl;

string url = string.Format(
SPContext.Current.Web.Url, list.ID.ToString());
listItem.ClientOnClickNavigateUrl = url;



To deploy all of this first of all the assembly (DLL) that contains the ListSettingsMenu should be built and copied either to the Global Assembly Cache or the BIN folder of the SharePoint site where you’d like to use it. Secondly the feature should be installed by copying the feature files and running STSADM -o installfeature -n featurename. Finally a SafeControl element must be added to the web.config, so the ListSettingsMenu control is marked as safe. If you forget the last step, you won’t get an error, but the extra menu item won’t be rendered. Here is a screenshot of the result:

The only caveat for this technique seems to be that you can’t use it to add a hierarchical menu in a EditControlBlock (ECB) CustomAction. The menu items of the ECB are rendered using Javascript. If you want to see a full blown example of what you can accomplish, check out the latest addition to the SmartTools project: the Enhanced Site Actions menu.

No Comments