Saturday, August 30, 2008

SharePoint Best Practices

Guys the Best practices series is available on TechNet worth having a read:

http://technet.microsoft.com/en-us/office/sharepointserver/bb736746.aspx

Friday, August 29, 2008

Burn ISO images on a Virtual CD

Found this great tool which allows us to mount ISO images as Virtual CD's. This saves us time and cost of buying CD's or DVD's. The tool is called as Virtual CD Control Panel. This tool allows you to mount any ISO image onto a virtual CD drive. The steps to install and configure this tool are included in the readme.txt file that comes with the download. You can download it from here:

http://download.microsoft.com/download/7/b/6/7b6abd84-7841-4978-96f5-bd58df02efa2/winxpvirtualcdcontrolpanel_21.exe

How good is that?? No need to buy a CD/DVD. Just mount the tool whenever you need to run the install.

Thursday, August 28, 2008

Attaching SPItemEventReceiver with a List Type

In my last post I have talked about writing an SPItemEventReceiver for fetching a workflow instance out of a Task item in a Task List type. Next step that comes to our mind is how we can attach this event receiver with a List. There are two ways in which you can attach your event receiver to a list type. One is through a feature: in elements.xml file you can write CAML and have Receiver attributes. another way is by using object model. I will explain you both the ways:

1) Feature way:

Create a feature.xml in the normal way as you do for any other feature. Here is the example:



"<"!--Created by Kunal Kochhar at 18/08/2008 10:21:18 AM--">"
"<"Feature Id="66D0E36C-4D48-46D0-90E9-7BFGHFBE4E3C" Title="Item receiver attacher" Description="This feature will attach event handler to a task item generated by Disposition workflow" Version="1.0.0.0" Scope="Web" Hidden="false" ImageUrl="CustomBranding.gif" xmlns="http://schemas.microsoft.com/sharepoint/"">"
"<"ElementManifests">"
"<"ElementManifest Location="elements.xml" /">"
"<"/ElementManifests">"
"<"/Feature">"



Now write the elements.xml file. This file will have Receivers tag. Read here more about Receivers element:

http://msdn.microsoft.com/en-us/library/ms431081.aspx

Let me show you the elements file:

'<'elements xmlns="http://schemas.microsoft.com/sharepoint/"'>'
'<'Receivers ListTemplateId="107"'>'
'<'Receiver'>'
'<'Name'>'TaskAdded'<'/Name'>'
'<'Type'>'ItemAdded'<'/Type'>'
'<'SequenceNumber'>'10043'<'/SequenceNumber'>'
'<'Assembly'>'assemblyname, [full four part]'<'/Assembly'>'
'<'Class'>'namespacename.classname'<'/Class'>'
'<'Data'>''<'/Data'>'
'<'Filter'>''<'/Filter'>'
'<'/Receiver'>'
'<'/Receivers'>'
'<'/Elements'>'



As you can see I am saying ListTemplateId=107 in the Receivers element. This id is the List Template Id for Tasks list type. You can refer to more list template ids here: http://msdn.microsoft.com/en-us/library/ms431081.aspx
Once you deploy and activate this feature on web it will attach your required event handler with all the existing tasks lists or any new ones that you create.

2) Lets see the second approach which is through code. The SPWeb object exposes list templates and contenttypes collections. You can retreive the required list template type and content type and can add your eventreceiver assembly in their eventreceivers collection. Here is an example to add it to a content type:

SPWeb web = SPContext.Current.Web;
SPContentType ct = web.ContentTypes["Tasks"];
SPEventReceiverDefinition receiverDef = ct.EventReceivers.Add();
receiverDef.Name = "Custom_ItemAdded";
receiverDef.Type = SPEventReceiverType.ItemAdded;
receiverDef.SequenceNumber = 10012;
receiverDef.Assembly = "assembly, [full four part assembly details]";
receiverDef.Class = "namespacename.classname";
receiverDef.Update();

I hope this will help some of you. If you have any queries in relation to this then please feel free to write to me.

Wednesday, August 27, 2008

Custom Timer Job

This post is mainly for me to remember on how to create a custom timer job. Thought of posting it anyways if anyone gets benefit out of it. Just saw this post by Andrew Connell on creating a custom timer job and then registering it in FeatureReceiver class:

http://www.andrewconnell.com/blog/articles/CreatingCustomSharePointTimerJobs.aspx

Monday, August 25, 2008

How to get workflow instance of a Task item

This post is about finding which workflow a task item is associated to. For example if you have a workflow setup on a document library which creates a task in a task list everytime that workflow is initiated and you want to do an action further when a task is created. Now this sounds pretty straightforward that you can attach an event handler with a Task list and do the needful. But remember that the particular Task list can be used for many workflows and you want to run your event only for a particular WorkFlow.

What you can do is, Task list exposes few properties which are hidden which tells the exact workflow information. The three properties which are of our interests are:

Workflow List ID (This represents the document library ID from where the workflow was initiated)
Workflow Item ID (This represents the document for which the work flow is initiated)
ows_WorkflowInstanceID (This is the workflow instance id of the workflow that has been setup for document library. This will help us to get the workflow type)

Let me show you a code snippet to get these details:


public override void ItemAdded(SPItemEventProperties properties)
{
try
{

SPListItem taskItem = properties.ListItem;

//Check if the item added is a Workflow related or not
if (taskItem["Workflow List ID"] != null)
{
SPWeb web = properties.OpenWeb();
Guid sourceListID = new Guid(taskItem["Workflow List ID"].ToString());
SPList sourceList = web.Lists.GetList(sourceListID, true);
int sourceListItemID = Convert.ToInt32(taskItem["Workflow Item ID"]);
SPListItem sourceListItem = sourceList.GetItemById(sourceListItemID);


//Get the workflow instance id from Task item
Guid taskWorkflowInstanceID = new Guid(taskItem["ows_WorkflowInstanceID"].ToString());

//Get the workflow object
SPWorkflow wf = sourceListItem.Workflows[taskWorkflowInstanceID ]

//Get the workflow association object
SPWorkflowAssociation wfAss = sourceList.WorkflowAssociations[wf.AssociationId];
try
{
//Check if the associated workflow is of type Disposition Approval
//This GUID will be same in every MOSS install
if (wfAss.BaseId.Equals(new Guid("dd19a800-37c1-43c0-816d-f8eb5f4a4145")))
{
//if the workflow is of type disposition then do your action
}

catch (ArgumentException argex)
{
}
}
}

}

}
catch (SPException spex)
{
}
catch (Exception ex)
{
}

}



You will notice that I am checking the base id of the Workflow Association object this gives us the workflow type which has been setup for the document library. In this case I am checking if the base id is of same type of the Disposition workflow. This GUID will be same in every MOSS install. Now in next post I will tell you how you can attach this event receiver with a Task list template type.

Tuesday, August 19, 2008

Event Handler Explorer Tool

I am sure lot of you must have had problems registering event handlers with list types or content types. There is a very good tool developed by Patrick Tisseghem called as
Event Handler Explorer. This tool allows you to browse and list instances and content types and to attach even handlers manually. This way you will be assured that the event receiver is attached properly.

Thought of sharing this great tool with every one :-)

http://www.u2u.info/SharePoint/U2U%20Community%20Tools/EventHandlerExplorer.zip

Cheers,
Kunal

Sunday, August 17, 2008

Upgrading WSS 2.0 Sites or Site Templates for WSS 3.0

Just came across this Solution Accelerator tool that helps you to upgrade Windows SharePoint Services 2.0 custom sites and templates. It also explains you on what steps and proceudres will be involved in this upgrade process.

http://www.microsoft.com/technet/solutionaccelerators/collaboration/default.mspx