Respuestas:
Actualizar:
Casi cuatro años después de mi respuesta original y esta respuesta está muy desactualizada. Desde TopShelf apareció , el desarrollo de los servicios de Windows se volvió fácil. Ahora solo necesita descubrir cómo admitir la conmutación por error ...
Respuesta original:
Realmente no soy fanático del Programador de Windows. La contraseña del usuario debe proporcionarse como @moodforall señala arriba, lo cual es divertido cuando alguien cambia la contraseña de ese usuario.
La otra gran molestia con el Programador de Windows es que se ejecuta de forma interactiva y no como un proceso en segundo plano. Cuando aparezcan 15 ventanas de MS-DOS cada 20 minutos durante una sesión de RDP, se echará a perder por no haberlas instalado como servicios de Windows.
Independientemente de lo que elija, ciertamente le recomiendo que separe su código de procesamiento en un componente diferente de la aplicación de consola o el Servicio de Windows. Luego, tiene la opción de llamar al proceso de trabajo desde una aplicación de consola y conectarlo al Programador de Windows, o usar un Servicio de Windows.
Descubrirá que programar un servicio de Windows no es divertido. Un escenario bastante común es que tiene un proceso de ejecución prolongada que desea ejecutar periódicamente. Pero, si está procesando una cola, entonces realmente no desea que dos instancias del mismo trabajador procesen la misma cola. Por lo tanto, debe administrar el temporizador para asegurarse de que si su proceso de ejecución prolongada ha durado más que el intervalo de temporizador asignado, no se reinicia hasta que el proceso existente haya finalizado.
Después de haber escrito todo eso, piensas, ¿por qué no usé Thread.Sleep? Eso me permite dejar que el hilo actual siga ejecutándose hasta que haya finalizado y luego se activa el intervalo de pausa, el hilo se pone en suspensión y se inicia de nuevo después del tiempo requerido. ¡Ordenado!
Luego, lee todos los consejos en Internet con muchos expertos que le dicen que realmente es una mala práctica de programación:
Así que te rascarás la cabeza y pensarás para ti mismo, WTF, Deshacer pagos pendientes -> Sí, estoy seguro -> Deshacer todo el trabajo de hoy ... maldita sea, maldita sea ...
Sin embargo, me gusta este patrón, incluso si todos piensan que es una mierda:
Método OnStart para el enfoque de un solo hilo.
protected override void OnStart (string args) { // Create worker thread; this will invoke the WorkerFunction // when we start it. // Since we use a separate worker thread, the main service // thread will return quickly, telling Windows that service has started ThreadStart st = new ThreadStart(WorkerFunction); workerThread = new Thread(st); // set flag to indicate worker thread is active serviceStarted = true; // start the thread workerThread.Start(); }
El código crea una instancia de un hilo separado y le adjunta nuestra función de trabajo. Luego inicia el hilo y deja que el evento OnStart se complete, para que Windows no crea que el servicio está bloqueado.
Método de trabajo para el enfoque de un solo hilo.
/// <summary> /// This function will do all the work /// Once it is done with its tasks, it will be suspended for some time; /// it will continue to repeat this until the service is stopped /// </summary> private void WorkerFunction() { // start an endless loop; loop will abort only when "serviceStarted" // flag = false while (serviceStarted) { // do something // exception handling omitted here for simplicity EventLog.WriteEntry("Service working", System.Diagnostics.EventLogEntryType.Information); // yield if (serviceStarted) { Thread.Sleep(new TimeSpan(0, interval, 0)); } } // time to end the thread Thread.CurrentThread.Abort(); }
Método OnStop para el enfoque de un solo hilo.
protected override void OnStop() { // flag to tell the worker process to stop serviceStarted = false; // give it a little time to finish any pending work workerThread.Join(new TimeSpan(0,2,0)); }
Fuente: http://tutorials.csharp-online.net/Creating_a_.NET_Windows_Service%E2%80%94Alternative_1%3a_Use_a_Separate_Thread (Dead Link)
He estado ejecutando muchos servicios de Windows como este durante años y me funciona. Todavía no he visto un patrón recomendado con el que la gente esté de acuerdo. Solo haz lo que funcione para ti.
NT AUTHORITY\NetworkService
es una cuenta con privilegios limitados.
Alguna desinformación aquí. El Programador de Windows es perfectamente capaz de ejecutar tareas en segundo plano sin que aparezcan ventanas y sin necesidad de contraseña. Ejecútelo con la cuenta NT AUTHORITY \ SYSTEM. Utilice este interruptor schtasks:
/ ru SISTEMA
Pero sí, para acceder a los recursos de la red, la mejor práctica es una cuenta de servicio con una política de contraseña independiente que no caduque.
EDITAR
Dependiendo de su sistema operativo y los requisitos de la tarea en sí, es posible que pueda usar cuentas con menos privilegios que Localsystem con el /ru
opción.
Del fino manual ,
/RU username
A value that specifies the user context under which the task runs.
For the system account, valid values are "", "NT AUTHORITY\SYSTEM", or "SYSTEM".
For Task Scheduler 2.0 tasks, "NT AUTHORITY\LOCALSERVICE", and
"NT AUTHORITY\NETWORKSERVICE" are also valid values.
Programador de tareas 2.0 está disponible en Vista y Server 2008.
En XP y Server 2003, system
es la única opción.
Local Service
(alias NT AUTHORITY\LocalService
) en lugar de LocalSystem
(alias .\LocalSystem
). El primero tiene derechos limitados, mientras que el segundo es administrador
LocalService
y NetworkService
están disponibles en schtasks
Vista v2 en adelante y deben preferirse siempre que sea posible. En ese momento, esto se refería a schtasks
XP y Server 2003, que solo aceptan System
como parámetro según la versión anterior del manual technet.microsoft.com/en-us/library/bb490996.aspx
¿Cuál es la sobrecarga de iniciar y cerrar la aplicación? Cada dos minutos es bastante frecuente. Un servicio probablemente permitiría que el sistema funcione con más fluidez que ejecutar su aplicación con tanta frecuencia.
Ambas soluciones pueden ejecutar el programa cuando el usuario no está conectado, por lo que no hay diferencia. Sin embargo, escribir un servicio es algo más complicado que una aplicación de escritorio normal; es posible que necesite un cliente GUI separado que se comunique con la aplicación de servicio a través de TCP / IP, canalizaciones con nombre, etc.
Desde el punto de vista de un usuario, me pregunto cuál es más fácil de controlar. Tanto los servicios como las tareas programadas están prácticamente fuera del alcance de la mayoría de los usuarios no técnicos, es decir, ni siquiera se darán cuenta de que existen y se pueden configurar, detener, reprogramar, etc.
En el desarrollo de .NET, normalmente empiezo desarrollando una aplicación de consola, que ejecutará todos los registros de salida en la ventana de la consola. Sin embargo, esta es solo una aplicación de consola cuando se ejecuta con el argumento de comando /console
. Cuando se ejecuta sin este parámetro, actúa como un servicio de Windows, que seguirá ejecutándose en mi propio temporizador programado codificado personalizado.
Los servicios de Windows, en mi opinión, se utilizan normalmente para administrar otras aplicaciones, en lugar de ser una aplicación de larga duración. O ... son aplicaciones pesadas de ejecución continua como SQL Server, BizTalk, conexiones RPC, IIS (aunque IIS técnicamente descarga el trabajo a otros procesos).
Personalmente, prefiero las tareas programadas sobre los servicios de Windows para aplicaciones y tareas de mantenimiento repetitivas, como copia / sincronización de archivos, envío masivo de correo electrónico, eliminación o archivo de archivos, corrección de datos (cuando no hay otras soluciones disponibles).
Para un proyecto, he estado involucrado en el desarrollo de 8 o 9 servicios de Windows, pero estos se quedan en la memoria, inactivos, consumiendo 20 MB o más de memoria por instancia. Las tareas programadas harán su trabajo y liberarán la memoria de inmediato.
La palabra 'serv'ice comparte algo en común con' serv'er. Se espera que siempre esté ejecutándose y "sirva". Una tarea es una tarea.
Juego de rol. Si soy otro sistema operativo, aplicación o dispositivo y llamo a un servicio, espero que se esté ejecutando y espero una respuesta. Si yo (os, app, dev) solo necesito ejecutar una tarea aislada, entonces ejecutaré una tarea, pero si espero comunicarme, posiblemente comunicación bidireccional, quiero un servicio. Esto tiene que ver con la forma más efectiva de que dos cosas se comuniquen, o una sola cosa que quiera ejecutar una sola tarea.
Luego está el aspecto de la programación. Si desea que algo se ejecute a una hora específica, programe. Si no sabe cuándo lo va a necesitar, o si lo necesita "sobre la marcha", servicio.
Mi respuesta es de naturaleza más filosófica porque es muy similar a cómo los humanos interactúan y trabajan con otros. Cuanto más comprendamos el arte de la comunicación y las "entidades" comprendan su función, más fácil será esta decisión.
Dejando de lado toda la filosofía, cuando estás "haciendo prototipos rápidamente", como suele hacer mi departamento de TI, haces lo que sea necesario para llegar a fin de mes. Una vez que la creación de prototipos y la prueba de concepto están fuera del camino, generalmente en la planificación y el descubrimiento iniciales, debe decidir qué es más confiable para la sostenibilidad a largo plazo.
Bien, en conclusión, depende en gran medida de muchos factores, pero es de esperar que esto haya proporcionado información en lugar de confusión.
Un servicio de Windows no necesita que nadie inicie sesión, y Windows tiene instalaciones para detener, iniciar y registrar los resultados del servicio.
Una tarea programada no requiere que aprenda a escribir un servicio de Windows.
NT AUTHORITY\LocalService
, o NT AUTHORITY\NetworkService
). Cualquier contraseña proporcionada se ignora porque las cuentas no tienen contraseña.
¿Por qué no proporcionar ambos?
En el pasado, puse los bits 'centrales' en una biblioteca y envié una llamada a Whatever.GoGoGo () tanto en un servicio como en una aplicación de consola.
Con algo que disparas cada dos minutos, las probabilidades son decentes de que no esté haciendo mucho (por ejemplo, una función de tipo "ping"). Los contenedores no deberían contener mucho más que una única llamada a un método y algunos registros.
Esta es una pregunta antigua, pero me gustaría compartir con lo que me he enfrentado.
Recientemente me dieron el requisito de capturar la captura de pantalla de un radar (de un sitio web meteorológico) y guardarla en el servidor cada 10 minutos.
Esto requirió que usara WebBrowser. Por lo general, hago servicios de Windows, así que decidí hacer este servicio también, pero seguiría fallando. Esto es lo que vi en el Visor de eventos ruta del módulo de fallas del : C: \ Windows \ system32 \ MSHTML.dll
Como la tarea era urgente y tenía muy menos tiempo para investigar y experimentar, decidí usar una aplicación de consola simple y la activé como una tarea y se ejecutó sin problemas.
Me gustó mucho el artículo de Jon Galloway recomendado en la respuesta aceptada por Mark Ransom.
Recientemente, las contraseñas de los servidores se cambiaron sin reconocerme y todos los servicios no se ejecutaron porque no pudieron iniciar sesión. Entonces, las personas que afirman en el artículo comentan que esto es un problema. Creo que los servicios de Windows pueden enfrentar el mismo problema (por favor corríjame si me equivoco, solo soy un novato)
También lo mencionado, si se usa el programador de tareas, aparecen ventanas o la ventana de la consola. Nunca me he enfrentado a eso. Puede aparecer, pero al menos es muy instantáneo.
Generalmente, el mensaje central es y debe ser que el código en sí debe ser ejecutable desde todos y cada uno de los "desencadenadores / clientes". Por lo tanto, no debería ser ciencia de cohetes cambiar de un enfoque a otro.
En el pasado usábamos más o menos siempre los servicios de Windows, pero dado que también más y más clientes se cambian a Azure paso a paso y el cambio de una aplicación de consola (implementada como una tarea programada) a un WebJob en Azure es mucho más fácil que desde un servicio de Windows, por ahora nos centramos en las tareas programadas. Si nos encontramos con limitaciones, simplemente aumentamos el proyecto de servicio de Windows y llamamos a la misma lógica desde allí (siempre que los clientes estén trabajando en OnPrem ..) :)
BR, y
Los servicios de Windows quieren más paciencia hasta que esté listo. Tiene un poco de instalación y depuración. No tiene rostro. Si necesita una tarea que debe realizarse cada segundo, minuto u hora, debe elegir el Servicio de Windows.
La tarea programada se desarrolla rápidamente y tiene una cara. Si necesita una tarea diaria o semanal, puede utilizar Tarea programada.