Let's get started - starting up applications on Windows CE at boot time

I've seen tons of questions on the newsgroups asked about how to startup apps at system init time on Windows CE.  I hope to answer %99 of them once and for all.  There's a ton of options for startup, with different tradeoffs and platforms they'll work on.

Regardless of which approach you take, be aware that if you get started this early at bootup then system services that you're anticipating being ready may not be.  For instance, a compact flash based filesystem may take a few seconds after bootup before it's available for use.  So if your application wants to read or write to a file right away, it should have some primitive polling mechanism where it tries say 10 times and waits a second between tries before giving up on accessing files.

Other stuff may not be up right after boot either, like the device may not have a DHCP address yet.  So program defensively as always, but just be aware that if some stuff fails the first time it doesn't necessarily mean the system is hopeless - try again in a few more seconds.

(1) PUT THE APP IN A STARTUP FOLDER
I believe that PocketPC has a \windows\Startup menu folder that acts just like StartUp in the Windows XP Start menu.  If you're on a PocketPC (or another CE platform that implements this) and you don't really want to be a service (see (4) below), this is the easiest and probably best way.

Everything else assumes you're on a standard Windows Embedded device that doesn't have PocketPC shell to do nice things like start up apps for you.

(2) HAVE YOUR APP LOADED BY THE KERNEL
The kernel decides which apps to load up and in which order by reading the values in HKLM\Init.  http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wcepb40/html/pbconconfiguringregistryfiletorunapplicationatstartup.asp has a good introduction to this.

Just remember to call the SignalStarted() API once you're through with your initialization.  Also you should make your app depend on an executable that gets started late in the bootup process.  I would recommend depending on services.exe - i.e. services.exe must indicate it's done starting up (when it calls SignalStarted()) before your app gets launched.

(3) USE SVCSTART
One drawback of option (2) is that you can't pass command line arguments to apps.  Also you may want to delay your app startup a few seconds (say 10-20) if it's not critical for system operation and you want to minimize the likelyhood you'll have to poll for critical system services that aren't started yet.  You could add an initial Sleep() of course, but if you want this app to be called at other times other than the boot process then you have to have a cmd line to specify the sleep option.

In CE 4.1 I added a sample called svcStart, which is a simple service loaded by services.exe with the sole purpose of starting up applications.  Note this isn't officially tested or supported by MS.  However, I've used svcStart to startup apps in devices that went in MS executive's houses.  So obviously I trust it enough to bet my career, if not my life, on it :).

To build it from Platform Builder, go to 'build OS->open release directory' and cd to %_WINCEROOT%\public\servers\sdk\samples\services\svcStart.  Then 'build' and run 'sysgen -p servers svcstart.'  Add svcstart.dll to your image. You'll need this registry to get the service started:

[HKEY_LOCAL_MACHINE\Services\SVCSTART]
   "Context"=dword:0
   "Dll"="svcstart.dll"
   "Order"=dword:99
   "Keep"=dword:1
   "Prefix"="STR"
   "Index"=dword:0


Each reg subkey under this represents a different application to be started. An example (from servers.reg) would be:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SVCStart\1]
    @="msmqadm"
    "Args"="register"    // command line arguments
    "Delay"=dword:4000   // delay time, in milliseconds, before the app will be started

Check out C code if you want to know more details.

(4) WHY ARE YOU STARTING AN EXE IN THE FIRST PLACE?
You know that CE has a 32 process limit, right?  And that on just about any OS, processes are more expensive than threads.  In scenarios where you just need to do some quick initialization on system startup and then have your application quit, (1)-(3) are still fine options.

However if you're writing a long-running system service, you should implement it as a DLL and have services.exe load it up on system initialization just like all the other built-in services (web server, telnet, UPNP, MSMQ, etc... depending on your platform).

Preaching services.exe is beyond what I plan on doing today (though soon I will), but at least understand services.exe and think about whether whatever you're trying to start up is really a service after all.

Services.exe is available on CE 4.0 and above and PocketPC 2003 and above.  Docs are available at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceserv/html/cmconServicesexe.asp.

--

[10/19/2005 Update] Paul Tobey, one of our MVPs, wrote a very good newsgroup post walking through some common problems people have with starting apps at startup here.  It was written to a question regarding the HKLM\Init method, but many of the points are generically useful.

[Author: John Spaith]