[The following article is authored by one of the Windows Embedded MVPs (Most Valuable Professionals). Our MVPs have a heavy background in Embedded systems and are a great repository of information on Windows Embedded products. We’re providing this space on our team blog as a service to our readers by allowing MVPs to share some of their knowledge with the rest of the community.]
It is one of the classic problems in an embedded project: After the successful boot process of the device and the OS one or more applications need to be started to do something useful on the device. This can get complex, because one might have applications that need to be started only once, some need to run all the time, but only in a certain user context and some should be running even when no user is logged on, to name just a few examples.
Any time the application started is the central UI or functionality node it should be started as the OS shell. There are quite a few articles on this in the MSDN library that explain how to do this. For example creating a custom shell component or running different shells for different users. The latter comes in handy when administrators requires more extensive system access using the normal explorer shell, while a standard user should have more restricted access to e.g. a custom shell.
Shells always run in a user’s context, so a user has to log on manually or is logged on automatically e.g. with the help of the Automatic Logon component. Using a custom shell has quite a few benefits for tailoring the system to a dedicated use as well as from a security perspective. Of course, there are some disadvantages, too. A lot of the functionality such as double-click on applications, wizards, pop-ups, tray icons, etc. are implemented in Explorer Shell and therefore will not be available when using a custom shell. In addition, using Autologon can pose a security risk, because the password is stored in clear text in the registry.
Applications that need to run without manual or Automatic Logon should be implemented as a Windows Service. These services still run in context of a given user, but normally run in their own virtual desktop, which provides additional encapsulation. Windows Services are ideal to implement functionality e.g. for headless system or background processes that need to be always available when the system is running, regardless of the user logged on.
If the usage scenario does not fit into those described above, there are other options available. To start an application automatically without having it set as shell or implement it as a service, a variety of registry keys can be used. These keys can be set on machine as well as on user level for a current user.
Machine level: [HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run] [HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce]
User level: [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run] [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce]
The RunOnce key provides the ability to run the specified application just once, which makes it ideal for management and installation purposes.
To get an overview which applications are started via Run keys one can leverage the MSConfig utility.
It is located in the Software\System\Management\Applications node of the Component Catalog. If you want to have an even better and more detailed overview Mike Russinovich’s tool AutoRuns for Windows is recommended.
Autoruns shows everything related to automatic startup and may even provide too muc info for being included into a Windows Embedded Standard retail image.
RunOnce Keys can also be set when creating components, with the help of a FBA Resource Command.
Setting the RunOnce request in the component does not mean that there will be a RunOnce entry in the registry after the FBA process is finished. Depending on the build phase of the component this RunOnce Request will be executed at the next boot of the system. Due to the fact that there can be several boots during FBA, it sometimes can get tricky if one wants to control exactly when a certain request is executed. Additionally, for some use cases the RunOnce request needs to be executed on the final target in field. Therefore, if this is required, it is often easier to add the key manually after FBA and before sealing the image for runtime deployment.
There is an additional RunOnce key available below the same registry path called RunOnceEX, which has been introduced as part of Windows Desktop Update. It can be used for installation purposes and provides a more sophisticated syntax as well as a UI splash screen during the execution of the RunOnce items. More information regarding RunOnceEx can be found in this Microsoft support article. RunOnceEx has a dependency on IE and therefore is not suited for low footprint images. If the required functionality is not part of the image, this key will just be ignored without any further error messages.
A different way to automate the launch of applications is using logon scripts. An easy method to configure this the local Group Policy console. Group Policies are a valuable part of the Windows configuration infrastructure.
Logon scripts are a very powerful technology, which leverage the Windows Scripting Host execution environment. They can also be used to develop advanced scenarios that are easily updateable via the Group Policy infrastructure in combination with Active Directory.A good introduction to this can be found in this Technet article.
Under certain circumstances, and depending on the application that is started via script, there are sometimes timing issues. Logon scripts are run quite early during system initialization and not all parts of the infrastructure may be available. In most cases a simple workaround suspending the script for a few seconds will solve the problem.