This article will explore how to call a standard K2.net 2003 Collaboration Tools for Microsoft SharePoint Products & Technologies Workflow process from a custom workflow process, without using Microsoft SharePoint event handling, by means of an Inter Process Call (IPC).

Introduction

K2.net 2003 Collaboration Tools has the following standard K2.net 2003 processes:

  • Configured Workflow
  • CopyDocument
  • DeleteDocument

In this article we will use as an example a process that will by means of an Inter Process Call (IPC), call the K2.net 2003 collaboration process as defined within Microsoft SharePoint. This process is defined by means of an XML document within the Configure Workflow process. In order for this process to execute correctly, the original XML for the K2.net 2003 Collaboration Tools defined process must be contained within the custom process that will be calling the K2.net 2003 Collaboration Tools process. In other words, the IPC will have to emulate the "Submit to Workflow" event by passing the exact same data to the Configured Workflow process as what the event would have if the process was started from the event. In order for this to happen, the following information and code will be required:

EventDetail XML data

The EventDetail XML data structure that is contained in the Configured Workflow process must exist in the custom K2.net 2003 process that will be starting the K2.net 2003 Collaboration Tools process. This XML data field must be set prior to the IPC with the correct data, otherwise the IPC will fail.

The EventDetail XML contains the K2.net 2003 Collaboration Tools "process definition" as defined within Microsoft SharePoint. It is necessary to generate this XML within the custom process and to pass this information to the K2.net 2003 Collaboration Tools process. The following defines the EventDetail XML that must be contained within the custom K2.net process:

 

<EventData>
< EventType/>
< ServerUrl/>
< SiteFullUrl/>
< SiteRelativeUrl/>
< DocumentLibrary/>
< DocumentLibraryRelativeUrl/>
< DocumentLibraryFullUrl/>
< FileName/>
< FileRelativeUrl/>
< FileFullUrl/>
< Fields>
<  Field Title=""/>
< /Fields>
</EventData>

 

To set the above XML data structure, place the following code in a server event just before the IPC event that will start the K2.net 2003 Collaboration Tools process:


C#:

 

//update the eventdetail XML field
System.Xml.XmlDocument ConfigField = new System.Xml.XmlDocument();
//load some XML since this value will be blank
ConfigField.LoadXml(K2.ProcessInstance.XmlFields["EventDetail"].MetaData.ToString());
 
//Please take special note of the following line:
// This defines the EVENT HANDLER NAME

ConfigField.SelectSingleNode("EventData/EventType").InnerText = "Manual";
 
//load the attacheddocuments xml field to retireve info from there
System.Xml.XmlDocument AttachedDocsField = new System.Xml.XmlDocument();
AttachedDocsField.LoadXml(K2.ProcessInstance.XmlFields["AttachedDocuments"].Value.ToString());
string server = AttachedDocsField.SelectSingleNode("spsdocuments/documents/document/server").InnerText;
string site = AttachedDocsField.SelectSingleNode("spsdocuments/documents/document/site").InnerText;
string folder = AttachedDocsField.SelectSingleNode("spsdocuments/documents/document/folder").InnerText;
 
ConfigField.SelectSingleNode("EventData/ServerUrl").InnerText = server;
ConfigField.SelectSingleNode("EventData/SiteFullUrl").InnerText = server + @"/" + site;
ConfigField.SelectSingleNode("EventData/SiteRelativeUrl").InnerText = @"/" + site;
 
ConfigField.SelectSingleNode("EventData/DocumentLibrary").InnerText = folder;
ConfigField.SelectSingleNode("EventData/DocumentLibraryRelativeUrl").InnerText = ConfigField.SelectSingleNode("EventData/SiteRelativeUrl").InnerText + @"/" + folder;
ConfigField.SelectSingleNode("EventData/DocumentLibraryFullUrl").InnerText = ConfigField.SelectSingleNode("EventData/SiteFullUrl").InnerText + @"/" +folder;
 
//get the filename of the new file
string filename = K2.ProcessInstance.DataFields["DocumentName"].Value.ToString(); 
ConfigField.SelectSingleNode("EventData/FileName").InnerText = filename;
ConfigField.SelectSingleNode("EventData/FileRelativeUrl").InnerText = ConfigField.SelectSingleNode("EventData/DocumentLibraryRelativeUrl").InnerText + @"/" + filename;
ConfigField.SelectSingleNode("EventData/FileFullUrl").InnerText = ConfigField.SelectSingleNode("EventData/DocumentLibraryFullUrl").InnerText + @"/" + filename;
 
//update the Fields value with each datafield in the process
for (int i = 0; i <= K2.ProcessInstance.DataFields.Count - 1; i++)
{
 string FieldName = K2.ProcessInstance.DataFields[i].Name;
 try
 {
// If Value Not found Continue
string FieldValue = K2.ProcessInstance.DataFields[FieldName].Value.ToString();
System.Xml.XmlNode oXmlElement = ConfigField.CreateNode(System.Xml.XmlNodeType.Element, "Field", "");
oXmlElement.InnerText = FieldValue;
oXmlElement.Attributes.Append(ConfigField.CreateAttribute("", "Title", ""));
oXmlElement.Attributes["Title"].Value = FieldName;
ConfigField.SelectSingleNode("EventData/Fields").AppendChild(oXmlElement); 
}
catch
{
}
}
 
K2.ProcessInstance.XmlFields["EventDetail"].Value = ConfigField.OuterXml;
 
string CurrentConfiguration = String.Empty;
 
//retrieve the configured workflow for the library from the SPS list
string CurrentSPSServer = ConfigField.SelectSingleNode("EventData/ServerUrl").InnerText;
string CurrentWSSSite = ConfigField.SelectSingleNode("EventData/SiteRelativeUrl").InnerText;
string CurrentDL = ConfigField.SelectSingleNode("EventData/DocumentLibrary").InnerText;
string CurrentEvent = ConfigField.SelectSingleNode("EventData/EventType").InnerText;
 
Console.WriteLine("______________*********Site relative URL " + CurrentWSSSite);
 
If(!SourceCode.SharePointWorkflowServices2005.SpsListHelper.FindWorkflowConfiguration(ref K2, ref CurrentConfiguration, CurrentSPSServer, CurrentWSSSite, CurrentDL, CurrentEvent).Equals(String.Empty))
{
 K2.ProcessInstance.XmlFields["Configuration"].Value = CurrentConfiguration;

else
{
 Console.WriteLine("_____________******** Config not found");
}

 

VB:

'update the eventdetail XML field 
Dim ConfigField As System.Xml.XmlDocument = New System.Xml.XmlDocument

'load some XML since this value will be blank
ConfigField.LoadXml(K2.ProcessInstance.XmlFields("EventDetail").MetaData.ToString())
'Please take special note of the following line:
 This defines the EVENT HANDLER NAME
ConfigField.SelectSingleNode("EventData/EventType").InnerText = "Manual"
'load the attached documents xml field to retireve info from there
Dim AttachedDocsField As System.Xml.XmlDocument = New System.Xml.XmlDocument

AttachedDocsField.LoadXml(K2.ProcessInstance.XmlFields("AttachedDocuments").Value.ToString())
Dim server As String =
AttachedDocsField.SelectSingleNode("spsdocuments/documents/document/server").InnerText
Dim site As String =
AttachedDocsField.SelectSingleNode("spsdocuments/documents/document/site").InnerText
Dim folder As String =
AttachedDocsField.SelectSingleNode("spsdocuments/documents/document/folder").InnerText
ConfigField.SelectSingleNode("EventData/ServerUrl").InnerText = server
ConfigField.SelectSingleNode("EventData/SiteFullUrl").InnerText = server + "/"+ site
ConfigField.SelectSingleNode("EventData/SiteRelativeUrl").InnerText = "/" + site
ConfigField.SelectSingleNode("EventData/DocumentLibrary").InnerText = folder
ConfigField.SelectSingleNode("EventData/DocumentLibraryRelativeUrl").InnerText = ConfigField.SelectSingleNode("EventData/SiteRelativeUrl").InnerText + "/" + folder
ConfigField.SelectSingleNode("EventData/DocumentLibraryFullUrl").InnerText = ConfigField.SelectSingleNode("EventData/SiteFullUrl").InnerText + "/" + folder
'get the filename of the new file

Dim filename As String = K2.ProcessInstance.DataFields("DocumentName").Value.ToString()
ConfigField.SelectSingleNode("EventData/FileName").InnerText = filename
ConfigField.SelectSingleNode("EventData/FileRelativeUrl").InnerText = ConfigField.SelectSingleNode("EventData/DocumentLibraryRelativeUrl").InnerText + "/" + filename
ConfigField.SelectSingleNode("EventData/FileFullUrl").InnerText = ConfigField.SelectSingleNode("EventData/DocumentLibraryFullUrl").InnerText + "/" + filename
'update the Fields value with each datafield in the process
 
Dim i As Integer
For i = 0 To K2.ProcessInstance.DataFields.Count - 1
Dim FieldName As String = K2.ProcessInstance.DataFields(i).Name
Try
' If Value Not found Continue
Dim FieldValue As String = K2.ProcessInstance.DataFields(FieldName).Value.ToString()
Dim oXmlElement As System.Xml.XmlNode = ConfigField.CreateNode(System.Xml.XmlNodeType.Element, "Field", "")
oXmlElement.InnerText = FieldValue
oXmlElement.Attributes.Append(ConfigField.CreateAttribute("", "Title", ""))
oXmlElement.Attributes("Title").Value = FieldName
ConfigField.SelectSingleNode("EventData/Fields").AppendChild(oXmlElement)
Catch
End Try
Next K2.ProcessInstance.XmlFields("EventDetail").Value = ConfigField.OuterXml Dim CurrentConfiguration As String = String.Empty 'retrieve the configured workflow for the library from the SPS list
Dim CurrentSPSServer As String = ConfigField.SelectSingleNode("EventData/ServerUrl").InnerText
Dim CurrentWSSSite As String = ConfigField.SelectSingleNode("EventData/SiteRelativeUrl").InnerText
Dim CurrentDL As String = ConfigField.SelectSingleNode("EventData/DocumentLibrary").InnerText
Dim CurrentEvent As String = ConfigField.SelectSingleNode("EventData/EventType").InnerText Console.WriteLine("______________*********Site relative URL " + CurrentWSSSite) If Not (SourceCode.SharePointWorkflowServices2005.SpsListHelper.FindWorkflowConfiguration(K2, CurrentConfiguration, CurrentSPSServer, CurrentWSSSite, CurrentDL, CurrentEvent).Equals(String.Empty)) Then
K2.ProcessInstance.XmlFields("Configuration").Value = CurrentConfiguration
Else
Console.WriteLine("_____________******** Config not found")
End If

What is important to note in the above code is the following:

C#:

 

SourceCode.SharePointWorkflowServices2005.SpsListHelper.FindWorkflowConfiguration( ref K2, ref CurrentConfiguration, CurrentSPSServer, CurrentWSSSite, CurrentDL, CurrentEvent)

 

VB:

 

SourceCode.SharePointWorkflowServices2005.SpsListHelper.FindWorkflowConfiguration(K2, CurrentConfiguration, CurrentSPSServer, CurrentWSSSite, CurrentDL, CurrentEvent)

 

This code retrieves the workflow process definition as defined within SharePoint. The CurrentEvent variable refers to EventData/EventType node in the XML. In this case it is set to "Manual". This refers to a manual configured workflow process. For this document this will always be set to "Manual" as SharePoint events are not available.

Also important to note regarding the above code is that this relies on a string tale entry within the custom process. This string table is called "Configuration List" and the needed value is "WorkflowConfiguration". The above code statement will fail if this string table is not set up. The function uses the string table internally and therefore cannot function without the string table available.

The AttachedDocuments XML is important for the configured workflow to have a handle on the current document(s) that is associated with the process. This XML document is used to populate values within the EventDetail process XML as seen in the previously defined code sample.

After all the necessary XML process data fields have been set, an IPC can be made to the "SharePoint Workflow Services\Configured Workflow" process. The critical XML data that must be set is the EventDetail XML as explained earlier. See the attached process for an example of how this call is made with accompanied data and XML documents.