changes.
| | This is the third part of a four-part series on automating workflow execution within Citrix Workflow Studio. In the first two parts of the series, I discussed how you can create Powershell scripts to execute workflows. [Part 1|http://community.citrix.com/blogs/citrite/edy/2009/06/19/Using+Powershell+to+automate+workflow+execution+within+Citrix+Workflow+Studio] provided a high-level overview of creating Powershell scripts for automating workflow execution and [Part 2|http://community.citrix.com/blogs/citrite/edy/2009/06/26/Passing+parameters+into+a+workflow+within+Citrix+Workflow+Studio] expanded on those scripts to discuss how to pass parameters into the workflow. In this blog, I will discuss how you can automate workflow execution with a custom Windows application. The sample .NET application I built is shown below. I am providing both the executable and full source code to allow you to expand upon this solution to meet the needs of your environment. |
| | !1_CustomApp.JPG|align=left! |
| | |
| | \\ |
| | \\ |
| | |
| | *When would I need to use a custom application for executing workflows?* |
| | A lot of you might be asking the question - "If we can use the Workflow Studio Console to execute workflows, why would I need a custom application to do that for me?". The answer really comes down to how you need to execute certain workflows in your environment. If you need to execute workflows "*on-demand*" or "*on a schedule*", the Workflow Studio Console would meet those needs. Just open the Workflow Studio Console and schedule a job to run immediately or on a pre-determined schedule. However, if you need "*event-driven*" automation where a third-party application kicks off the execution of a workflow based on an event happening, that is where you need to be able to hook into Workflow Studio with a custom solution to perform that type of automation. |
| | |
| | The custom application provided in the *Downloads* section below provides a sample for how you can tie any .NET windows application to Workflow Studio for executing workflows. Feel free to try out the sample application on your Workflow Studio machine. The full source code is also provided to allow you to customize and extend the application further based on what you need to do. |
| | |
| | *Downloads:* |
| | [Download the application executable here|^WFS Application Executable.zip] |
| | [Download the application source code here|^WFS Application Source Code.zip] |
| | * * |
| | |
| | *Preparing your Workflow Studio environment to use the custom application:* |
| | The custom application needs to run on a machine that contains Workflow Studio since it ties into Powershell and calls the Workflow Studio cmdlets for performing various actions on Workflow Studio. In your *Workflow Studio Console*, you will need to pre-deploy the workflow that you want to automate (see [Part 1|http://community.citrix.com/blogs/citrite/edy/2009/06/19/Using+Powershell+to+automate+workflow+execution+within+Citrix+Workflow+Studio] for more information on pre-deploying workflows). The workflow that you want to automate can include parameters as well. Parameters for a workflow are defined in the *Workflow Studio Designer* under the *Global Properties* section (see [Part 2|http://community.citrix.com/blogs/citrite/edy/2009/06/26/Passing+parameters+into+a+workflow+within+Citrix+Workflow+Studio] for more information on defining workflow parameters). |
| | |
| | This custom application functions as any typical Windows application in that it runs under the context of the logged-on user account. The logged-on account needs to have permissions in Workflow Studio to execute workflows. These permissions are defined in the *Security* section of the *Workflow Studio Console*. For simplicity, I typically add the user accounts as a "*Workflow-Admin*", but you can play with the security roles here to determine what roles are actually needed. |
| | !2_SecurityRoles.JPG|align=left! |
| | |
| | \\ |
| | \\ |
| | |
| | *Using the custom application:* |
| | To use the custom application, log onto your Workflow Studio machine with an account that has permissions to execute workflows within Workflow Studio. Place *WFSWorkflowExecute.exe* on your Workflow Studio machine. When you launch the application, the initial view is shown below. |
| | !3_CustomAppBlank.JPG|align=left! |
| | |
| | \\ |
| | \\ |
| | |
| | Click the *Get Runtimes* button to get the Workflow Studio runtimes that are installed on the local machine. The runtimes are listed within the combo-box below and the name of the runtime specifies which account the runtime is running under. |
| | !4_Runtimes.JPG|align=left! |
| | |
| | \\ |
| | \\ |
| | |
| | When a runtime is selected, all of the workflows that are deployed on that runtime are listed as well. To execute a certain workflow, you need to know which runtime you deployed the workflow on. This sample application also provides the version of the workflow as you may have deployed two different versions of the same workflow to the same runtime. Using the version numbers helps you keep them straight. |
| | |
| | When you want to execute a workflow, you need to know if that workflow requires any parameters. The workflow parameters are defined in the *Workflow Studio Designer* in the *Global Properties* section of the workflow. As mentioned above, [Part 2|http://community.citrix.com/blogs/citrite/edy/2009/06/26/Passing+parameters+into+a+workflow+within+Citrix+Workflow+Studio] of this blog series goes into detail on how to define and use parameters inside a workflow. |
| | !5_GlobalProperties.JPG|align=left! |
| | |
| | \\ |
| | \\ |
| | |
| | When specifying workflow parameters inside the custom application, the parameter name is *case sensitive*. (Notice how I kept the parameter name as "gMessage"). If you mistype the parameter name or use the wrong case, you will get an error message when executing the workflow stating that the parameter name is not recognized. Just keep this in mind as you type the name of the parameters into the application. |
| | !6_WorkflowExecute.JPG|align=left! |
| | |
| | \\ |
| | \\ |
| | |
| | Click the *Execute Workflow* button to execute the workflow. If the workflow was successfully executed, you'll get a pop-up message indicating success. |
| | !7_Success.JPG|align=left! |
| | |
| | \\ |
| | \\ |
| | |
| | To verify the workflow was executed, you can open the *Workflow Studio Console* and check out the *Jobs* section.* * !8_JobCompleted.JPG|align=left! |
| | |
| | \\ |
| | \\ |
| | |
| | *Understanding the source code:* |
| | A lot of you out there will want to customize this application in your own environment. I developed this application with *C#* using *Visual Studio 2008* and the *Powershell SDK*. Your development machine will also need *Powershell 1.0* and *Citrix Workflow Studio*. For advice on setting up your Visual Studio environment, check out this [article|http://community.citrix.com/blogs/citrite/edy/2009/05/01/Workflow+Studio+SDK+Series+-+Part+2+-+Setting+up+your+Visual+Studio+development+environment]. If you follow the steps in that article, you'll just need to add the Powershell SDK and you should be all set. |
| | |
| | The Powershell SDK is included as part of the *Windows Software Development Kit*. You can get information on the [Poweshell SDK here|http://msdn.microsoft.com/en-us/library/bb204630(VS.85).aspx]. I downloaded the full ISO and it took me quite a while to get it. When you are ready to install, you don't need everything in the setup wizard. The Powershell SDK link provided above actually tells you what you specifically need to install to just get the Powershell SDK. To use the Powershell SDK inside your Visual Studio project, the project will need to reference *System.Management.Automation.dll*. |
| | |
| | Once you get your development machine set up, you can open the solution that I provided above inside Visual Studio. Essentially all this custom application does is use the Powershell SDK APIs to execute cmdlets on Powershell. Since Workflow Studio provides Powershell cmdlets to automate various tasks, we can use the Powershell SDK to automate many Workflow Studio functions. |
| | |
| | From my personal experience, using the Powershell SDK takes a little time getting used to. What I found to be helpful is to first write out the Powershell commands in Notepad and test them within Powershell to make sure they are functioning as expected. If you are working with Powershell variables, use the *echo* statement frequently to understand the current value of the variable. Then when you are ready to use the Powershell SDK in your Visual Studio project, you can convert each of your Powershell statements to the equivalent Powershell SDK code. In the source code that I provided for this custom application, I put comments into the code to explain what Powershell command I was trying to execute within that code block. Reviewing those comments should help you to get started with understanding how to use the Powershell SDK. For example, here is the *ExecuteWorkflow()* function that is used by the custom application. Stepping through this code inside Visual Studio and watching the variables is another great way to learn this code. |
| | \\ |
| | {code} |
| | public string ExecuteWorkflow(Hashtable objFunctionParameters, Hashtable objWorkflowParameters) |
| | { |
| | try |
| | { |
| | //Declare local variables |
| | string l_strReturn = "Executing workflow"; |
| | string l_strWorkflowName = objFunctionParameters["WorkflowName"].ToString(); |
| | string l_strRuntimeName = objFunctionParameters["RuntimeName"].ToString(); |
| | Hashtable l_objWorkflowParameters = objWorkflowParameters; |
| | |
| | //Create a runspace containing the Workflow Studio snap-ins |
| | RunspaceConfiguration l_objRSConfiguration = RunspaceConfiguration.Create(); |
| | PSSnapInException l_objSnapInException = null; |
| | l_objRSConfiguration.AddPSSnapIn("Citrix.WorkflowStudio.Azman", out l_objSnapInException); |
| | l_objRSConfiguration.AddPSSnapIn("Citrix.WorkflowStudio.Core", out l_objSnapInException); |
| | l_objRSConfiguration.AddPSSnapIn("Citrix.WorkflowStudio.DataStore", out l_objSnapInException); |
| | l_objRSConfiguration.AddPSSnapIn("Citrix.WorkflowStudio.Installer", out l_objSnapInException); |
| | Runspace l_objRunspace = RunspaceFactory.CreateRunspace(l_objRSConfiguration); |
| | l_objRunspace.Open(); |
| | |
| | //Get reference to the Workflow Studio runtime that was passed in. |
| | //We are executing the Powershell command below: |
| | //$rt = Get-WorkflowRuntime -ServiceName $ServiceName |
| | Pipeline l_objPipeLine = l_objRunspace.CreatePipeline(); |
| | Command l_objCommand = new Command("get-workflowruntime"); |
| | l_objCommand.Parameters.Add("ServiceName", l_strRuntimeName); |
| | l_objPipeLine.Commands.Add(l_objCommand); |
| | Collection<PSObject> l_objCommandResults = l_objPipeLine.Invoke(); |
| | PSObject l_objRuntime = l_objCommandResults[0]; |
| | l_objPipeLine = null; |
| | |
| | //Get reference to the deployed workflow that was passed in. |
| | //We are executing the Powershell command below: |
| | //$workflow = get-deployedworkflow -workflowruntime $rt -workflowname $strWorkflowName -includeschedule |
| | l_objPipeLine = l_objRunspace.CreatePipeline(); |
| | l_objCommand = new Command("get-deployedworkflow"); |
| | l_objCommand.Parameters.Add("workflowruntime", l_objRuntime); |
| | l_objCommand.Parameters.Add("workflowname", l_strWorkflowName); |
| | l_objCommand.Parameters.Add("includeschedule"); |
| | l_objPipeLine.Commands.Add(l_objCommand); |
| | l_objCommandResults = l_objPipeLine.Invoke(); |
| | PSObject l_objWorkflow = l_objCommandResults[0]; |
| | l_objPipeLine = null; |
| | |
| | //Schedule the workflow to run immediately. |
| | //We are executing the Powershell command below: |
| | //schedule-workflow -workflowruntime $rt -workflowstrongname $workflow.WorkflowStrongName -workflowparameters $wfparameters -runimmediately |
| | l_objPipeLine = l_objRunspace.CreatePipeline(); |
| | l_objCommand = new Command("schedule-workflow"); |
| | l_objCommand.Parameters.Add("workflowruntime", l_objRuntime); |
| | l_objCommand.Parameters.Add("workflowstrongname", l_objWorkflow.Properties["WorkflowStrongName"].Value.ToString()); |
| | l_objCommand.Parameters.Add("workflowparameters", l_objWorkflowParameters); |
| | l_objCommand.Parameters.Add("runimmediately"); |
| | l_objPipeLine.Commands.Add(l_objCommand); |
| | l_objCommandResults = l_objPipeLine.Invoke(); |
| | l_objPipeLine = null; |
| | |
| | //Close the runspace |
| | l_objRunspace.Close(); |
| | |
| | //Return success |
| | l_strReturn = "Job completed!"; |
| | return l_strReturn; |
| | } |
| | catch (Exception objException) |
| | { |
| | //Initialize error message |
| | string l_strError = ""; |
| | l_strError = "An error has occurred. The error is \"" + objException.Message.ToString() + "\". "; |
| | return l_strError; |
| | } |
| | } |
| | {code}\\ |
| | *Blogs in this series:* |
| | [Using Powershell to automate workflow execution within Citrix Workflow Studio|http://community.citrix.com/blogs/citrite/edy/2009/06/19/Using+Powershell+to+automate+workflow+execution+within+Citrix+Workflow+Studio] |
| | [Passing parameters into a workflow within Citrix Workflow Studio|http://community.citrix.com/blogs/citrite/edy/2009/06/26/Passing+parameters+into+a+workflow+within+Citrix+Workflow+Studio] |
| | Automating workflow execution for Citrix Workflow Studio using a .NET windows application (_this one_) |
| |  | Automating workflow execution for Citrix Workflow Studio using an ASP.NET web application |
| | | [Automating workflow execution for Citrix Workflow Studio using an ASP.NET web application|http://community.citrix.com/blogs/citrite/edy/2009/07/02/Automating+workflow+execution+for+Citrix+Workflow+Studio+using+an+ASP.NET+Web+application] |
| | \\ |
| | \\ |
| | \\ |
| | \\ |
| | \\ |
| | \\ |
 | | \\ |