Run .NET Code in UiPath From a Text File

UPDATE (06/27/2023) - UiPath has introduced coded workflows (currently in public preview as of the time of this writing), which is significantly better than the solution described in this article. Once coded workflows reach general availability, the article below will be mostly useless. I say mostly useless, because there is one concept from this article that is still worthwhile.

Creating and invoking instances of activities programmatically is still beneficial for UiPath projects. This can shorten workflows significantly if done well. Even more useful is applying this concept in non-UiPath projects. Simply import CoreWF as a dependency in your .NET Framework project, and you will be able to use activities programatically just like this article describes, without needing UiPath at all.


ORIGINAL ARTICLE - If you're like me, you like using UiPath's Invoke Code activity to simplify code that would otherwise require several activities. But if your .NET code is very long, the Invoke Code activity can be a bit cumbersome at times.

If you've ever wanted to run .NET code from a text file in UiPath without using the Invoke Code activity, there is a way to do this.

First, create an instance of the Invoke Code activity and set its properties:

Dim codeActivity As New UiPath.Core.Activities.InvokeCode

'Arguments property cannot be null
codeActivity.Arguments = New Dictionary(Of String, Argument)

codeActivity.Code = File.ReadAllText("CodeFile.vb")
codeActivity.ContinueOnError = False

'You can use C# or VB.NET code
codeActivity.Language = NetLanguage.VBNet

Then use a WorkflowInvoker to execute the code:

New WorkflowInvoker(codeActivity).Invoke

To pass arguments from UiPath to your code, create a Dictionary (Of String, InArgument). Then convert this dictionary to a new Dictionary (Of String, Argument):

Dim args As New Dictionary(Of String, InArgument) From {
    {"num1", New InArgument(Of Integer)(10)},
    {"num2", New InArgument(Of Integer)(20)}
}

codeActivity.Arguments = args.ToDictionary(
    Function(x) x.Key,
    Function(y) CType(y.Value, Argument)
)

Suppose that CodeFile.vb contains Console.WriteLine(num1 + num2). Using the num1 & num2 arguments above as an example, since num1 = 10 and num2 = 20, the sum 30 would be written to the console.

Code files should have comments and top-level documentation:

  • What the code file does on a high level
  • Dependencies (packages and version numbers)
  • Arguments that need to be passed in from UiPath

There are some limitations to this approach of invoking code:

  • Code files do not recognize imported namespaces, meaning classes must be fully qualified. For example, instead of writing List(Of String), you must write out System.Collections.Generic.List(Of String)
  • Code files can use In arguments, but they cannot use In/Out or Out arguments. But a workaround is using environment variables to return values to UiPath:
    • In your code file, use System.Environment.SetEnvironmentVariable
    • In UiPath, use System.Environment.GetEnvironmentVariable
    • Note that environment variables are limited to 32,760 characters

With all these limitations, why is this method of running .NET code useful?

  • Code files (.cs or .vb) are easier to share with others than xamls
  • If your project uses source control, storing .NET code in separate text files makes it much easier to track changes
  • Long scripts are much easier to view and modify in a code editor (e.g. Atom, Notepad++, VS Code, etc)