Partager via


Autorun installation

My first post on this blog was about deploying application and I touched briefly on autorun.exe. I have been asked several times to expand on this and go into the details so here it is!

Windows Mobile supports a simple, automated way of installing and uninstalling applications from removable media cards. When an SD card or CF card is inserted into a device the OS catches the hardware event and looks on the storage card for a directory that matches the processor type.

All Windows Mobile devices after Pocket PC 2000 have an ARM V4 instruction set so in general 2577 is all you need to know. Other processor types are useful to know for embedded CE systems, Pocket PC 2000 device and for the current emulators:

ARMV4 (or more accurately SA1100): 2577

X86: 686

ARM 720: 1824

MIPS: 4000

SH3: 10003

If the correct processor specific directory exists the OS looks for a file named 'Autorun.exe' and attempt to copy it to the \windows directory. Once the file is copied it is executed with a single parameter string ‘install’.

The autorun.exe is just a standard PE format executable. You can insert UI if you want, or even write the application in managed code so long as Compact Framework is present on the device.

In many cases the autorun application is used to scan and install CAB files from the inserted card, but beware because the autorun is executed from the \windows directory *not* from the original location. On modern devices it’s quite a challenge to locate the card that was just inserted. There is an api: SHGetAutoRunPath that can help if there is just one card present in the device, but most devices today have more than one expansion slots and often include internal card: these are spare areas of ROM memory, unused by the OS. OEM’s often wrap this spare storage as a flash card for things like data backup.

When a storage card is removed from the device the OS looks in the \windows directory and re-runs autorun.exe but with ‘uninstall’ as a parameter. Once the autorun process has completed, the autorun.exe file is deleted from the device. This is an ideal opportunity to remove applications or to do some tidy-up on the device.

There are a couple of things to be aware of:

1> If an autorun.exe already exists in the \windows directory when a new card is inserted into the device then no new autorun will be copied into \windows, but the existing autorun will execute! So imagine a device with both SD and CF card slots. SD1 card is inserted and the autorun gets copied and run with ‘install’ parameter. Then CF1 card is inserted but because the SD1 card autorun exists in the windows directory no copy takes place. However the existing SD1 autorun *will* still be run with the ‘install’ parameter. Now remove the CF1 card. The SD1 autorun in the \windows directory will be executed with the ‘uninstall’ parameter and then deleted. Now remove SD1, nothing happens.

2> Removing or inserting cards while the device is in an ‘off’ state is still picked up when the power is turned back on. The OS then catches up and takes the relevant steps. Obviously if a card is inserted and removed while the power is off, nothing happens.

3> If the OEM has wrapped up spare flash ROM space as a removable card then it obeys the same rules. Putting \2577\autorun.exe on the internal storage card will cause it to run when that card is ‘inserted’. An internal card is ‘inserted’ when a soft or hard reset takes place. There is no practical way of removing an internal card. This can be a great way of installing apps on hard reset. Be aware that OEM’s have the freedom to implement this behavior differently on their device.

Here is an example of an autorun written in C++ (disclaimer applies):

// Autorun.cpp : Defines the entry point for the application.

//

#include "stdafx.h"

#include "projects.h" // Defines the ‘project’ api’s like FindFirstFlashCard api’s

int WINAPI WinMain( HINSTANCE hInstance,

                        HINSTANCE hPrevInstance,

                        LPTSTR lpCmdLine,

                        int nCmdShow)

{

      if (0==wcscmp(lpCmdLine,L"install"))

      {

            MessageBox(NULL,L"About to install, press OK to start",L"Media card install",MB_OK);

            WIN32_FIND_DATA fflash;

            HANDLE findflash = FindFirstFlashCard(&fflash);

            while (INVALID_HANDLE_VALUE != findflash)

            {

                  TCHAR FileName[MAX_PATH];

                  wsprintf(FileName,L"\\%s\\*.cab",fflash.cFileName);

                  WIN32_FIND_DATA ffile;

                  HANDLE findfile = FindFirstFile(FileName,&ffile);

                  while (INVALID_HANDLE_VALUE != findfile)

                  {

                        TCHAR fullPath[MAX_PATH];

                        wsprintf(fullPath,L"\\%s\\%s",fflash.cFileName, ffile.cFileName);

      SHELLEXECUTEINFO sei;

                        memset(&sei,0,sizeof(SHELLEXECUTEINFO));

                        sei.cbSize = sizeof(SHELLEXECUTEINFO);

                        sei.fMask = 0;

                        sei.hwnd = NULL;

                        sei.lpVerb = NULL;

                        sei.lpFile = fullPath;

                        sei.lpParameters = L"";

                        sei.nShow = SW_SHOWNORMAL;

                        ShellExecuteEx(&sei);

                        if (!FindNextFile(findfile,&ffile))

                        {

                              FindClose(findfile);

                              findfile = INVALID_HANDLE_VALUE;

                        }

                  }

                  // Now install the CPF files

                  wsprintf(FileName,L"\\%s\\*.cpf",fflash.cFileName);

                  findfile = FindFirstFile(FileName,&ffile);

                  while (INVALID_HANDLE_VALUE != findfile)

                  {

                        TCHAR fullPath[MAX_PATH];

                        wsprintf(fullPath,L"\\%s\\%s",fflash.cFileName, ffile.cFileName);

                        SHELLEXECUTEINFO sei;

                        memset(&sei,0,sizeof(SHELLEXECUTEINFO));

                        sei.cbSize = sizeof(SHELLEXECUTEINFO);

                        sei.fMask = 0;

                        sei.hwnd = NULL;

                        sei.lpVerb = NULL;

                        sei.lpFile = fullPath;

                        sei.lpParameters = L"";

                        sei.nShow = SW_SHOWNORMAL;

                        ShellExecuteEx(&sei);

                        if (!FindNextFile(findfile,&ffile))

                        {

                              FindClose(findfile);

                              findfile = INVALID_HANDLE_VALUE;

                        }

                  }

                  // Look for the next card

                  if (FALSE==FindNextFlashCard(findflash, &fflash))

                  {

                        FindClose(findflash);

                        findflash = INVALID_HANDLE_VALUE;

                  }

            }

      }

      return 0;

}

 

 

Windows Mobile 5.0

Things are a little different with WM5.0 …

With Windows Mobile 5.0 the Autoexec.exe file is copied to a sub directory specific to the storage card name. For example, if the storage card is named: ‘Storage Card2’ then the autoexec.exe is copied to and run from ‘\windows\autorun\Storage Card2’. This means that the OS can track each storage slot individually and avoid the multi card clash.

 

Marcus

Comments

  • Anonymous
    June 17, 2005
    oops, forgot to add a docs reference:
    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/guide_ppc/html/ppc_programming_pocket_pc_2002_balr.asp


    Marcus

  • Anonymous
    June 17, 2005
    Marcus, did you mean "Autoexec.exe" when discussing Windows Mobile 5.0 has the name changed? If so, will it also be backward compatible with SD installation cards built for Windows Mobile 2003 ?

  • Anonymous
    June 17, 2005
    Hey Marcus...

    Thanks for starting to fill in the blanks for deployment. I'm looking to refresh my posting on mobile app deployment this will definitely get a link!

    Great stuff...cheers,

    James

  • Anonymous
    June 18, 2005
    The comment has been removed

  • Anonymous
    June 19, 2005
    Ooops! The file name for Windows Mobile 5 is unchanged "Autorun.exe".

    Daniel has a good point, this is default functionality for Windows Mobile only. Its possible to duplicate this functionality on a bespoke CE platform but its not for free, the OEM will have to write their own code to make this happen.

    Marcus

  • Anonymous
    June 19, 2005
    This topic rates in my top 3 'soapbox' issues and it’s about time I vented some of my inner frustration... so...

  • Anonymous
    August 24, 2005
    Daniel & Marcus,

    Thanks for pointing it out, I just tested it on my CE 4.2 devices, autorun.exe doesn't work. I wrote a little program to call the SHGetAutoRunPath, it does return DOC486autorun.exe, but looks like it doesn't run the autorun.exe there.

    So what kind of changes needed to apply on Explorer shell? any detail suggestions?

    Thanks,

    -Allen

  • Anonymous
    June 21, 2006
    How to disable autorun.exe in WM5.

  • Anonymous
    November 06, 2006
    This topic rates in my top 3 'soapbox' issues and it’s about time I vented some of my inner frustration...

  • Anonymous
    June 27, 2007
    The comment has been removed

  • Anonymous
    July 22, 2007
    Quiero el instalador de autorun.exe

  • Anonymous
    September 15, 2008
    The comment has been removed

  • Anonymous
    May 07, 2009
    Is this still applicable for new version of Windows mobile OS like 6 and 6.1??