Windows Embedded Compact Shell Launcher

Microsoft

bloggers

discussions

Windows Embedded Compact Shell Launcher

  • Comments 0

Posted By Pavel Bansky
Program Manager

Welcome to the next article about Windows Embedded Compact. I want to describe you a situation and I’m sure you are familiar with it: You come across a digital signage device or point of sale terminal and there is an error code showing on the Windows desktop. The device is inactive, waiting for someone to reboot it. This is not just pretty lame; it might hurt your service or your company if you allow it to happen.

Today, I want to give you ideas on how to prevent moments like this one, and to minimize the downtime of your application in Windows Embedded Compact. There are many articles about launching your application right after machine reboot, how to make kiosk mode in your managed code application, and so on. But I have yet to come across an article on application launcher that discusses not just launching the application, but also caring whether or not the application is still running.

The program below has a very simple functionality: launch a process defined in the registry and wait for that process to exit. If the process exits intentionally or because of a crash, it will automatically be launched again. I think the source code is self-explanatory and can be also improved by a crash counter, which will send an alert when the application crashes too often in a short time.

#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <tchar.h>

int _tmain(int argc, _TCHAR* argv[])
{
    const TCHAR c_szSWRegKey[]    = TEXT("Autorun");    
    const TCHAR c_szProcess[]    = TEXT("Process");
    
    TCHAR   szProcess[MAX_PATH];
    HKEY    hKey;    
    DWORD   dwType;
    DWORD   dwValueSize;
    BOOL    bAutorunSet = false;

    // Open registry
    if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szSWRegKey, 
                                      0, KEY_QUERY_VALUE, &hKey))
    {
        dwValueSize = sizeof(szProcess);
        if (ERROR_SUCCESS == RegQueryValueEx(hKey,// Handle to registry key
                                             c_szProcess,     // Name of the registry value
                                             NULL,                       // reserved
                                             &dwType,                // Pointer to type
                                             (LPBYTE) szProcess, // Pointer to data
                                             &dwValueSize))          // Pointer to data size
        {
            RegCloseKey(hKey);
            
            STARTUPINFO si;
            PROCESS_INFORMATION pi;
            
            ZeroMemory( &si, sizeof(si) );
            si.cb = sizeof(si);
            ZeroMemory( &pi, sizeof(pi) );            

            // Autorun loop
            while(true)
            {
                if( !CreateProcess( szProcess,        // Application name
                                    NULL,            // Command line
                                    NULL,     // Process handle not inheritable
                                    NULL,     // Thread handle not inheritable
                                    FALSE,    // Set handle inheritance to FALSE
                                    0,        // No creation flags
                                    NULL,     // Use parent's environment block
                                    NULL,     // Use parent's starting directory 
                                    &si,      // Pointer to STARTUPINFO structure
                                    &pi ))    // Pointer to PROCESS_INFORMATION structure 
                {
                    printf( "Creating Process failed (%d).\n", GetLastError());
                    return 1;
                }

                // Wait infinitely until process exits.
                WaitForSingleObject( pi.hProcess, INFINITE );        
            }
        }
    }

    return 0;
}

In order to launch this launcher right after the Windows Embedded Compact reboot, add this registry key to the platform.reg file:

[HKEY_LOCAL_MACHINE\init]
        "Launch90"="Launcher.exe"
        "Depend90"=hex:14,00,1E,00

[HKEY_LOCAL_MACHINE\Autorun]
        "Process"="cmd.exe"        

…where the init section is a standard Windows Embedded Compact registry key, which defines applications to be run after the reboot. While the Autorun section is there for launcher, our application defines which process to run and watch.

I hope this will give you an idea of how to control whether your application is still running or not. This approach can be used especially if you are not an owner of the executed application; although, it has its limitations. For example, what if the application hangs out and it is not responsive? The process is still there, so our launcher thinks everything is alright, but the machine is in an unusable state.

A much better option, which is outside of the scope of this article, would be to use watchdog APIs. In order to do that, the monitored application needs to be written in a certain way, to enable the launcher to monitor it and take an appropriate action when necessary. Hmm…I just got an idea for the next article.

blog comments powered by Disqus