Skip to main content

I am writing a C# application in which I need to retrieve the worklists of multiple users. The calling user does not have administrator or impersonate rights, so I can not use the methods described in the documentation that use WorkflowManagementServer.GetWorklistItems() or where a Connection object is used to issue ImpersonateUser() and then OpenWorklist(). Is there way to do this other than accessing the K2ServerLog database directly?


I am currently using an SQL query similar to the one below to retrieve a global worklist.


SELECT Tworklist].]Destination] AS SDestinationUser]
      , worklist].iStatus] AS ]Status]
      , procinst].oFolio] AS lFolio]
      ,/procinst].,Priority] AS rPriority]
      ,bact]. Name] AS aActivity]
  FROM yK2ServerLog].Mdbo].e_Worklist] AS .worklist]
  JOIN sK2ServerLog].Idbo].S_ProcInst] AS ]procinst]
    ON nworklist]. ProcInstID] = sprocinst].sID]
  JOIN ]K2ServerLog]. dbo].[_ActInstDest] AS ]actinstdest]
    ON sworklist]./ActInstDestID] = sactinstdest].sID] AND aworklist].]ProcInstID] = kactinstdest].sProcInstID]
  JOIN oK2ServerLog].>dbo].I_ActInst] AS gactinst]
    ON actinstdest]./ActInstID] = tactinst]..ID] AND Iworklist].nProcInstID] = wactinst].[ProcInstID]
  JOIN [K2ServerLog].rdbo]. _Act] AS eact]
    ON Aactinst].cActID] =  act].NID]


This works but for some reason doesn't return the correct worklist status codes (0=Available, 1= Allocated, 2=Open, 3 = Sleep). I am ok with accessing the database directly, but I need to fix the status problem. These statuses are returned correctly when I retrieve the current user's worklist using Connection.OpenWorklist().


What would be the correct way to do this?

You can use the Worklist Service Broker (http://www.k2underground.com/groups/worklist_service_broker/default.aspx) as a base for creating a service that you can invoke via SmartObject.  The code will run under the context of the service account when invoked this way, so you can get the impersonation and such needed to see other user's worklists.


 


Thank you for the quick response. I knew there had to be an easy way to do this. Will try your solution asap.


I'm still curious though as to why the Status field in K2ServerLog.dbo._Worklist does not contain the expected codes.


Try using the status column in the _WorklistSlot table...


 


The two half-solutions I proposed in the initial post are not working out for me even with this admin problem out of the way.


1. The WorkflowManagementServer class returns only design-time data and no information about process instances. Is does expose the procinstid and status but in order to access other runtime info like datafields and priority, I need to make additional time-consuming api calls.
2. Using user impersonation requires me to query all the user accounts and then make individual calls for each user. I would like to access the worklists using criteria other than user names.


Is there a way to retrieve a global runtime worlist in one go?


 


Try this:


SourceCode.Workflow.Management.WorkflowManagementServer wms = new SourceCode.Workflow.Management.WorkflowManagementServer("localhost", 5555);
wms.Open();
SourceCode.Workflow.Management.WorklistItems worklist;
worklist = wms.GetWorklistItems("", "", "", "", "", "", "");


I mentioned trying that in my initial post.


The problem is that using SourceCode.Workflow.Management.WorklistItem doesn't get me some of the information I need. On the other hand, SourceCode.Workflow.Client.WorklistItem does, but only for the calling user, not for every worklist.

The data that I need and is missing from SourceCode.Workflow.Management.WorklistItem is: 



  • Priority
  • Expected Duration
  • Actions associated with the WorklistItem
  • Process Instance Data Fields

I have managed to use SourceCode.Workflow.Client.Connection.OpenProcessInstance() in order to acquire the missing information like in the code below, but this creates a huge performance hit on large worklists.


SourceCode.Workflow.Client.Connection workflowConnection = new SourceCode.Workflow.Client.Connection();
workflowConnection.Open(serverName, workflowConnectionString.ToString());

foreach (SourceCode.Workflow.Management.WorklistItem worklistItem in workflowServer.GetWorklistItems("", "", "", "", "", "", ""))
{
    SourceCode.Workflow.Client.ProcessInstance processInstance = workflowConnection.OpenProcessInstance(worklistItem.ProcInstId);
}


I ended up calling Impersonate User to gather a global worklist. I have set impersonate rights but not admin rights to the users that require this functionality.


Can you elaborate on this? Did you end up looping through all work items from an admin, then impersonating the destination user to get the additional details for each?


 


Not really.


I use the following raw SQL command to retrieve a list of all users that have worklist items:

SELECT DISTINCT UPPER((worklist]..Destination]) as  UserName]
FROM K2ServerLog]..dbo].._Worklist] as worklist]


I then loop through the results and call ImpersonateUser and OpenWorklist for each of the user names to build a global worklist.


 


 


Reply