In some cases, with attended bots, it could be necessary to input data into the automation workflow. As long as we work in desktop environments, we have everything aboard to enable such inputs on a simple way. In this post I describe an example of how to use Windows Forms UI.
Windows Forms UI DLL
Windows Forms is a UI framework to create rich desktop client apps for Windows. We can use Windows Forms for the compatibility modes Windows - Legacy (dotNET Framework 4.61 - x86 architecture) and Windows (dotNET 6 - x64 architecture). In my example I use a very easy one, a window with one label, one text box and one button.
The Windows Forms UI code is in a dynamic link library (DLL). Besides the definitions of the window and the UI controls, the DLL contains the event routines that are executed when the button is pressed or the window is closed. In both cases a JSON string is returned which contains the entered name. And last but not least the routine getValue which we call from UiPath.
//-Begin----------------------------------------------------------------
using System;
using System.Drawing;
using System.Windows.Forms;
namespace First {
public class MyForm : Form {
private static string retValue = String.Empty;
private TextBox txtName = new TextBox();
public MyForm() {
InitComponents();
}
private void InitComponents() {
//-Window---------------------------------------------------------
Text = "UiPath example";
ClientSize = new Size(640, 480);
CenterToScreen();
this.FormClosing += MyForm_FormClosing;
//-Label Name-----------------------------------------------------
Label lblName = new Label();
lblName.Text = "Name";
lblName.Left = 20;
lblName.Top = 20;
lblName.Width = 150;
lblName.Height = 30;
lblName.Font = new Font("Consoleas", 10);
Controls.Add(lblName);
//-Textbox Name---------------------------------------------------
txtName.Left = 170;
txtName.Top = 20;
txtName.Width = 180;
txtName.Height = 30;
txtName.Font = new Font("Consoleas", 10);
txtName.Text = "Stefan Schnell";
Controls.Add(txtName);
//-Button to quit ------------------------------------------------
Button btnQuit = new Button();
btnQuit.Text = "Click me to quit";
btnQuit.Left = 6;
btnQuit.Top = 444;
btnQuit.Width = 628;
btnQuit.Height = 30;
btnQuit.BackColor = SystemColors.ButtonFace;
btnQuit.Click += new System.EventHandler(click_btnQuit);
Controls.Add(btnQuit);
}
//-Quit button click event------------------------------------------
private void click_btnQuit(object sender, EventArgs e) {
MessageBox.Show("Hello World from " + txtName.Text);
retValue = "{\"name\": \"" + txtName.Text + "\"}";
this.Close();
}
//-Windows Forms close event----------------------------------------
private void MyForm_FormClosing(object sender, FormClosingEventArgs e) {
retValue = "{\"name\": \"" + txtName.Text + "\"}";
}
//-Main-------------------------------------------------------------
[STAThread]
public string getValue() {
#if NETCOREAPP
Application.SetHighDpiMode(HighDpiMode.SystemAware);
#endif
Application.EnableVisualStyles();
Application.Run(new MyForm());
return retValue;
}
}
}
//-End------------------------------------------------------------------
To compile this code to a DLL use for dotNET Framework 4.61 this command …
csc.exe /target:library /platform:anyCPU /out:UiPathExample.dll UiPathExample.cs
… or with dotNET 6 SDK use this csproj …
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net6.0-windows7.0;net461</TargetFrameworks>
<OutputType>Library</OutputType>
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<UseWindowsForms>true</UseWindowsForms>
</PropertyGroup>
<ItemGroup>
<Reference Include="System.Windows.Forms" Condition="'$(TargetFramework)' == 'net461'">
<HintPath>System.Windows.Forms.dll</HintPath>
</Reference>
<Reference Include="System.Windows.Forms" Condition="'$(TargetFramework)' == 'net6.0-windows7.0'">
<HintPath>System.Windows.Forms.dll</HintPath>
<HintPath>System.Windows.Forms.Primitives.dll</HintPath>
</Reference>
</ItemGroup>
</Project>
… and copy the DLL into your project directory.
Windows Forms with UiPath
After all these preparations are done, the library can now be used with UiPath. Here we use only a tiny Invoke Code activity, like I described it here about the using of dotNET assemblies.
System.Reflection.Assembly TestLibrary = System.Reflection.Assembly.LoadFrom(@"UiPathExample.dll");
dynamic Instance = TestLibrary.CreateInstance("First.MyForm");
strResult = Instance.getValue();
That’s all.
And in the context of the UiPath Assistant it works exactly like expected.
Conclusion
As we can see it is very easy to integrate rich client UIs, via Windows Forms, into the automation workflow. This allows us to build user interfaces and use the input from that, without any additional installations. For an attended bot that runs on the desktop and needs input certainly a good approach.
Addendum 19.09.2022: Tried successfully with UiPath Studio 22.8 in Windows compatibility mode (x64) with dotNET 6 SDK.