Partilhar via


Why your application shouldn't call CreateProcess(services.exe,configuration command,...) directly

On Windows CE, services.exe has a command line interface that allows you to control the state of running services.  See the services.exe white paper, "Services.exe Command-Line Interface and Service Configuration" for details about how this works.

This cmd line interface was really only intended for development purposes.  It assumes you, the engineer, are developing a service and you need to stop/restart it, or you need to unload it, recompile the DLL, and reload it.  Being able to use the common command line parser to do common functionality makes this easier.

For applications that need to control services on shipping devices, we have an API family to do this.  For instance RegisterService, DeviceIoControl (with well defined IOCTLs in service.h.), EnumServices, and so on.  Unfortunately a number of applications don't call these APIs but instead do a CreateProcess(L"services.exe","Command I want to run",...).

This is bad for two reasons.  First, it's less efficient.  When you make an API call you only have to do an inter-process communication call which is pretty cheap.  CreateProcess is much more expensive.

The second, bigger problem is that it won't work anymore on PocketPC and SmartPhone 2005 devices or later.  This functionality is now disabled by default.  It can only be reenabled by setting the registry or value HKLM\Services\AllowCmdLine to be non-zero.  Note that this is a protected registry key, so your application if it's not trusted will not have access to go change this on its own. 

Services command line parsing was disabled due to security concerns - basically an untrusted application could call CreateProcess("services",...) and the service would be tricked into thinking that a trusted process had initiated whatever command line request it received.  Now that CE has the trusted/untrusted model on shipping devices, we had to fix this.

So the bottom line is have fun with the cmd line interface for your debugging, but don't rely on it in the actual product.

[Author: John Spaith]

Comments

  • Anonymous
    May 12, 2006
    The comment has been removed
  • Anonymous
    May 18, 2006
    The comment has been removed
  • Anonymous
    December 04, 2006
    In CE 6.0, one of the things we changed was naming services.exe to be servicesd.exe. I mentioned it at
  • Anonymous
    September 02, 2007
    Can calling EnumServices() be accomplished from .net?  I tried this, but I get a NotSupportedException.       [DllImport("coredll.dll", SetLastError=true)]       public static extern int EnumServices(           [MarshalAs(UnmanagedType.LPArray)]           IntPtr bufptr,           out int entries,           ref int ServiceLen)       public static void ReadServices()       {           const int count = 100;           try           {               ServiceEnumInfo[] buf = new ServiceEnumInfo[count];               int buflen = 10000;               IntPtr ptr;               ptr = Marshal.AllocHGlobal(buflen);               int numRunningServices;               int rc = EnumServices(ptr, out numRunningServices, ref buflen);               Marshal.FreeHGlobal(ptr);           }           catch (Exception e)           {           }
  • Anonymous
    June 19, 2009
    PingBack from http://mydebtconsolidator.info/story.php?id=19931