¿Cómo comunicarse con un servicio de Windows desde una aplicación que interactúa con el escritorio?

Con .Net, ¿cuál es la mejor manera de interactuar con un servicio (es decir, cómo se comunica la mayoría de las aplicaciones de bandeja con sus servidores). Sería preferible si este método fuera multiplataforma también (trabajando en Mono, ¿así que supongo que no habrá comunicación remota?)


Editar:

Se me olvidó mencionar que todavía tenemos que admitir máquinas con Windows 2000 en el campo, por lo que WCF y todo lo que se encuentre por encima de .Net 2.0 no funcionarán.

Tenga en cuenta que si planea implementarlo finalmente en Windows Vista o Windows Server 2008, no funcionarán muchas formas en que esto se pueda hacer hoy. Esto se debe a la introducción de una nueva característica de seguridad llamada “Aislamiento de sesión 0”.

La mayoría de los servicios de Windows se han movido para ejecutarse en la Sesión 0 ahora con el fin de aislarlos adecuadamente del rest del sistema. Una extensión de esto es que el primer usuario que inicia sesión en el sistema ya no se coloca en la Sesión N. ° 0, sino que se coloca en la Sesión 1. Y por lo tanto, el aislamiento romperá el código que hace ciertos tipos de comunicación entre servicios y aplicaciones de escritorio.

La mejor forma de escribir código hoy que funcionará en Vista y Server 2008 en el futuro cuando se realiza la comunicación entre servicios y aplicaciones es usar una API adecuada de procesos cruzados como RPC, Canalizaciones con nombre, etc. No use SendMessage / PostMessage como lo hará fallar en la sesión 0 Aislamiento.

http://www.microsoft.com/whdc/system/vista/services.mspx

Ahora, dados tus requerimientos, vas a estar en un pequeño aprieto. Para las preocupaciones multiplataforma, no estoy seguro si Remoting sería compatible. Es posible que deba desplegar e ir hasta los sockets: http://msdn.microsoft.com/en-us/library/system.net.sockets.aspx

Si se trata de una aplicación de bandeja y no es un servicio real, tenga cuidado con la forma de configurar sus comunicaciones si usa pipes o TCP / IP. Si varios usuarios inician sesión en una máquina (Citrix, Escritorio remoto) y cada usuario inicia un “servicio” de la aplicación de bandejas, puede encontrarse con una situación en la que tiene múltiples procesos que intentan utilizar el mismo puerto o conducto conocido. Por supuesto, esto no es un problema si no planea admitir varias canalizaciones o si tiene un servicio real en lugar de una aplicación de bandeja que se ejecuta en cada shell de usuario.

Haga que su servicio escuche 127.0.0.1 en un puerto predefinido con un viejo zócalo de transmisión TCP. Conéctese a ese puerto desde su aplicación de escritorio.

Es completamente simple y es completamente multiplataforma.

¿Alguno de ustedes realmente intentó comunicarse de forma remota con Mono? Funciona bien. Puede toparse con algunos casos de esquina, pero esto es muy poco probable. Simplemente pruebe su aplicación para comunicación remota multiplataforma (MS.Net <-> Mono) de vez en cuando para detectar posibles problemas técnicos. Y comienza con un Mono reciente, 2.4.2 es actual.

Remoting es una opción, pero no es multiplataforma. Algunas otras formas son usar canalizaciones con nombre, IPC o eventos kernel.

¡Curiosamente, iba a recomendar Remoting! Las Notas de la versión de Mono 1.0 (de archive.org porque falta la ubicación original) mencionan System.Runtime.Remoting.dll como una biblioteca compatible y no dice nada sobre problemas conocidos.

Si la comunicación remota está fuera, es probable que deba implementar su propio protocolo de encuadre de mensajes TCP. Windows no tiene un equivalente de sockets de dominio UNIX para la comunicación en la misma máquina.

La mayoría de los servicios que tienen un componente GUI se ejecutan como un usuario designado y se les permite el acceso al escritorio. Esto le permite acceder a él a través de COM o .NET pero solo localmente (a menos que quiera complicarse)

Personalmente, abro un viejo socket común en el servicio: su multiplataforma, permite múltiples clientes, permite que cualquier aplicación acceda a él, no confía en que la seguridad de Windows se abra para él, y permite que su GUI se escriba en cualquier idioma que te gusta (ya que todo admite sockets).

Para una aplicación de bandeja, desearía que se comunique un protocolo simle; también podría usar un sistema de estilo REST para enviar comandos a él, y transmitir XML (yuk) o un formato de datos personalizado.