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]
Comments
- Anonymous
July 13, 2005
Another CON of the services approach is that you cannot use it from managed code (whereas p2p queues are fine :-) - Anonymous
April 30, 2006
 
I wanted to make a client-server application that would run both on WinCE/Windows Mobile 5.0... - Anonymous
May 12, 2006
I read the paper on services.exe, and I wonder... Can multiple IOCTLs be in progress at once via handles from separate calls to createfile("SVC0:"...), and can they each take an arbitrarily long time?
Also, does Daniel Moth mean that you can't write a client of a service in .NET, or just that you can't write a service in .NET? - Anonymous
May 18, 2006
Daniel - Yes, multiple apps can be simultaneously blocked in one "SVC0: " for arbitrary amounts of time. There's mechanisms for unblocking these for say an app shutdown (or crash), but the service has to be smart. My services.exe white paper, referenced on this blog but published on MSDN proper, deals with this to some extent.
You can absolutely write clients of services in .Net -- for instance the System.Messaging stuff is just an elaborate P/Invoke into the MSMQ API's, which is itself just an elaborate wrapper into services.exe DeviceIoControl calls. Writing services in .Net is not allowed.
John Spaith - Anonymous
May 19, 2006
Mr Spaith, thanks for the clarification. I've got another question that has cropped up while considering the proper use of DeviceIOControl...
Is there a size limit on either the BufIn or BufOut? I ask because I'd like to send a big bit of data back and forth and want to use the packetising behaviour of DeviceIOControl to avoid having to specify a stream protocol and implementing xxx_Read/Write as well as xxx_IOControl. I couldn't see any statement either way at MSDN. - Anonymous
May 19, 2006
I've looked at IOCTL_PSL_NOTIFY, but pkfuncs.h is not present in the windows mobile 5.0 pocket pc SDK and the text string "IOCTL_PSL_NOTIFY" isn't present in the SDK at all. Also, the DEVICE_PSL_NOTIFY structure that should be passed in tells you which process is dying but there is no way I can see to link that to the xxx_IOControl calls that are blocked when implementing a service, so no way to terminate them prematurely.
Is there a solution to this problem for folks that aren't an OEM? - Anonymous
June 13, 2006
Daniel - sorry for delay, as you can probably guess I don't check blog feedback enough. In future, newsgroups are the best place to catch me. Issue is I haven't trained myself to use the blog and I'm a creature of habit, and I don't like the interface as much as I like newsgroup reader.
I know about the IOCTLs & structs not being defined in SDK. I think there's ways you can get the OEM header files, which is all you need to kickstart your development. I don't really know how you can do this (legally) though, but someone on newsgroup may.
There's no limit of DeviceIoControl() that I know of -- it's just a pointer that gets mapped with the same mechanism ReadFile & WriteFile pointers are marshalled.
John Spaith - Anonymous
October 20, 2006
COM on Windows Mobile only supports creating in-proc COM objects, not out-of-proc or COM objects on remote - Anonymous
January 31, 2007
What about named pipes? I thought of using RAPI and named pipes to communicate to my processes on the device. What do you think? - Anonymous
January 31, 2007
The comment has been removed - Anonymous
March 05, 2008
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnce50/html/implement_network_service.asp cannot be found.... - Anonymous
March 06, 2008
Thanks MD for alerting me to the broken link - I've cleaned it up. John