Click here to Skip to main content
Click here to Skip to main content

Automatically Starting Your Application on Windows Mobile

By , 31 Jul 2008
 

Introduction

Figuring out how to make an application automatically start up had long been a mystery to me. The information was scattered, and a bit of research was needed to collect all of it. During my research, I placed all of my notes in various documents, and have decided to organize them into a single document and share with all. The information presented here was tested on Windows Mobile 5 and Windows Mobile 6 devices, but can also be applied to several versions of Windows CE (the OS from which Windows Mobile is derived).

It's possible to achieve similar functionality by making your own executable that watches system changes through the SystemState class and responding accordingly, but that would cause your program to have a larger footprint.

About the code

The first methods of automatically starting a program are centered in what I will call configuration tasks; making shortcuts, Registry entries, or placing files in specific locations. For these methods, I do not provide code examples. Later within this article, I discuss methods for automatically launching applications that are setup through code. For these methods, I have included example code within the article, and full source attached to the article.

The code examples rely on some Win32 functions that are called through P/Invoke. Both code examples refer to a project named Win32 which contains the references to these functions. Additionally, Win32 also contains a structure and an enumeration needed to properly pass information to the WinAPI functions. To run the code examples, you will need a Windows Mobile device (or emulator) and Visual Studio 2008.

Remember that on Windows Mobile devices, you should prevent more than one instance of your program from existing in memory (if a second instance is started, it should notify the first instance and then immediately terminate).

What is meant by “auto-start”?

When I use the phrase auto-start, I use it to refer to the launching of any program based on an event (other than the user clicking on the program’s icon). A program can be automatically started in one of four ways:

  • A program on a memory card runs as soon as the card is inserted
  • A program is scheduled to start at a predetermined time
  • A program is launched in response to a system change
  • A program launches at device power up

Auto-Run from a memory card

The user inserting a memory card can cause an application to launch in one of two ways. The memory card could have a program on it that launches upon insertion, or the Windows Mobile device could start a program that is already present in its main storage in response to the memory card being inserted. The latter would be implemented by registering an application to start on a system change (discussed later).

When a memory card is inserted into a Windows Mobile / Windows CE device, the OS automatically looks in a certain folder for a program named Autorun.exe. If that program is found, then it is immediately run. The folder in which the OS looks is going to depend on what type of processor the device has. For an overwhelming majority of Windows Mobile devices, that folder will be “/2577”. Here is a table of the possible folder names for other Windows CE devices:

Processor Folder Name
ARM 720 1824
Arm 820 2080
ARM 920 2336
ARM 7TDMI 70001
Hitachi SH3 10003
Hitachi SH3E 10004
Hitachi SH4 10005
Motorola 821 821
SH3 103
SH4 104
Strongarm 2577

f you already have an application on a memory card that you wanted to auto-run, but you did not want to rename the executable or place it in this folder, then you can always make a second executable whose purpose is to launch your first executable.

Startup shortcut

A shortcut can be made to an application that you wish to startup automatically, and placed in \Windows\StartUp. Use this method if you have a single executable that needs to be started that has no dependencies on other executables. The format of shortcuts on Windows Mobile devices is simple. It will always be in the form 00#"<\program Files\path>", where 00 is replaced with the number of characters that appear after the ‘#’ sign; the ‘#’ is a delimiter, and then the complete path to the executable. The following is an example of a shortcut to Windows Media Player:

23#“\windows\wmplayer.exe”

You don't have to manually create the shortcut though. There is a native API call SHCreateShortcut that will create a shortcut for you. The first argument is the full path to the shortcut to be created, and the second argument is the full path to the file to which the shortcut points to.

Starting an application at bootup

For Windows Mobile devices, the location for auto-start entries is HKEY_LOCAL_MACHINE\Init. Unlike the startup entries on a desktop machine (which only require the path to the executable to start), the entries for Windows Mobile devices are a little more structured. There are two keys associated with an application that needs to start up automatically, a LaunchXX key and an optional DependXX key. The XX would be replaced with a number. This number is also called the sequence number. The value of LaunchXX is a string value (REG_SZ) that contains the path to the executable to be started. The DependXX key is used to specify on what applications the current application has dependencies (and thus in what order the applications must be launched). The DependXX key contains a list of word (2 byte) values that contain the sequence number values of the required applications.

The following screenshot is of the Registry on my Windows Mobile 5 phone. Launch21 refers to an application named “coldinit”. If we look at Depend21, we see that “coldinit.exe” has a dependency on an application identified by 0x14 (20 decimal). So, “coldinit.exe” must be launched after the app identified in Launch20, “Device.exe”.

Screen shot of Windows Mobile Registry

Applications launched using this method must notify the application of successful startup by calling the SignalStarted(DWORD) function. This function is a native call. For C programs, the header to this function is defined in Winbase.h and in the library Coredll.lib. Developers using managed code will need to P/Invoke this method. The function's only argument is the sequence number of the executable. The sequence number is passed to the application as its only command argument. Note that the sequence number is the only argument that the application will be able to receive through the command line arguments. Any other information that must be passed to the application should be passed through configuration files or Registry keys.

Starting a program at a specified time

The Windows CE / Windows Mobile OS contains functionality for automatically starting a program at a specified time. The functionality is available through a call to CeRunApAtTime from the CoreDLL library. As mentioned by Jim Wilson in many of his “How Do I” video posts on MSDN, this function expects the start time to be specified in the WinAPI SystemTime structure instead of the DateTime structure (CeRunAppAtTime is an unmanaged function called using the platform invoke functionality). Converting a time from a DateTime to a SystemTime is not difficult; there are WinAPI functions that doed this for you. To make calling this function easier, I have placed the following code in my Win32Helper class. I’ve also provided an overloaded function to allow the time to be passed as an offset from the current time with a TimeSpan object.

public static void RunAppAtTime(string applicationEvent, DateTime startTime)
{
    long fileTimeUTC = startTime.ToFileTime();
    long fileTimeLocal = 0 ;
    SystemTime systemStartTime = new SystemTime();
    CoreDLL.FileTimeToLocalFileTime(ref fileTimeUTC, ref fileTimeLocal);
    CoreDLL.FileTimeToSystemTime(ref fileTimeLocal, systemStartTime);
    CoreDLL.CeRunAppAtTime(applicationEvent, systemStartTime);
}
public static void RunAppAtTime(
     string applicationEvent, 
     TimeSpan timeDisplacement
)
{
    DateTime targetTime = DateTime.Now + timeDisplacement;
    RunAppAtTime(applicationEvent, targetTime);
}

applicationEvent is the full path to the application to start and startTime is the time at which the application should be executed. There’s also an overloaded version of the method that accepts a TimeSpan object instead of a DateTime, if you want to specify the start time relative to the current time.

If an application were attempting to schedule itself to be restarted at a later time, it will need to be able to pass its complete path. I used Reflection to find that path.

Module[] m = this.GetType().Assembly.GetModules();
target = m[0].FullyQualifiedName;

Screenshot of timed start program

Running the program because of a system change

There are a number of system changes that can be used to trigger the execution of a program. The WinAPI function CeRunAppAtEvent is used to associate a program with an event. Once associated, that program will be launched every time that the event occurs! So, you must also remember to disassociate the program with the event when you no longer want it to automatically start.

I have created an enumeration in the Win32 class named WhichEvent that contains the ID numbers for the events that can be used to trigger program execution.

When a program is started because of a change in system state, a single argument is passed to the program to indicate the state change that triggered the program's execution. (I don't discuss the details of how to do that here). For a complete list of the possible arguments, see the example code in AutoStartArgumentString.cs.

Enumeration Element Description

NOTIFICATION_EVENT_NONE

Used to clear all events associated with a program

NOTIFICATION_EVENT_TIME_CHANGE

NOTIFICATION_EVENT_SYNC_END

ActiveSync synchronization has completed on the device

NOTIFICATION_EVENT_ON_AC_POWER

The unit’s charger is connected

NOTIFICATION_EVENT_OFF_AC_POWER

The unit’s charger is disconnected

NOTIFICATION_EVENT_NET_CONNECT

The device is connected to a network

NOTIFICATION_EVENT_NET_DISCONNECT

The device is disconnected from a network

NOTIFICATION_EVENT_DEVICE_CHANGE

A memory card or other device was inserted or removed

NOTIFICATION_EVENT_IR_DISCOVERED

The device has detected another infrared device

NOTIFICATION_EVENT_RS232_DETECTED

The device has been connected to an RS232 device

NOTIFICATION_EVENT_RESTORE_END

A full restore of the device has completed

NOTIFICATION_EVENT_WAKEUP

The device has come out of a suspended state

NOTIFICATION_EVENT_TZ_CHANGE

The time zone of the device has changed

NOTIFICATION_EVENT_MACHINE_NAME_CHANGE

The name of the device has changed

I have created a class simply named Core for declaring platform invoked methods from the CoreDLL.dll library, and declared the CeRunApAtEvent function within it. The following schedules the Windows Calculator to start when the device comes out of the suspended state:

CoreDLL.CeRunAppAtEvent(@"\Windows\Calc.exe", 
       (int)WhichEvent.NOTIFICATION_EVENT_DEVICE_CHANGE);

After that call, the Windows Calculator will start every single time that the device is woken up. To prevent the Calculator from starting up, a second call is necessary:

CoreDLL.CeRunAppAtEvent(@"\Windows\Calc.exe", 
       (int)WhichEvent.NOTIFICATION_EVENT_NONE);

Included with this article is an example application that can be used to cause an application to launch various events. Originally, this program would only register a program to start upon wakeup. But, I've extended the program so that it can also start programs in response to other events. Note that by changing the value in the call to CERunAppAtEvent, you can use the program to cause an executable to launch because of some other event (such as a memory card being inserted, or ActiveSync completing its synchronization).

WiMoAutostart/WakeupStart.png

When a program is auto-started, a string is passed to it through the command line indicating the event that started it. I've included a program named ShowCommandLine with the source code that does nothing more than display the command line arguments that it received. From the screenshot below, you can see the command line argument that was received when the program was started upon connecting to a network connection.

WiMoAutostart/ShowCommandLine.png

Preventing multiple instances

Normally, the .NET framework will take care of ensuring that multiple instances of your program are not running. This doesn't always work for programs that are started because of a system event. Several system events can be fired in rapid succession, or the same event can be fired twice (for some odd reason, the wakeup event is usually fired twice). The first time I tried scheduling the ShowCommandLine program to start on wakeup of another event, I ended up with several instances of it running.

WiMoAutostart/MultiInstance.png

To get around this, I create an event object (using P/Invoke) before loading the form. If several instances of the program are started in rapid succession, then the creation of the event will fail, and we can use this failure to know that this is not the first instance of the program and immediately unload it.

static void Main()
{
    IntPtr eventHandle = IntPtr.Zero;
    const string ApplicationEventName = "ShowCommandLineEvent";
    //We will use this as our handle to ensure only one instance of the
    //program is started            

    try
    {
        //Try to create the event. If the creation fails then it is 
        //because another instance of this application is already 
        //running. If another instance exists then this instance
        //should immediatly terminate.
        eventHandle = CoreDLL.CreateEvent(IntPtr.Zero, true, 
                                          false, ApplicationEventName);
        int lastError = Marshal.GetLastWin32Error();
        //MessageBox.Show(String.Format("event handle {0}",eventHandle));
        
        if (0 == lastError)
        {
            Application.Run(new Form1());
        }
    }
    finally
    {
        //When the application is no longer 
        //running it should release the event
        if (eventHandle != IntPtr.Zero)
            CoreDLL.CloseHandle(eventHandle);
    }
}

When multiple instances of a program are created in this manner, you may want to send a notification to the first instance of the program so that it can respond to the event.

What's next?

This article is largely the result of research I am doing in preparation for software solutions that I plan to design. In the next part of my research, I will develop a solution for making the phone respond to other events not exposed directly through the CeRunAppAtEvent function.

History

  • 19 July 2008 - Initial publication.
  • 31 July 2008 - Added reference to SHCreateShortcut. (Thanks Zoomesh!)

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Joel Ivory Johnson
Software Developer
United States United States
Member
I attended Southern Polytechnic State University and earned a Bachelors of Science in Computer Science and later returned to earn a Masters of Science in Software Engineering.
 
For the past few years I've been providing solutions to clients using Microsoft technologies for web and Windows applications.
 
While most of my CodeProject.com articles are centered around Windows Phone it is only one of the areas in which I work and one of my interests. I also have interest in mobile development on Android and iPhone. Professionally I work with several Microsoft technologies including SQL Server technologies, Silverlight/WPF, ASP.Net and others. My recreational development interest are centered around Artificial Inteligence especially in the area of machine vision.
 

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionMinimize on startupmembernilavya31 Jul '09 - 5:39 
Hi,
 
Very nice article. I have a query. Is there a way to launch the application in a minimized state? It need not be present in the System tray to relaunch it. I have got other shortcuts for launching that.
 
Regards,
Nirav
 
dddd

GeneralAutostart disablingmembernamiiiii13 Jul '09 - 4:22 
Hi and thank you for your great article!
But i am left with a question, how do i unhook a application from autostart during uninstallation?
 
Best regards
GeneralRe: Autostart disablingmemberJoel Ivory Johnson21 Jul '09 - 13:45 
You will want to make use of NOTIFICATION_EVENT_NONE for that.
 
Joel Ivory Johnson
My site: J2i.net
Twitter: J2iNet

QuestionAn issue when calling CeRunAppAtTime at specified timemembervanhuycntt10 Jul '09 - 16:29 
Hi Joel,
I am using your block code to start app at specified time but it occurs a strange issue.
I found that it seemly created multiple instances every time it calls CeRunAppAtTime API,this makes
the system throw out of memory exception due to having many instances.
What happens to it?Please help me explain this issue.
Thanks.
GeneralVery similar to a "keep alive" app I'm trying to designmemberkmartburrito10 Jul '09 - 6:13 
Hi Joel,
 
Thanks for your article, it was a very good read. I've been envisioning an app for a while somewhat similar to yours, basically that would monitor a process or event, and listen for that event to stop. If it stops, the app would restart the event.
 
There's an app I use every day, and unfortunately when I moved devices, my new device utilizes the Touch Flo 3d interface, and that interface seems to randomly close my app. With the research I've done, I haven't come across an application that will keep another app alive if it's closed.
 
Possibly one of the events you could add that you spoke of would be a certain process disappearing. So, your app would listen for the process to terminate, and if it does, it starts a new one. Sounds fairly straightforward, and I hope that you could see the benefit of something like this, as I've yet to find an app that fills this requirement.
 
Thanks again!
-Nathan Rapp
GeneralRe: Very similar to a "keep alive" app I'm trying to designmemberJoel Ivory Johnson10 Jul '09 - 6:45 
It may not be a good idea to keep that app alive. Your app is getting closed because the system's free memory is falling below a certain threshold. When this happens the system sends out the WM_HIBERNATE message which is a request for applications to free up memory if they can. If enough applications don't free memory then the OS will begin closing programs. Keeping the program alive may not be advisable of the phone is low on memory.
 
Joel Ivory Johnson
My site: J2i.net
Twitter: J2iNet

GeneralInterestingmemberBrian Shifrin8 Jul '09 - 5:31 
You are saying you can start app before gwes?
 
And call coredll.ddl... while in OAL?
Questionevent for gps connectionmemberd3nika5 May '09 - 20:38 
hi..good article..I only have one question: is it posible to lunch an app when the gps app is connecting to the satellites?I ask this because I installed an app that I deleted afterwards but a notification appears every time the gps connects to a satellite that the system can't execute that app. The same notification appears even when the system starts-up. I tried registry and startup folder but no lock. My device has WM v.5.
Generallaunch app at USB cablememberjoshi aniruddha29 Apr '09 - 19:57 
how to detect programmatically that USB cable is connected to device?
Questionrun app. at incoming call...memberbarbod_blue21 Apr '09 - 21:37 
hi , how can i run my app. at incomming call???
on the other hand , how can i reject incoming call
with sms , by add a menu to incoming call (reject by sms)??!!??
please help me
tanx Smile | :)
Generalquery regarding Starting a program at a specified timememberkria_a30 Mar '09 - 21:11 
Hi Joel,
Great article ,but i have a doubt ,I tried using your code to start an application at a specified time to start an exe at a prticular time,but it doesn turn up.what can be the reason ?kindly help. :(
GeneralRe: query regarding Starting a program at a specified timememberJoel Ivory Johnson31 Mar '09 - 4:55 
That code sample was derived from some code that Jim Wilson wrote and posted on MSDN. As a diagnostic excercise try to run his code (from MSDN How-to[^]) and let me know whether or not that works. If it doesn't then we can diagnose it further.
 
Joel Ivory Johnson
My site: J2i.net
Twitter: J2iNet

GeneralRe: query regarding Starting a program at a specified timememberkria_a19 Apr '09 - 22:52 
Hi Joel,
I used the provided code and got success in invoking the application after that interval but there is one issue.If i schedule the operation after a prticular time and i restart the device in between,the application doesn't start as expected.can u please provide giudelines for the same.
Thanks in advance.
GeneralRe: query regarding Starting a program at a specified timememberJoel Ivory Johnson20 Apr '09 - 16:56 
The simplest solution would be to also make a shortcut entry in the \Windows\Startup folder so that when the device resets your program get's executed. I would suggest putting a parameter in this shortcut so that your program knows wheher it was started by user invokation or by the device being reset. If it were by the reset then just have your program reschedule it's startup and immediatly shutdown.
 
Joel Ivory Johnson
My site: J2i.net
Twitter: J2iNet

GeneralRe: query regarding Starting a program at a specified timememberkria_a22 Jun '09 - 0:21 
Hi Joel,
I am using the solution provided by you to start an application automatically but i have a strange issue.If after scheduling the application the PDA/device clock timezone/time is changed the application doesn start at the time scheduled on.
Can u please provide some help .I am stuck :(
GeneralRMSmemberEdyb25 Aug '08 - 2:38 
Hello,
 
Any idea on using RMS on windows mobile phones?
 
Thank you.
GeneralRe: RMSmemberJoel Ivory Johnson7 Dec '08 - 6:07 
Sorry, the only "RMS" of which I know is "Root Mean Squared," and I don't think that is the RMS of which you are asking. So to answer your question I've got no idea of using "RMS" on a Windows Mobile Phone.
 
Joel Ivory Johnson
My site: J2i.net

GeneralStartup Shortcut - Reference Code for Windows Mobile in VC++memberzoomesh31 Jul '08 - 0:22 
SHCreateShortcut( _T("\\Windows\\StartUp\\AppName.lnk"),
_T("\"\\Program Files\\AppName\\AppName.exe\""));
GeneralRe: Startup Shortcut - Reference Code for Windows Mobile in VC++memberJoel Ivory Johnson31 Jul '08 - 12:36 
Thanks for the API function name. I'll update the article.
 
Joel Ivory Johnson
Computer Science, spsu.edu

GeneralGood Articlemembermasterkid19 Jul '08 - 6:38 
Thanks for sharing your research with the community. It helped me a lot.
GeneralThank YoumemberBGaddis19 Jul '08 - 0:20 
Your method is far simpler than the one I've been using.
 
I write a lot of mobile applications for business and will be using this in all my future mobile applications.
 
Thanks again for your research.
 
Adding manpower to a late software project only makes it later.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130523.1 | Last Updated 31 Jul 2008
Article Copyright 2008 by Joel Ivory Johnson
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid