Search code examples
workflow-foundationworkflow-foundation-4.net-4.0-beta-2

Workflow 4.0 custom activity to start external process


I am trying out Workflow 4.0 and hoping to write a custom activity to start an external executable, wait for that process to complete and then resume subsequent steps in the workflow.

I found the following example that shows (towards the bottom of the page) how to write an activity to waiting for a file to arrive in a specific directory:

Creating Custom Activities with Workflow 4.0

I have a couple of problems with the example. Firstly, when I add the following code:

void FileCreated(object sender, FileSystemEventArgs e)
{
    instance.ResumeBookmark(bookmarkName, e.FullPath);
    fsw.Dispose();
}

instance.Resumebookmark(...) does not seem to be available but instance.BeginResumeBookmark and instance.EndResumeBookmark are.

I am also unsure of how to change this around to deal with external processes, rather than just watching the contents of a directory.

Is this even the best approach for this kind of thing?


Solution

  • I would suggest writing an AyncCodeActivity and avoid bookmarks altogether. Here is an example of a custom activity that returns the process exit code as the result:

        public sealed class RunProcess : AsyncCodeActivity<int>
        {
            public InArgument<string> FileName { get; set; }
            public InArgument<string> Arguments { get; set; }
    
            private Func<string, string, int> runProcessAsyncCall;
    
            protected override IAsyncResult BeginExecute(AsyncCodeActivityContext context, AsyncCallback callback, object state)
            {
                this.runProcessAsyncCall = this.RunProcessImpl;
                return runProcessAsyncCall.BeginInvoke(FileName.Get(context), Arguments.Get(context), callback, state);
            }
    
            protected override int EndExecute(AsyncCodeActivityContext context, IAsyncResult result)
            {
                return this.runProcessAsyncCall.EndInvoke(result);
            }
    
            private int RunProcessImpl(string fileName, string arguments)
            {
                Process p = Process.Start(fileName, arguments);
                p.WaitForExit();
                return p.ExitCode;
            }
        }
    

    In general, bookmarks are great if the external event will not come for a potentially long time. If the process you're invoking is short-lived, an AsyncCodeActivity might be a better choice (it's certainly an easier one to manage).