Pregunta

Tengo una aplicación c # que se ejecuta como un servicio de Windows que controla las conexiones de socket y otras cosas. Además, existe otra aplicación de formularios de Windows para controlar y configurar este servicio (systray con inicio, detener, mostrar formulario con parámetros de configuración).

Estoy usando .net a distancia para hacer el IPC y estuvo bien, pero ahora quiero mostrar un poco de tráfico real y otros informes y la comunicación remota no cumplirá con mis requisitos de rendimiento. Así que quiero combinar ambas aplicaciones en una sola.

Aquí está el problema:

Cuando empecé el formulario desde el servicio de Windows, no sucedió nada. Busqué en Google y encontré que tengo que hacer clic con el botón derecho en el servicio, ir a Iniciar sesión y revisar " Permitir que el servicio interactúe con el escritorio " opción. Ya que no quiero pedirles a mis usuarios que hagan eso, obtuve algo de código en Google nuevamente para establecer esta opción en regedit del usuario durante el tiempo de instalación. El problema es que incluso configurando esta opción, no funciona. Tengo que abrir las opciones de inicio de sesión del servicio (está marcado), desmarcar y volver a marcar.

Entonces, ¿cómo resolver eso? ¿Cuál es la mejor manera de tener un servicio de Windows con un control del sistema en el mismo proceso, disponible para cualquier usuario que inicie sesión?

ACTUALIZACIÓN: Gracias por los comentarios hasta ahora, chicos. Estoy de acuerdo en que es mejor usar IPC y sé que es malo mezclar servicios de Windows e interfaces de usuario. A pesar de que quiero saber cómo hacerlo.

¿Fue útil?

Solución

Dos procesos separados que se comunican utilizando la tecnología de su elección. Los servicios con IU son una mala idea . No sigas por este camino, te arrepentirás.

He tenido muy buenos resultados al tener una comunicación de servicio a través de una simple conexión de socket: documente bien su protocolo de servicio, sea lo más simple posible y será más fácil de lo que cree.

Otros consejos

En la práctica, no debe asociar su servicio con la IU de administración.

Estoy de acuerdo con Greg. Tal vez usted podría examinar un mecanismo de IPC diferente. Tal vez use sockets y su propio protocolo. O, si su aplicación de control de servicio solo puede controlar el servicio en la máquina local, puede usar canalizaciones con nombre (incluso más rápido).

Aquí hay una manera de mezclar servicios y formularios

http://www.codeproject.com/KB/system/SystemTrayIconInSvc.aspx

Descubrí cómo hacer esto en esto artículo (haga clic en el enlace " Cambiar " en la tabla Métodos).

string wmiPath = "Win32_Service.Name='" + SERVICE_NAME + "'";
using (ManagementObject service = new ManagementObject(wmiPath))
{
    object[] parameters = new object[11];
    parameters[5] = true;  // Enable desktop interaction
    service.InvokeMethod("Change", parameters);
}

Tengo la solución en unos pocos pasos, este es el plan

  1. no vamos a crear un proyecto de servicio con un formulario de Windows, sino que crearemos una solución de estudio visual que contenga un proyecto de servicio de Windows, un proyecto de Windows y un proyecto de instalación.

  2. La idea es tener una base de datos o un archivo o cualquier cosa con la que se sienta cómodo almacenando datos en los que almacenaría los parámetros que su servicio de Windows utilizará siempre para ejecutar. Por lo tanto, su servicio de Windows y su aplicación de formulario de Windows deberían poder modificar y recuperar datos de él.

  3. Al formulario principal de su aplicación de Windows, arrastre y suelte un NotifyIcon en el formulario, en la pestaña de propiedades, busque y seleccione una imagen .ico (puede crear una en Visual Studio pero ese es otro tema que puede obtener en google o contactarme) que se mostrará en la bandeja del sistema cuando ejecute la aplicación y el formulario principal esté activo o se muestre, pruébelo, ejecute la aplicación.

  4. Agregue ambos como resultados en el proyecto de configuración de la solución. Para agregar un proyecto a un proyecto de configuración, deben estar en la misma solución. Haga clic con el botón derecho en el proyecto de configuración en el explorador de soluciones, resalte agregar y luego seleccione la salida del proyecto, agregue el servicio de Windows y las salidas de formulario de ventanas y las verá en el explorador de soluciones debajo del proyecto de configuración.

  5. agregar un servicio de Windows va más allá de esto, pero también es otro tema google,

  6. Crear un acceso directo para la aplicación de Windows y agregarlo a la carpeta de inicio también es otro tema de google o contáctame.

    NOTA Programe su formulario de tal manera que el botón de cierre no se muestre y el formulario vaya. Me.visible = falso y hacer doble clic en el icono en la bandeja del sistema es la única forma de configurarme.visible = verdadero.que cada vez que se inicia la computadora, su aplicación de formulario de Windows también se inicia y se configura visible a falso de inmediato, pero como tiene una notificación con un icono, se mostrará en la bandeja del sistema y al hacer doble clic en él se hace visible el formulario para editar el configuración que está almacenando para el servicio, el servicio también se inicia automáticamente, ya que lo habría configurado para configurar el servicio en el proyecto de configuración. mi correo es iamjavademon@gmail.com para una mejor ilustración usando capturas de pantalla y explicar en su totalidad

Es muy simple: su necesidad de crear un hilo para realizar eventos de aplicación. Así (código fuente para C ++ con CLR, pero puede hacer esto en C #):

ref class RunWindow{
public:
    static void MakeWindow(Object^ data)
    {
        Application::EnableVisualStyles();
        Application::SetCompatibleTextRenderingDefault(false); 

        Application::Run(gcnew TMainForm());
    };
};

Y crea un hilo en main

int main(array<System::String ^> ^args)
{
    bool bService = RunAsService(L"SimpleServiceWithIconInTrayAndWindow");

    if (bService)
    {

        System::Threading::Thread ^thread = gcnew System::Threading::Thread(gcnew ParameterizedThreadStart(RunWindow::MakeWindow));
        thread->Start();

        ServiceBase::Run(gcnew simpleWinService());
        Application::Exit();
    }
    else
    {
        Application::EnableVisualStyles();
        Application::SetCompatibleTextRenderingDefault(false); 

        // Create the main window and run it
        Application::Run(gcnew TMainForm());
    }

    return 0;
}

Los principales problemas con los servicios interactivos son:

  • Seguridad: otro proceso podría enviarle mensajes a través de su bomba de mensajes, obteniendo acceso a un proceso SISTEMA / LOCAL.

  • Incompleta: un servicio interactivo nunca ve mensajes de shell, por lo que no puede interactuar con los íconos del área de notificación.

Usamos regularmente conexiones TCP y UDP para pasar información de servicios a otros ejes, y, en algunos casos, MSMQ.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top