We’ll learn how to launch an external process (exe) from a Universal Windows Platform (UWP) app using
This is a headed sample. To better understand what headed mode is and how to configure your device to be headed, follow the instructions here.
Windows.System.ProcessLauncher API is new to Windows IoT Core Fall Update. You can download a Windows 10 IoT Core image with Fall Update from our downloads page.
To use the
ProcessLauncher API and other new features of Windows IoT Core Fall Update, a newer version of the Windows SDK is needed as well. Windows SDK 10.0.10586.0 or higher is required and can be downloaded from here.
For more information on setting everything up, refer to our get started guide..
You can find the source code for this sample by downloading a zip of all of our samples here. Make a copy of the folder on your disk and open the project from Visual Studio.
The code for the ProcessLauncher sample can be found under:
If you’re building for Minnowboard Max, select
x86 as the architecture. If you’re building for Raspberry Pi 2 or 3 or DragonBoard , select
Select Remote Machine to point to IoT device and hit F5 to deploy to your device. Go back to the basic ‘Hello World’ sample. if you need guidance
The sample app when deployed displays a screen similar to this one:
Go ahead, click the Run Command button to launch the application specified in the Command edit box, SampleConsoleApplication.exe, which is an executable Win32 application built and deployed from the sample app as well.
When run, the SampleConsoleApplication exe, will send output to both the Standard Output and Standard Error boxes. The return error code of the process, 100, should also be shown.
The code for this sample makes use of the
Windows.System.ProcessLauncher API, which is part of the system management contract APIs available on Windows IoT Core.
To use the API, we need to do a couple of things.
Since the IoT extension SDK is not added to projects by default, we’ll need to add a reference to it so its types, including
Windows.System.SystemManagement.ProcessLauncher, will be available in the project.
To do so, right-click on the References entry under the project, select “Add Reference” then navigate the resulting dialog to
Universal Windows->Extensions->Windows IoT Extensions for the UWP making sure the right version, 10.0.10586.0 or higher, is selected, then check the box, and click OK.
Windows.System.ProcessLauncher API from your code requires the
systemManagement IOT Capability. So, we need to add it to the AppX manifest, Package.appxmanifest file:
NOTE: While you can add other capabilities directly by double clicking and opening the Package.appxmanifest file in the UI editor, systemManagement capability can only be added via the XML editor (Right Click on the file -> Open with -> XML (Text) Editor) and adding the capability below:
ProcessLauncher API providers a number of static method overloads to launch new apps using the executable file name plus optional arguments and other options.
Here’s the part of the sample that launches the new process. After the process is launched, we
await its return to get the exit code.
While the exit code is often enough to let us know if an executable has succeeded or not, sometimes we need to read the output from the program; e.g. to log information or to show that text in the app.
ProcessLauncherOptions class allows sharing the standard input, output and error streams between the UWP app and external process.
ProcessLauncherOptions.StandardInputis of type
Windows.Storage.Streams.IInputStreamand is read from by the external process
Windows.Storage.Streams.IInputStreamproperties and are used by the external process to write to standard output or standard error
Now, let’s learn how to pass output streams to the executable and then read what was written to it.
To be able to both read and write data to strams, we create the streams as
InMemoryRandomAccessStream can be casted as both Input or Output streams, which is exactly what we need. We will pass it as
IOutputStream to the
ProcessLauncherOptions, and then read data from it as an
IInputStream after the external exe has completed writing to it.
Here’s the relavant code from the sample. First, we initialize the stream objects:
Then, we pass the options to the
Finally, we read the data from the
InMemoryRandomAccessStream after getting it as an input stream:
Note, while not used in the sample, the standard input stream can be used with the
ProcessLauncher API as well.
ProcessLauncher API can launch executable programs packaged as part of the same AppX. So, a sample Win32 console app, SampleConsoleApplication, is included in the sample.
The program itself is quite simple, but it demonstrates the various aspects of the ProcessLauncher API, including argument passing and sharing standard output and standard error streams.
Here’s the main method of the sample console app:
The application has been added to the solution as a console application. To create your own console application, please refer to the Console Application Sample.
To be able to find and invoke the SampleConsoleApplication exe at runtime, we need to package the output exe with the AppX. We’ve already added it to the sample application. However, to do the same in your own application, you can follow these steps:
Now, everytime the solution is built or deployed, it’ll ensure the console application exe is up-to-date and deployed with the rest of the AppX.
When a relative path is specified; such as SampleConsoleApp.exe, .\SampleConsoleApp.exe or a subfolder, subfolder\SampleConsoleApp.exe, the
ProcessLauncher API looks for the exe file starting at the package root of the AppX deployed.
However, the API is also capable of running apps anywhere on the device, by specifying the absolute path; e.g. c:\windows.system32\ipconfig.exe
To use an external exe, that exe must be added to an allow list. This is needed to prevent malicious apps from running.
To add an exe to the allow list, add to or replace the reg value in the reg command below:
reg.exe ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\EmbeddedMode\ProcessLauncher" /v AllowedExecutableFilesList /t REG_MULTI_SZ /d "c:\windows\system32\ipconfig.exe\0c:\windows\system32\tlist.exe\0"
ProcessLauncher API launches executables under the current user credentials, or DefautlAccount, so apps requiring admin priviliges will fail to run properly.
Go ahead, run the command above on your device, using SSH or PowerShell. Then, in the sample app (no need to restart) type the command
c:\windows\system32\ipconfig.exe. You should get an output similar to the one below:
Additionally, to overcome the limitations of using reg commands, the Process Launcher Whitelist Configuration tool can be used to very easily add or remove executables to the ProcessLauncher allow list.
The tool is available as part of the Windows 10 IoT Utilities on GitHub.
To use the tool: