UiPath ReFramework 101: Killing a User-Specified Process

Published on in Robotic Process Automation by Marius Vrancianu

If you’ve used the UiPath Robotic Enterprise Framework enough, then you’ve probably used the “KillAllProcesses” (KAP) workflow. The KAP workflow is a default workflow of the Framework that you can use to forcefully shutdown processes that fail to close during an automation. It is a useful tool, because having excess open applications that run multiple processes on your computer can be problematic, resulting in memory jams or the overuse of CPU at best. In a worst-case scenario, it could even result in serious security issues.

While the KAP workflow is a great tool, there is also a scenario in which a developer needs a more precise way of forcefully terminating applications and processes. Such a scenario occurs on high-density servers, with hosted virtual machines (VMs) in an environment that allows multiple concurrent users. Because there are multiple users, and because you cannot terminate a process for all users, the developer must single out the user whose processes they want to terminate. (Trying to terminate a process for all users will result in an “access denied/fatal error” message). 

In the image below you can see the above-described scenario. Multiple users are running the “chrome.exe” process. If you wanted to close “chrome.exe” the only way you could do that is by first specifying the username.

We know that developers frequently encounter the need to specify a user to close that user’s open processes in such an an environment, because the issue has sparked much debate on the UiPath Forum. Some have suggested using  custom *.bat files as a remedy, while others have suggested retrieving and killing processes by their PID. The Marketplace also offers some custom-made components that do just that, but as UiPath does not officially recommend them, their use may pose questionable security risks. Luckily there is a simple, short and easy-to-implement workaround for isolating a user and closing their processes.

The pseudocode is simple and should look something like this:

START
GET ALL CURRENTLY RUNNING PROCESSES
GET CURRENT USER
FOR EACH CURRENTLY RUNNING PROCESS:
GET PROCESS USER
IF PROCESS USER = CURRENT USER
TERMINATE PROCESS
ELSE SKIP
END

So:

  • Start by adding a single input argument to the “KillAllProcesses” workflow, as an Array of String:

The Array entries contain all of the automation-specific processes you could want to terminate. You can define them manually in the array, but, then again, a good practice would be to specify them in the Config file for the end-user’s ease of use.

  • Find and retrieve all the currently running processes and the current user, by adding two assign activities; (below renamed “Get all running processes” and “Get current user”). The CurrentProcesses variable should be an Array of Process (System.Diagnostics.Process), and the syntax to obtain it should simply be: Process.GetProcesses .

As for the CurrentUser, you can retrieve it by applying System.Security.Principal.WindowsIdentity.GetCurrent().Name (which will return the full hostname, user+domain included) and then removing the domain part, so the final syntax for that would be: 

System.Security.Principal.WindowsIdentity.GetCurrent().Name.Replace(System.Environment.UserDomainName+“\”,“”)

This will return a String containing the username only, for later use.

  • Then, using a For Each loop, iterate through all currently running processes and retrieve the  corresponding user names for each open process. In order to do that, use the syntax Current_Process.StartInfo.Environment(“Username”) in an Assign activity, adding it to another String variable:

Please don’t forget to specify the TypeArgument of the loop as Systems.Diagnostics.Process, because we iterate through a collection of processes.

  • As a final step, add an If Statement inside the For Each loop and check if the current iteration item (i.e. process) is an entry in the input Array of Process to kill and, if so, whether it’s run under the current user or not.

To verify the above you can use a single, but somewhat longer condition:

in_ProcessesToKill.Contains(Current_Process.ProcessName, StringComparer.InvariantCultureIgnoreCase) AndAlso ProcessUsername.Equals(CurrentUser)

The actual Kill Process activity should only be executed if the condition is true, so it will obviously be added to the Then branch of the If Statement, with the CurrentProcess variable set as target process:

And voilà! Problem solved with virtually no risks taken!

We hope this comes in handy, and that it will be as much  help to you as has been  for us.