// In this function the activity action is performed private void PerformWork(ActivityActionData data) { bool failed = false; Exception exception = null; try { // setting up the streams data.command.Streams.Debug = data.streams.DebugStream; data.command.Streams.Error = data.streams.ErrorStream; data.command.Streams.Progress = data.streams.ProgressStream; data.command.Streams.Verbose = data.streams.VerboseStream; data.command.Streams.Warning = data.streams.WarningStream; // Custom WinRM Workflow Endpoint details // run CustomWorkflowEndpointSetup.ps1 in Powershell console as administrator, if you have not done. // WSManConnectionInfo connectionInfo = new WSManConnectionInfo(); connectionInfo.ShellUri = "http://schemas.microsoft.com/powershell/CustomeWorkflowEndpoint"; // Create runspace pool on custom workflow endpoint where command will be invoked using (RunspacePool r = RunspaceFactory.CreateRunspacePool(1, 1, connectionInfo)) { try { r.Open(); data.command.RunspacePool = r; // now executing the powershell command. data.command.Invoke(data.streams.InputStream, data.streams.OutputStream, new PSInvocationSettings()); } finally { r.Close(); r.Dispose(); } } } catch (Exception e) { // since work is getting performed on background thread so there should not be any exception. failed = true; exception = e; } // Now since activity action has already been performed so now we need to resume the execution of the // workflow. This will be done by PSWorkflowJob job = _runtime.JobManager.GetJob(data.jobInstanceId); // Now resuming the job if (failed) { job.ResumeBookmark(data.bookmark, this.SupportDisconnectedPSStreams, data.streams, exception); } else { job.ResumeBookmark(data.bookmark, this.SupportDisconnectedPSStreams, data.streams); } }
// the servicing thread will execute this function to perform the activity action. private void ServiceRequests(object state) { Guid jobInstanceId = (Guid)state; ActivityActionData actiondata = null; ActivityActionsQueue.TryRemove(jobInstanceId, out actiondata); if (actiondata != null) { // the work is getting perform here PerformWork(actiondata); } }
// This function executes the activity. // It is highly recommended to not to block the execution of this function while executing the activity. // All the information should be logged into the queue and the function should be returned. // In a separate thread or on a separate machine, read the data from the queue and execute the activity. // Once the activity action is completed the bookmark should be resumed. // Design the activity controller to hanlde multiple activities from one workflowflow. public override void StartResumablePSCommand(Guid jobInstanceId, Bookmark bookmark, PowerShell command, PowerShellStreams<PSObject, PSObject> streams, PSActivityEnvironment environment, PSActivity activityInstance) { ActivityActionData data = new ActivityActionData(); data.jobInstanceId = jobInstanceId; data.bookmark = bookmark; data.command = command; data.streams = streams; data.environment = environment; // Add the request to the queue. ActivityActionsQueue.TryAdd(jobInstanceId, data); // Return the fucntion and allow the workfow do other work in parallel. // There should be a servicing thead which gets the data from the queue and perform the action. // To keep this sample simple, the worker thread calls the servicing function. ThreadPool.QueueUserWorkItem(ServiceRequests, jobInstanceId); }
// This function executes the activity. // It is highly recommended to not to block the execution of this function while executing the activity. // All the information should be logged into the queue and the function should be returned. // In a separate thread or on a separate machine, read the data from the queue and execute the activity. // Once the activity action is completed the bookmark should be resumed. // Design the activity controller to hanlde multiple activities from one workflowflow. public override void StartResumablePSCommand(Guid jobInstanceId, Bookmark bookmark, PowerShell command, PowerShellStreams <PSObject, PSObject> streams, PSActivityEnvironment environment, PSActivity activityInstance) { ActivityActionData data = new ActivityActionData(); data.jobInstanceId = jobInstanceId; data.bookmark = bookmark; data.command = command; data.streams = streams; data.environment = environment; // Add the request to the queue. ActivityActionsQueue.TryAdd(jobInstanceId, data); // Return the fucntion and allow the workfow do other work in parallel. // There should be a servicing thead which gets the data from the queue and perform the action. // To keep this sample simple, the worker thread calls the servicing function. ThreadPool.QueueUserWorkItem(ServiceRequests, jobInstanceId); }