Using Microsoft Office SharePoint Designer 2007, you can design workflows without writing custom code. Microsoft has provided an article on Create a Workflow which helps you to get started by explaining some key design considerations and providing a basic procedure, but the problem is there are only few limited actions available in SharePoint Designer 2007 to develop your custom workflows (Figure 1).
You can develop custom actions using Microsoft Visual Studio 2005 or higher and deploy in your SharePoint server. Then you will see your custom action when you click More Actions (Figure 1).
In this article I’m going to show you how to add custom actions to SharePoint site and use it in SharePoint Designer 2007 to develop SharePoint workflows. For your ease here I have included all the necessary screen shots and coding step by step.
Building Custom Workflow
First create new project in Microsoft Visual Studio, there select Project Type as workflow and template as Workflow Activity Library (Figure 2). I have given "MyFirstWorkflow" for the name.
Then Add reference to the "Microsoft.SharePoint.dll" and "microsoft.sharepoint.WorkflowActions.dll". They can be found in your SharePoint server’s ISAPI folder (Figure 3 & 4).
You should copy those files from the same directory to a directory on your local computer if you are developing your project on a machine not having SharePoint or MOSS.
Now you can give a name to your Activity, Here I gave "SampleActivity" as Figure 5 and drag-and-drop codeActivity from Toolbox (Figure 6).
Now replace your Activity1.cs file using following code. If you are using different name spaces and class names, you have to change this code according to those names.
using System; using System.ComponentModel; using System.ComponentModel.Design; using System.Collections; using System.Drawing; using System.Linq; using System.Workflow.ComponentModel.Compiler; using System.Workflow.ComponentModel.Serialization; using System.Workflow.ComponentModel; using System.Workflow.ComponentModel.Design; using System.Workflow.Runtime; using System.Workflow.Activities; using System.Workflow.Activities.Rules; using Microsoft.SharePoint; using System.Diagnostics; using Microsoft.SharePoint.Workflow; using Microsoft.SharePoint.WorkflowActions; namespace MyFirstWorkflow { public partial class SampleActivity : SequenceActivity { SPList _list; private EventLog _log; public SampleActivity() { InitializeComponent(); } public static DependencyProperty __ContextProperty = DependencyProperty.Register("__Context", typeof(WorkflowContext), typeof(SampleActivity)); [DescriptionAttribute("__Context")] [BrowsableAttribute(true)] [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)] public WorkflowContext __Context { get { return ((WorkflowContext)(base.GetValue(SampleActivity.__ContextProperty))); } set { base.SetValue(SampleActivity.__ContextProperty, value); } } public static DependencyProperty ListIdProperty = DependencyProperty.Register("ListId", typeof(string), typeof(SampleActivity)); [DescriptionAttribute("ListId")] [BrowsableAttribute(true)] [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)] public string ListId { get { return ((string)(base.GetValue(SampleActivity.ListIdProperty))); } set { base.SetValue(SampleActivity.ListIdProperty, value); } } public static DependencyProperty ListItemProperty = DependencyProperty.Register("ListItem", typeof(int), typeof(SampleActivity)); [DescriptionAttribute("ListItem")] [BrowsableAttribute(true)] [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)] public int ListItem { get { return ((int)(base.GetValue(SampleActivity.ListItemProperty))); } set { base.SetValue(SampleActivity.ListItemProperty, value); } } protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext) { _log = new EventLog("Add Description"); _log.Source = "Share Point Workflows"; try { //Execute method as a elevated method SPSecurity.CodeToRunElevated elevatedExecuteMethod = new SPSecurity.CodeToRunElevated(ExecuteMethod); SPSecurity.RunWithElevatedPrivileges(elevatedExecuteMethod); } catch (Exception ex) { _log.WriteEntry("Error" + ex.Message.ToString(), EventLogEntryType.Error); } return ActivityExecutionStatus.Closed; } private void ExecuteMethod() { try { //retrieveing the Site object SPSite _site = new SPSite(__Context.Site.Url); //retrieveing the Web object SPWeb _web = (SPWeb)(__Context.Web); //retrieveing the list object _list = _web.Lists[new Guid(this.ListId)]; //retrieveing the list item object SPListItem _listItem = _list.GetItemById(this.ListItem); _site.AllowUnsafeUpdates = true; _web.AllowUnsafeUpdates = true; _listItem["Description"] = "This is sample description"; _listItem.Update(); _list.Update(); _site.AllowUnsafeUpdates = false; _web.AllowUnsafeUpdates = false; } catch (Exception ex) { } } } }In the above code you can see some methods to get the current Site, Web, List and List Item. You don’t need to change those things. In the above simple example I have fill the "Description" column using my custom action written inside the "ExecuteMethod()" method. You can write any custom event which cannot be done using given actions in SharePoint designer.
Signing your Project
To deploy this custom workflow to GAC and the Microsoft Office SharePoint Server, we should assign a Strong Name key and sign the control.
To do this, right click the "MyFirstWorkflow" node in Solution Explorer and select Properties. Then select the Signing tab from the choices on the left. Check the "Sign the assembly" box and select from the "Choose a strong name key file" drop down list (Figure 7).
There give a key file name and click ok. Now you can build your project and ready to deploy.
Deploying to Server
To deploy your custom workflow action to the SharePoint server, follow these simple steps.
Drag and drop the compiled DLL (You can find it in your project folder's bin folder) into the Global Assembly Cache. The Global Assembly Cache is a special folder located at %WINDIR%\assembly where %WINDIR% is the full path to your Windows folder (e.g. C:\Windows or C:\Winnt).
Get the publicKeyToken property of our assembly. You can find it by right click on the file and select properties in "assembly" folder (Figure 8).
Update the "web.config file" by inserting fillowing line between <authorizedTypes> and </authorizedTypes> tags. (You can find your site’s web.config file in SharePoint server’s "C:\Inetpub\wwwroot\wss\VirtualDirectories\<your_site_port>" directory).
<authorizedtype Assembly="MyFirstWorkflow, Version=1.0.0.0, Culture=neutral, PublicKeyToken=8f2766b10f337a33" Namespace="MyFirstWorkflow" TypeName="*" Authorized="True" />Update the WSS.ACTIONS file by adding following line between
<Actions Sequential="then" Parallel="and"> and </Actions> tags. (You can find WSS.ACTIONS file in SharePoint server’s "C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\1033\Workflow" directory).
<action Name="Add Description" ClassName="MyFirstWorkflow.SampleActivity" Assembly="MyFirstWorkflow, Version=1.0.0.0, Culture=neutral, PublicKeyToken=8f2766b10f337a33" AppliesTo="all" Category="Extras"> <ruledesigner Sentence="Add Description to %1"> <fieldbind Field="ListId,ListItem" Text="this list" Id="1" DesignerType="ChooseListItem" /> </RuleDesigner> <parameters> <parameter Name="__Context" Type="Microsoft.SharePoint.WorkflowActions.WorkflowContext" Direction="In" /> <parameter Name="ListId" Type="System.String, mscorlib" Direction="In" /> <parameter Name="ListItem" Type="System.Int32, mscorlib" Direction="In" /> </Parameters> </Action>Now deploying is completed, reset IIS and you can use your newly added custom action in the SharePoint Designer by going to "More Actions…" (Figure 1) when creating a workflow.
If you want more details on how to use custom actions when creating workflows follow my article "Use custom actions in SharePoint Designer".
Thanks for sharing, worked perfectly !
ReplyDeleteYou are welcome !
ReplyDeleteMy workflow is completed,But i didnt get any description.
ReplyDeleteHi saritha,
ReplyDeleteDid you refresh the page and check the result ?
In the above example in ExecuteMethod() I'm adding description for the Task list item. Task list has default Description column. If you are going to add this workflow action for another list, you have to add "Description" column for that list.
Hi Saranga - I already have Description column defined.The problem is my workflow doesn't start automatically .I need to start it manually.Finally i got it.Thanks .Can you tell me how to avoid this manual start.
ReplyDeleteSaranga -As I said earlier .I developed sam action for managing permissions but I could not run it can you give me one to manage permissions for list items in a list based on groups.
ReplyDeleteHi Saritha,
ReplyDeleteBy setting the start option of the workflow you can make it automatic. Please check the second figure of my article on Use Custom Workflow Actions in SharePoint Designer.
I’m not sure that I understood your second question well. In my previous article on SharePoint User Groups I have described how to check whether the current user in a particular group. Is that you want to do ?
Hi Saranga - Iknow that.Did same as it is.but then my workflow doesn't start automatically need to run everytime manually.
ReplyDeleteHi Saritha,
ReplyDeleteIf you make it automatic then it should be work. Please let me know whether you give any condition when you are designing?
Hi -Can i have you email id .I am trying to reach you but cant post my comment here.
ReplyDeleteThanks
saranga.rathnayake@gmail.com
ReplyDeleteYou can reach me using above mail
thanks.
Please give me sharepoint designer 2007 free download tutorials link.
ReplyDeleteThank you
Hi Srikanth,
ReplyDeleteHere you can learn most of the stuff,
http://office.microsoft.com/en-us/sharepointdesigner/HA102199841033.aspx
Thank you Saranga Rathnayake.
ReplyDeleteHello, I did everything exactly like you said, but when I select the custom action in the SP Designer the sentece doesn't appear. Do I have to configure something?
ReplyDeleteThank you very much.
Please do the IIS reset and check, this must be work.
ReplyDeletethanks !
I reseted the IIS and restarted the server, and the same error continues. I don't know what to do, I look out in other sites, but nobody knows the resolution.
ReplyDeleteIn this one: http://www.johnholliday.net/post/2007/03/27/Add-Your-Own-Custom-Workflow-Activities-to-SharePoint-Designer-2007.aspx
There are some people in the same situation.
Thank you.
Thank you Saranga. That was really helpful! Works like a champ. Thanks man
ReplyDeletethe only change i had to do was to deploy the DLL to the SharePoint folder: C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\ISAPI
ReplyDeleteHello again. I tried everything to solve my problem, but I couldn't do it. Maybe I have a information to help you to solve my problem. I created a custom workflow action, and deploy in a VM, and the problem was there. So, I tried to deploy the custom action in a development server, and it works, I did exactly the samething, but in the Virtual Machine it doesn't work.
ReplyDeleteCan you help me?
Thank you.
Hi Xokito,
ReplyDeleteI have only tried this in a development server, sorry for that. Check the latest Anonymous comment to this post. Please try that and see.
If you solve this problem, please kind enough to update me.
Thanks !
Hello Saranga,
ReplyDeleteI, finally, solved the problem. Actualy, I made a huge mistake, I was editing the wrong web.config. My virtual machine has the main sharepoint site, and others site collections in another locations. I edited the main web.config, and I was trying to implement a custom activity in a workflow in a diferent web site. Now I edited the right web.config, and I can create a custom activity. And I can do the principal quest: Debug The Custom Activity.
Thank you very much for the pacience
I have created custom forms for adding/Updating List items for a particular List. I have a simple workflow which sends a mail to the user, once an item is added/modified in the List. The workflow is getting trigerred if I add an Item manually through Edit DataSheet view, but not getting triggered if a item is inserted/updated through Custom forms I created. Any idea what needs to be done to fix this?
ReplyDelete@ Xokito,
ReplyDeleteIt is OK, thanks !
Saranga, IS it possible to debug the solution
ReplyDeleteHi Ajith,
ReplyDeleteThere is no way to debug the final solution. As a alternative you can create separate console project and debug ExecuteMethod(). Then merge the code and try.
thanks !
Hi Saranga,
ReplyDeleteI did the same way for one of my custom workflow action. It lists in the more actions but when i click on that it doesn't show any options.
Below is the action tags i have framed in WSS.Actions
Please let me know if i need to do any other modifications to this
Hi Shabbir,
ReplyDeleteNote here;
ruledesigner Sentence="Add Description to %1"
Do you have the "%" mark before 1?
thanks !
Hi Saranga
ReplyDeleteI am create a workflow his action is automatically fire but nothing is happen.
@ Anonymous,
ReplyDeletePlease check whether you add the correct value for PublicKeyToken(line 4) when you update WSS.ACTIONS file.
hi Saranga,
ReplyDeleteI am trying to create a workflow which is supposed to satrt only when AssignedTo field is not blank; Status is not completed and when the names in Assigned To and Modified To fields are different.
I am able to get it working but this is happening almost always. The only condition it is checking is AssignedTo field is not blank.
Can you please help me with this...
Not very sure if you check this portal always....please find a similar post sent to your mail also.
@ Priyanka,
ReplyDeleteI'll send you a reply to your email.