Search code examples
c#monoipc

Simple cross-platform process to process communication in Mono?


I'm working on a Mono application that will run on Linux, Mac, and Windows, and need the ability for apps (on a single os) to send simple string messages to each other.

Specifically, I want a Single Instance Application. If a second instance is attempted to be started, it will instead send a message to the single instance already running.

DBus is out, as I don't want to have that be an additional requirement. Socket communication seems to be hard, as windows seems to not allow permission to connect. Memory Mapped Files seems not to be supported in Mono. Named Pipes appears not to be supported in Mono. IPC seems not to be supported on Mono.

So, is there a simple method to send string messages on a single machine to a server app that works on each os, without requiring permissions, or additional dependencies?


Solution

  • I wrote about this on the mono-dev mailing list. Several general-purpose inter-process messaging systems were considered, including DBus, System.Threading.Mutex class, WCF, Remoting, Named Pipes... The conclusions were basically mono doesn't support Mutex class (works for inter-thread, not for inter-process) and there's nothing platform agnostic available.

    I have only been able to imagine three possible solutions. All have their drawbacks. Maybe there's a better solution available, or maybe just better solutions for specific purposes, or maybe there exist some cross-platform 3rd party libraries you could include in your app (I don't know.) But these are the best solutions I've been able to find so far:

    • Open or create a file in a known location, with exclusive lock. (FileShare.None). Each application tries to open the file, do its work, and close the file. If failing to open, Thread.Sleep(1) and try again. This is kind of ghetto, but it works cross-platform to provide inter-process mutex.
    • Sockets. First application listens on localhost, some high numbered port. Second application attempts to listen on that port, fails to open (because some other process already has it) so second process sends a message to the first process, which is already listening on that port.
    • If you have access to a transactional database, or message passing system (sqs, rabbitmq, etc) use it.
    • Of course, you could detect which platform you're on, and then use whatever works on that platform.