Réponses:
Mettre à jour:
Près de quatre ans après ma réponse initiale et cette réponse est très dépassée. Depuis l' arrivée de TopShelf , le développement des services Windows est devenu facile. Il ne vous reste plus qu'à comprendre comment prendre en charge le basculement ...
Réponse originale:
Je ne suis vraiment pas fan de Windows Scheduler. Le mot de passe de l'utilisateur doit être fourni comme @moodforall souligne ci-dessus, ce qui est amusant lorsque quelqu'un change le mot de passe de cet utilisateur.
L'autre inconvénient majeur du planificateur Windows est qu'il s'exécute de manière interactive et non en tant que processus d'arrière-plan. Lorsque 15 fenêtres MS-DOS apparaissent toutes les 20 minutes pendant une session RDP, vous vous coupez qui ne les a pas installées en tant que services Windows à la place.
Quoi que vous choisissiez, je vous recommande certainement de séparer votre code de traitement en un composant différent de l'application console ou du service Windows. Ensuite, vous avez le choix, soit d'appeler le processus de travail à partir d'une application console et de le connecter au planificateur Windows, soit d'utiliser un service Windows.
Vous constaterez que planifier un service Windows n'est pas amusant. Un scénario assez courant est que vous avez un processus de longue durée que vous souhaitez exécuter périodiquement. Mais, si vous traitez une file d'attente, vous ne voulez vraiment pas que deux instances du même worker traitent la même file d'attente. Vous devez donc gérer la minuterie, pour vous assurer que si votre processus de longue durée a duré plus longtemps que l'intervalle de minuterie attribué, il ne redémarre pas tant que le processus existant n'est pas terminé.
Après avoir écrit tout cela, vous pensez, pourquoi n'ai-je pas simplement utilisé Thread.Sleep? Cela me permet de laisser le thread actuel continuer à fonctionner jusqu'à ce qu'il soit terminé, puis l'intervalle de pause entre en action, le thread se met en veille et redémarre après le temps requis. Soigné!
Ensuite, vous lisez tous les conseils sur Internet avec de nombreux experts vous disant à quel point c'est une très mauvaise pratique de programmation:
Alors vous vous gratterez la tête et vous penserez à vous-même, WTF, Annuler les contrôles en attente -> Oui, j'en suis sûr -> Annuler tout le travail d'aujourd'hui ..... putain, putain, putain ....
Cependant, j'aime ce modèle, même si tout le monde pense que c'est de la merde:
Méthode OnStart pour l'approche à un seul thread.
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(); }
Le code instancie un thread séparé et y attache notre fonction de travail. Ensuite, il démarre le thread et laisse l'événement OnStart se terminer, de sorte que Windows ne pense pas que le service est bloqué.
Méthode de travail pour l'approche à un seul thread.
/// <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éthode OnStop pour l'approche à un seul thread.
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)); }
Source: http://tutorials.csharp-online.net/Creating_a_.NET_Windows_Service%E2%80%94Alternative_1%3a_Use_a_Separate_Thread (lien mort)
J'exécute beaucoup de services Windows comme celui-ci depuis des années et cela fonctionne pour moi. Je n'ai toujours pas vu de modèle recommandé sur lequel les gens sont d'accord. Faites simplement ce qui fonctionne pour vous.
NT AUTHORITY\NetworkService
est un compte avec des privilèges limités.
Une certaine désinformation ici. Windows Scheduler est parfaitement capable d'exécuter des tâches en arrière-plan sans que les fenêtres n'apparaissent et sans mot de passe requis. Exécutez-le sous le compte NT AUTHORITY \ SYSTEM. Utilisez ce commutateur schtasks:
/ ru SYSTÈME
Mais oui, pour accéder aux ressources réseau, la meilleure pratique est un compte de service avec une stratégie de mot de passe non expirante distincte.
ÉDITER
Selon votre système d'exploitation et les exigences de la tâche elle-même, vous pourrez peut-être utiliser des comptes moins privilégiés que Localsystem avec le /ru
option.
Du beau manuel ,
/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.
Le planificateur de tâches 2.0 est disponible à partir de Vista et Server 2008.
Dans XP et Server 2003, system
c'est la seule option.
Local Service
(aka NT AUTHORITY\LocalService
) plutôt que LocalSystem
(aka .\LocalSystem
). Le premier a des droits limités, tandis que le second est administrateur
LocalService
et NetworkService
sont disponibles à partir de schtasks
v2 Vista et devraient être préférés dans la mesure du possible. À l'époque, cela faisait référence à schtasks
XP et Server 2003 qui n'acceptent que le System
comme paramètre selon l'ancienne version du manuel technet.microsoft.com/en-us/library/bb490996.aspx
Quels sont les frais généraux liés au démarrage et à la fermeture de l'application? Toutes les deux minutes, c'est assez souvent. Un service permettrait probablement au système de fonctionner plus facilement que d'exécuter votre application si fréquemment.
Les deux solutions peuvent exécuter le programme lorsque l'utilisateur n'est pas connecté, donc aucune différence. Cependant, l'écriture d'un service est un peu plus complexe qu'une application de bureau classique - vous pouvez avoir besoin d'un client GUI séparé qui communiquera avec l'application de service via TCP / IP, des canaux nommés, etc.
Depuis le point de vue d'un utilisateur, je me demande lequel est le plus facile à contrôler. Les services et les tâches planifiées sont à peu près hors de portée pour la plupart des utilisateurs non techniques, c'est-à-dire qu'ils ne se rendront même pas compte qu'ils existent et peuvent être configurés / arrêtés / reprogrammés et ainsi de suite.
Dans le développement .NET, je commence normalement par développer une application console, qui exécutera toutes les sorties de journalisation dans la fenêtre de la console. Cependant, il s'agit uniquement d' une application console lorsqu'elle est exécutée avec l'argument de commande /console
. Lorsqu'il est exécuté sans ce paramètre, il agit comme un service Windows, qui restera en cours d'exécution sur mon propre minuteur programmé codé personnalisé.
Je pense que les services Windows sont normalement utilisés pour gérer d'autres applications, plutôt que pour être une application de longue durée. OU .. ils exécutent en permanence des applications lourdes comme SQL Server, BizTalk, RPC Connections, IIS (même si IIS décharge techniquement le travail vers d'autres processus).
Personnellement, je préfère les tâches planifiées aux services Windows pour les tâches de maintenance répétitives et les applications telles que la copie / synchronisation de fichiers, l'envoi d'e-mails en masse, la suppression ou l'archivage de fichiers, la correction des données (lorsque d'autres solutions de contournement ne sont pas disponibles).
Pour un projet, j'ai été impliqué dans le développement de services Windows 8 ou 9, mais ceux-ci restent en mémoire, inactifs, consommant 20 Mo ou plus de mémoire par instance. Les tâches planifiées feront leur travail et libéreront la mémoire immédiatement.
Le mot 'serv'ice a quelque chose en commun avec' serv'er. On s'attend à ce qu'il soit toujours en cours d'exécution, et 'serv'e. Une tâche est une tâche.
Jeu de rôle. Si je suis un autre système d'exploitation, une autre application ou un autre appareil et que j'appelle un service, je m'attends à ce qu'il fonctionne et j'attends une réponse. Si je (os, app, dev) juste besoin d'exécuter une tâche isolée, alors j'exécuterai une tâche, mais si je prévois de communiquer, éventuellement une communication bidirectionnelle, je veux un service. Cela a à voir avec le moyen le plus efficace pour deux choses de communiquer, ou une seule chose qui veut exécuter une seule tâche.
Ensuite, il y a l'aspect de la planification. Si vous voulez que quelque chose s'exécute à une heure précise, planifiez. Si vous ne savez pas quand vous en aurez besoin, ou quand vous en aurez besoin "à la volée", faites un service.
Ma réponse est de nature plus philosophique car c'est très similaire à la façon dont les humains interagissent et travaillent avec les autres. Plus nous comprenons l'art de la communication et les «entités» comprennent leur rôle, plus cette décision devient facile.
Toute philosophie mise à part, lorsque vous «prototypez rapidement», comme le fait souvent mon département informatique, vous faites tout ce que vous devez pour joindre les deux bouts. Une fois que le prototypage et la preuve de concept sont éliminés, généralement au début de la planification et de la découverte, vous devez décider de ce qui est le plus fiable pour la durabilité à long terme.
OK, donc en conclusion, cela dépend fortement de nombreux facteurs, mais j'espère que cela a fourni un aperçu au lieu de la confusion.
Un service Windows n'a pas besoin que quelqu'un se connecte, et Windows dispose de fonctionnalités pour arrêter, démarrer et enregistrer les résultats du service.
Une tâche planifiée ne nécessite pas que vous appreniez à écrire un service Windows.
NT AUTHORITY\LocalService
, ou NT AUTHORITY\NetworkService
). Tout mot de passe fourni est ignoré car les comptes n'ont pas de mot de passe.
Pourquoi ne pas fournir les deux?
Dans le passé, j'ai mis les bits `` principaux '' dans une bibliothèque et enveloppé un appel à Whatever.GoGoGo () à la fois dans un service et dans une application console.
Avec quelque chose que vous déclenchez toutes les deux minutes, les chances sont bonnes, il ne fait pas grand-chose (par exemple juste une fonction de type "ping"). Les wrappers ne devraient pas avoir à contenir beaucoup plus qu'un simple appel de méthode et une certaine journalisation.
C'est une vieille question mais j'aimerai partager ce à quoi j'ai été confronté.
Récemment, on m'a demandé de capturer la capture d'écran d'un radar (à partir d'un site Web météorologique) et de l'enregistrer sur le serveur toutes les 10 minutes.
Cela m'a obligé à utiliser WebBrowser. Je fais généralement des services Windows, j'ai donc décidé de créer ce service, mais il continuerait à planter. C'est ce que j'ai vu dans le chemin du module défaillant de l'Observateur d' événements : C: \ Windows \ system32 \ MSHTML.dll
Comme la tâche était urgente et que j'avais très moins de temps pour rechercher et expérimenter, j'ai décidé d'utiliser une simple application console et l'ai déclenchée comme une tâche et elle s'est exécutée sans problème.
J'ai beaucoup aimé l' article de Jon Galloway recommandé dans la réponse acceptée par Mark Ransom.
Récemment, les mots de passe sur les serveurs ont été modifiés sans me reconnaître et tous les services n'ont pas pu s'exécuter car ils ne pouvaient pas se connecter. Donc, ppl prétendant dans l'article commente que c'est un problème. Je pense que les services Windows peuvent faire face au même problème (veuillez me corriger si je me trompe, je suis juste un débutant)
Aussi la chose mentionnée, si vous utilisez les fenêtres du planificateur de tâches ou la fenêtre de la console apparaît. Je n'ai jamais fait face à ça. Cela peut apparaître mais c'est au moins très instantané.
Généralement, le message principal est et devrait être que le code lui-même doit être exécutable à partir de chaque "déclencheur / client". Il ne devrait donc pas être sorcier de passer de l’une à l’autre.
Dans le passé, nous utilisions plus ou moins toujours les services Windows, mais depuis aussi de plus en plus de nos clients passent à Azure étape par étape et le passage d'une application console (déployée en tant que tâche planifiée) à un WebJob dans Azure est beaucoup plus facile que de un service Windows, nous nous concentrons sur les tâches planifiées pour le moment. Si nous rencontrons des limitations, nous accélérons simplement le projet de service Windows et appelons la même logique à partir de là (tant que les clients travaillent OnPrem ..) :)
BR, y
Les services Windows veulent plus de patience jusqu'à ce que ce soit fait. Il a un débogage et une installation un peu difficiles. C'est sans visage. Si vous avez besoin d'une tâche qui doit être effectuée toutes les secondes, minutes ou heures, vous devez choisir Windows Service.
La tâche planifiée est rapidement développée et a un visage. Si vous avez besoin d'une tâche quotidienne ou hebdomadaire, vous pouvez utiliser Tâche planifiée.