Monday, January 28, 2008

Running a XOML workflow from the command line

I needed to be able to execute a XOML workflow from the command line so I wrote this little app that takes a XOML file as an argument and executes it. This is part of something that should become a nice example of using WF to build applications for non-programmers, i.e. using activities as building blocks like Lego. More on that to follow, perhaps.

using System;
using System.IO;
using System.Threading;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.Runtime;
using System.Xml;

namespace WFBuild
{
  class Program
  {
    private static AutoResetEvent waitHandle;
    static void Main(string[] args)
    {
      try
      {
        Console.WriteLine("WFBuild");
        if (args.Length != 1)
        {
          Console.WriteLine("Usage");
          Console.WriteLine("WFBuild <XOML file to execute>");
        }
        else
        {
          WorkflowRuntime workflowRuntime = new WorkflowRuntime();
          workflowRuntime.StartRuntime();
          workflowRuntime.WorkflowCompleted += new EventHandler<WorkflowCompletedEventArgs>(workflowRuntime_WorkflowCompleted);
          workflowRuntime.WorkflowTerminated += new EventHandler<WorkflowTerminatedEventArgs>(workflowRuntime_WorkflowTerminated);

          FileStream stream = new FileStream(args[0], FileMode.Open, FileAccess.Read);
          XmlTextReader reader = new XmlTextReader(stream);
          WorkflowInstance instance = workflowRuntime.CreateWorkflow(reader);
          waitHandle = new AutoResetEvent(false);
          instance.Start();
          Console.WriteLine("Executing...");
          waitHandle.WaitOne();
        }
        Console.WriteLine("Press return");
        Console.ReadLine();
      }
      catch (WorkflowValidationFailedException exp)
      {
        // catch workflow failed validation exception and show validation errors
        Console.WriteLine("Validation failed:");
        foreach (ValidationError error in exp.Errors)
        {
          Console.WriteLine(error.ToString());
        }
        Console.WriteLine("Press return");
        Console.ReadLine();
      }
      catch (Exception e)
      {
        Console.WriteLine(e.Message);
        Console.WriteLine("Press return");
        Console.ReadLine();
      }
    }

    static void workflowRuntime_WorkflowTerminated(object sender, WorkflowTerminatedEventArgs e)
    {
      Console.WriteLine("Workflow terminated");
      Console.WriteLine(e.Exception.Message);
      waitHandle.Set();
    }

    static void workflowRuntime_WorkflowCompleted(object sender, WorkflowCompletedEventArgs e)
    {
      Console.WriteLine("Workflow completed");
      waitHandle.Set();
    }
  }
}

Update - I've updated the code to show validation errors

No comments: