I won't explain here The principle on How to create Custom Activity on Sharepoint 2010, this topic has already been explained several times on the web :
http://www.chaholl.com/archive/2010/03/13/make-a-custom-activity-available-to-sharepoint-designer-2010.aspx or
http://social.msdn.microsoft.com/Forums/en/sharepointworkflow/thread/4e7a77f4-c29b-47b2-a1de-79470f0bb1c9
My plan is just to give you one more action to add to your SPD.
I will just provide you the code for the action file and the bin. I'll leave you the rest of the job.
Here is the action file :
<?xml version="1.0" encoding="utf-8"?>
<WorkflowInfo>
<Actions Sequential="then" Parallel="and">
<Action Name="Attach Doc to Item"
ClassName="AttachMailWFActivity.AttachDocToItem"
Assembly="AttachMailWFActivity, Version=1.0.0.0, Culture=neutral, PublicKeyToken=46f60639ee1bfb57"
AppliesTo="all" Category="List Actions">
<RuleDesigner Sentence="Attach %1 to %2">
<FieldBind Text="this document" Field="LibId,DocItem" DesignerType="ChooseDoclibItem" Id="1" />
<FieldBind Text="this item" Field="ListId,ListItem" DesignerType="ChooseListItem" Id="2"/>
</RuleDesigner>
<Parameters>
<Parameter Name="__Context" Type="Microsoft.SharePoint.WorkflowActions.WorkflowContext, Microsoft.SharePoint.WorkflowActions" Direction="In" />
<Parameter Name="LibId" Type="System.String, mscorlib" Direction="In" InitialBinding="__list"/>
<Parameter Name="DocItem" Type="System.Int32, mscorlib" Direction="In" InitialBinding="__item" DesignerType="ListItem" Description="ID of the list item used by this action." />
<Parameter Name="ListId" Type="System.String, mscorlib" Direction="In"/>
<Parameter Name="ListItem" Type="System.Int32, mscorlib" Direction="In" DesignerType="ListItem" Description="ID of the list item used by this action." />
</Parameters>
</Action>
</Actions>
</WorkflowInfo>
And the code of the AttachMailWFActivity.AttachDocToItem assembly is :
using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections;
using System.Linq;
using System.IO;
using Microsoft.SharePoint;
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 Microsoft.SharePoint.WorkflowActions;
using System.Workflow.Activities.Rules;
namespace TSP.AttachMailWFActivity
{
public partial class AttachDocToItem : Activity
{
public static DependencyProperty LibIdProperty = DependencyProperty.Register("LibId", typeof(string), typeof(AttachDocToItem));
public static DependencyProperty ListIdProperty = DependencyProperty.Register("ListId", typeof(string), typeof(AttachDocToItem));
public static DependencyProperty DocItemProperty = DependencyProperty.Register("DocItem", typeof(Int32), typeof(AttachDocToItem));
public static DependencyProperty ListItemProperty = DependencyProperty.Register("ListItem", typeof(Int32), typeof(AttachDocToItem));
public static DependencyProperty __ContextProperty = DependencyProperty.Register("__Context", typeof(WorkflowContext), typeof(AttachDocToItem));
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[ValidationOption(ValidationOption.Required)]
[Browsable(true)]
[Description("ID of the document library storing the doc that will be attached to the item")]
public string LibId
{
get { return ((string)(base.GetValue(AttachDocToItem.LibIdProperty))); }
set { base.SetValue(AttachDocToItem.LibIdProperty, value); }
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[ValidationOption(ValidationOption.Required)]
[Browsable(true)]
[Description("ID of the list keeping the item to which the document will be attached to")]
public string ListId
{
get { return ((string)(base.GetValue(AttachDocToItem.ListIdProperty))); }
set { base.SetValue(AttachDocToItem.ListIdProperty, value); }
}
[Description("ID of the list item to which the document will be attached to")]
[ValidationOption(ValidationOption.Required)]
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public Int32 ListItem
{
get { return ((Int32)(base.GetValue(AttachDocToItem.ListItemProperty))); }
set { base.SetValue(AttachDocToItem.ListItemProperty, value); }
}
[Description("ID of the document item to which the document will be attached to")]
[ValidationOption(ValidationOption.Required)]
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public Int32 DocItem
{
get { return ((Int32)(base.GetValue(AttachDocToItem.DocItemProperty))); }
set { base.SetValue(AttachDocToItem.DocItemProperty, value); }
}
[Description("Context")]
[ValidationOption(ValidationOption.Required)]
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public WorkflowContext __Context
{
get { return ((WorkflowContext)(base.GetValue(__ContextProperty))); }
set { base.SetValue(__ContextProperty, value); }
}
protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
{
try
{
__Context.Web.AllowUnsafeUpdates = true;
Guid id = new Guid(ListId);
SPList list = __Context.Web.Lists[id];
Guid did = new Guid(LibId);
SPList docLib = __Context.Web.Lists[did];
SPListItem sourceItem = docLib.GetItemById(DocItem);
SPFile sourceDoc = sourceItem.File;
byte[] fichierbyte = sourceDoc.OpenBinary();
SPListItem destinationItem = list.GetItemById(ListItem);
destinationItem.Attachments.Add(sourceItem.Name, fichierbyte);
destinationItem.Update();
return ActivityExecutionStatus.Closed;
}
catch (Exception Ex)
{
return ActivityExecutionStatus.Faulting;
throw new Exception(Ex.Message + "&&&&" + Ex.StackTrace);
}
finally
{
}
return ActivityExecutionStatus.Closed;
}
public AttachDocToItem()
{
InitializeComponent();
}
}
}
Now you've got that.
Just :
- Create a sharepoint 2010 empty project
- Create a class and copy the code
- Create an action file and copy the code
- Sign your assembly
- Package your wsp
- Install the wsp on you WFE. Deploy it.
- Add the correct line in the AuthorizedType tag of your web.config.
The result :
(for the capture... it's because my SPD Is in french)
I hope it helps.
Don't hesitate to contact me whether you are in trouble using it !!!