Interprocess Communication on Windows CE

Assume you have two processes running on the same WinCE device.  You want ProcB to give ProcA some data.  Or you want ProcB to tell ProcA to take some action on its behalf.  How do you do it?  I will describe 2 questionable and 2 good interprocess communication mechanism below.  I'm sure there's other ways - some of them good and some of them very hackish - that I'm not thinking of.  This is not an exhaustive list.

* Windows Sockets
One possible option is to open up a TCP/IP socket, bind it to localhost, and call accept() in ProcA.  When ProcB wants to communicate, it will create a socket of its own and connect() to the localhost socket.  Once the communication has been established, the apps can use standard Winsock APIs send/recv to pass data back and forth.

I do not recommend this mechanism.  There is extra overhead here you have to go through the TCP/IP stack to do the interproc communication, rather than a faster built-in mechanism.  There is also the danger that ProcA, if not coded properly, will allow remote network clients to connect to it.  This is a huge security concern.  A malicious user could remotely access your process, which probably does not have any authentication built-in, and take control.  It can also be quite clunky to program to this model.

* DCOM
Windows CE supports DCOM as an optional component.  When DCOM (not just "base COM") is included, then it is possible to access a COM object created in a "local server" running on the same device.  See CoCreateInstance and the CLSCTX_LOCAL_SERVER flag for more details.  Programming to this model lets DCOM handle a lot of ugly details for you and provides a programming model that may be familiar to people who have worked with Windows desktop programs.

This approach is not recommended either.  DCOM is optional and is not available on PocketPCs or SmartPhones.  Including DCOM in your image (if you're an OEM with Platform Builder) adds +500KB to your ROM size.

* Light-weight message queues
For completeness I listed sockets and DCOM.  I promise from now on we'll stick to good interprocess mechanisms :). 

The first is light-weight message queues.  Basically ProcA opens up a message queue and ProcB sends messages to it.  If ProcB wants a response, it creates its own message queue.  Since these were designed specifically for interproc communication on CE, they have a very usable API, take up minimal ROM, and are very fast.

Check out CreateMsgQueue, OpenMsgQueue, ReadMsgQueue, and WriteMsgQueue for more details.

* Services.exe
If you have a client/server relationship between ProcA and ProcB, it may make sense to put the "ProcA" into services.exe.  Services.exe is a system process that loads up service DLLs.  Services.exe makes it very easy for applications on the device to communicate to a service.  So in this model, ProcA isn't a process at all anymore.  Instead of ProcA.exe, you'd have ServiceA.dll.

I wrote a white paper on services.exe, including interproc communication, here.

* Services.exe versus light-weight message queues
When do you use services and when do you use message queues?  I'm biased in favor of services.exe since I wrote it :).  But I'll do my best to be impartial:

Services.exe PROs:
* By making "procA" as a service DLL, you don't take up one of the limited process slots.  It's also cheaper in terms of RAM to load a service DLL than to create a new process.
* Calls out the fact that "procA" is a server and that there is not a stand-alone application.  This can make the implementation cleaner and clearer.
* Also allows the service to be configured through a standard set of APIs.  This includes stopping, starting, refreshing, etc...

Services.exe CONs:
* On devices like newer versions of smartphone and PocketPC, your service DLL has to be signed to be trusted and loaded by services.exe.  This can be a hassle.  No such restrictions exist for the message queues.
* Again on trusted devices, code in services.exe will run with higher privelege than a user-mode application using the message queues would.  Code should be made to run with as low a security privelege as possible.
* If your application is not a true client/server model, but is more of a peer-to-peer (i.e. ProcA and ProcB both need to send messages to other, not just ProcB always calling ProcA to do work for it).  Services DLLs are not designed for the "peer-to-peer" model.

* Another good way to do interproc comm -- shared memory via file mapping (added 7/14/05)

Thanks to Paul Tobey for reminding me of another good way to do interproc communication - via the CreateFileMapping and related APIs.  Two processes open up the same memory mapped file and can share information that way.

[Author: John Spaith]