Last week I needed to write an application for my Electrical Engineer to run at boot up to test some hardware changes. He needed to run this test every time the system booted, and needed to have the system reboot often. Of course I don’t expect an EE to be able to set up the test so that it automatically starts when the system boots, and I don’t want to do it for him so I decided to have the application set itself up to run again on the next boot.
I have discussed how to set up an application to run at boot before in Windows CE: Starting an Application when the System Boots. For this I decided that the application should do two things:
1.       Add itself to HKEY_LOCAL_MACHINE\Init
since this is an embedded system, I am going to use Launch52 because on this system 52 is not used by anything else. You could develop a way to automatically select a LaunchXX number if you need to do this for an off the shelf system, but that complicates things and I don’t think is needed by most of us so I will leave that to you if you need it.
2.       Add its path to the system path
On my system, I have persistent storage in NOR flash. For simplicity, I will call that disk “NOR Flash” and use a folder named “Test”.
The code to do these looks like this:
void StartAutorun()
{
                HKEY    regKey=NULL;
                DWORD Disposition ;
                UINT32 status;
                TCHAR Launc52Val[] = TEXT("BootTest.exe");
                BYTE Depend52Val[] = { 0x14, 0x00, 0x1E, 0x00 };
                TCHAR *SystemPathVal;
                TCHAR NewSystemPath[] = TEXT("\\NOR Flash\\Test\\" );
                DWORD NumBytes = 0;
                DWORD Type;
 
                status = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
                                TEXT("Init"),
                                0,
                                0,
                                REG_OPTION_NON_VOLATILE,
                                0,
                                NULL,
                                &regKey,
                                &Disposition
                                );
 
                if( status == ERROR_SUCCESS )
                {
                                status = RegQueryValueEx( regKey, TEXT("Launch52"), NULL, &Type, NULL, &NumBytes );
                                // if this launch value already exists, then do nothing
                                if( status != ERROR_SUCCESS )
                                                RegFlushKey( regKey );
                                else
                                {
                                                // The value doesn't exist, so add it and change the system path
                                                RegSetValueEx( regKey,
                                                                TEXT("Launch52"),
                                                                0,
                                                                REG_SZ,
                                                                (const BYTE*)Launc52Val,
                                                                (wcslen(Launc52Val)+1)*sizeof( TCHAR)
                                                                );
                                                RegSetValueEx( regKey,
                                                                TEXT("Depend52"),
                                                                0,
                                                                REG_BINARY,
                                                                (const BYTE*)Depend52Val,
                                                                4
                                                                );
                                                // Persist the registry, then close the key
                                                RegFlushKey( regKey );
                                                RegCloseKey( regKey );
 
                                                status = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
                                                                TEXT("Loader"),
                                                                0,
                                                                0,
                                                                REG_OPTION_NON_VOLATILE,
                                                                0,
                                                                NULL,
                                                                &regKey,
                                                                &Disposition
                                                                );
                                                if( status == ERROR_SUCCESS )
                                                {
                                                                // This is a fake read, all it does is fill in NumBytes with the number of
                                                                // bytes in the string value plus the null character.
                                                                status = RegQueryValueEx( regKey, TEXT("SystemPath"), NULL, &Type, NULL, &NumBytes );
                                                                if( NumBytes > 0 )
                                                                {
                                                                                // Now we know how big the string is allocate and read it
                                                                                SystemPathVal = (TCHAR *)malloc( NumBytes + (wcslen(NewSystemPath)+1)*sizeof( TCHAR));
                                                                                if( SystemPathVal != NULL )
                                                                                {
                                                                                                status = RegQueryValueEx( regKey, TEXT("SystemPath"), NULL, &Type,
                                                                                                                                                (LPBYTE)SystemPathVal, &NumBytes );
                                                                                                // Make the math easier, convert to number of characters
                                                                                                NumBytes /= sizeof( TCHAR );
                                                                                                // Concatinate the new path on, which overwrites the last null, leaving one
                                                                                                wsprintf( &SystemPathVal[ NumBytes - 1 ], NewSystemPath );
                                                                                                NumBytes += wcslen(NewSystemPath);
                                                                                                // Tack on the second null
                                                                                                SystemPathVal[ NumBytes ]       = '\0';
                                                                                                NumBytes += 1;
 
                                                                                                RegSetValueEx( regKey,
                                                                                                                TEXT("SystemPath"),
                                                                                                                0,
                                                                                                                REG_MULTI_SZ,
                                                                                                                (const BYTE*)SystemPathVal,
                                                                                                                (NumBytes * sizeof( TCHAR))
                                                                                                                );
                                                                                                free( SystemPathVal );
                                                                                }
                                                                }
                                                                // Persist the registry, then close the key
                                                                RegFlushKey( regKey );
                                                                RegCloseKey( regKey );
                                                }
 
                                }
                }
}
This code sets up the system to run the application again on boot by setting up the registry and persisting the changes to the registry.  Which of course means that the system that you are using must be able to perist the registry, that is a choice for your OEM to make and implement.
 
You may also want to look at Summary of Registry Posts
Tags: 
Copyright © 2008 – Bruce Eitman
All Rights Reserved