Відповіді:
Оновлення:
Майже через чотири роки після моєї оригінальної відповіді та ця відповідь дуже застаріла. Оскільки TopShelf прийшов разом із розробкою служб Windows, стало легко. Тепер вам просто потрібно розібратися, як підтримувати аварійну допомогу ...
Оригінальний відповідь:
Я насправді не шанувальник планувальника Windows. Пароль користувача повинен бути наданий, як зазначено вище @moodforall , що цікаво, коли хтось змінює пароль цього користувача.
Іншим головним роздратуванням у Windows Scheduler є те, що він працює в інтерактивному режимі, а не як фоновий процес. Коли кожні 20 хвилин під час сеансу RDP з'являються 15 вікон MS-DOS, ви будете виганяти себе, що не встановили їх замість Служб Windows.
Що б ви не вибрали, я, безумовно, рекомендую розділити код обробки на інший компонент із консольного додатка чи служби Windows. Тоді у вас є вибір: або зателефонувати в робочий процес із консольного додатка та підключити його до планувальника Windows, або скористатися службою Windows.
Ви побачите, що планування служби Windows не є цікавим. Досить поширений сценарій полягає в тому, що у вас є тривалий запущений процес, який ви хочете періодично запускати. Але, якщо ви обробляєте чергу, то вам дійсно не потрібні два екземпляри одного і того ж робітника, який обробляє ту саму чергу. Тому вам потрібно керувати таймером, щоб переконатися, що ваш тривалий запуск триває довше, ніж призначений інтервал таймера, він не починається знову, поки не закінчиться існуючий процес.
Після того, як ви все це написали, ви думаєте, чому я просто не використовував Thread.Sleep? Це дозволяє мені дозволити поточному потоку продовжувати працювати, поки він не закінчиться, і тоді починається інтервал пауз, нитка переходить у режим сну і знову починається через необхідний час. Акуратно!
Потім ви читаєте всі поради в Інтернеті з великою кількістю експертів, які розповідають, як це насправді погана практика програмування:
Тож ви подряпаєте собі голову і подумайте самі, WTF, Скасувати відкладені каси -> Так, я впевнений -> Скасувати всю сьогоднішню роботу ..... чорт, чорт, чорт ...
Однак мені подобається така модель, навіть якщо всі думають, що це лайно:
Метод OnStart для однопотокового підходу.
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(); }
Код створює окремий потік і додає до нього функцію нашого працівника. Потім він запускає потік і дозволяє завершити подію OnStart, так що Windows не вважає, що служба підключена.
Робітничий метод для підходу з одним потоком.
/// <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(); }
Метод OnStop для однопотокового підходу.
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)); }
Джерело: http://tutorials.csharp-online.net/Creating_a_.NET_Windows_Service%E2%80%94Alternative_1%3a_Use_a_Separate_Thread (мертве посилання)
Я вже багато років використовую подібні служби Windows, і це працює на мене. Я досі не бачив рекомендованої моделі, з якою люди погоджуються. Просто робіть те, що працює для вас.
NT AUTHORITY\NetworkService
запис з обмеженими привілеями.
Деякі дезінформації тут. Планувальник Windows прекрасно здатний виконувати завдання у фоновому режимі без спливаючих вікон та без пароля. Запустіть його під обліковим записом NT AUTHORITY \ SYSTEM. Використовуйте цей перемикач schtasks:
/ ru СИСТЕМА
Але так, для доступу до мережевих ресурсів найкращою практикою є обліковий запис служби з окремою політикою паролів, що не закінчується.
EDIT
Залежно від вашої ОС та вимог самої задачі, ви можете мати можливість використовувати облікові записи, які мають менші привілеї, ніж Localsystem з /ru
можливістю вибору.
З чудового посібника ,
/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.
Планувальник завдань 2.0 доступний у Vista та Server 2008.
У XP та Server 2003 system
- це єдиний варіант.
Local Service
(ака NT AUTHORITY\LocalService
), а не LocalSystem
(ака .\LocalSystem
). Перший має обмежені права, тоді як останній є адміністратором
LocalService
і NetworkService
доступні в schtasks
v2 Vista , починаючи і має бути кращим , де це можливо. У той час це стосувалося schtasks
в XP та Server 2003, які приймають лише System
параметр у ручній версії старої версії technet.microsoft.com/en-us/library/bb490996.aspx
Що за накладні витрати на запуск та вихід програми? Кожні дві хвилини досить часто. Служба, ймовірно, дозволить системі працювати більш плавно, ніж виконувати вашу програму так часто.
Обидва рішення можуть запускати програму, коли користувач не входить у систему, тому різниці немає. Написання сервісу дещо більше, ніж звичайний додаток для настільних комп’ютерів, - можливо, вам знадобиться окремий клієнтський інтерфейс, який буде спілкуватися зі службовим додатком через TCP / IP, названі канали тощо.
З POV користувача, мені цікаво, що легше контролювати. І сервіси, і заплановані завдання в значній мірі недоступні для більшості нетехнічних користувачів, тобто вони навіть не усвідомлюють, що вони існують, і можуть бути налаштовані / зупинені / перекладені тощо.
У розробці .NET я зазвичай починаю розробку додатка консолі, який запускатиме всі записи журналу до вікна консолі. Однак це лише додаток консолі, коли він запускається з аргументом команди /console
. Коли він запускається без цього параметра, він виконує функцію сервісу Windows, який працюватиме на моєму власному кодованому плановому таймері.
На мій погляд, сервіси Windows зазвичай використовуються для керування іншими програмами, а не для роботи з давно працюючим додатком. АБО .. вони постійно працюють із важкими програмами, такими як SQL Server, BizTalk, RPC Connections, IIS (навіть якщо IIS технічно вивантажує роботу в інших процесах).
Особисто я віддаю перевагу плановим завданням через Window Services для повторюваних завдань технічного обслуговування та додатків, таких як копіювання / синхронізація файлів, масове надсилання електронної пошти, видалення або архівування файлів, виправлення даних (коли інші способи вирішення недоступні).
В одному проекті я брав участь у розробці 8 або 9 служб Windows, але вони сидять навколо пам’яті, простою, їдять 20 Мб або більше пам’яті на примірник. Заплановані завдання займуться своєю справою та негайно звільнять пам'ять.
Слово "serv'ice" має щось спільне з "serv'er". Очікується, що він завжди працює, і 'serv'e. Завдання - це завдання.
Рольова гра. Якщо я інша операційна система, додаток або пристрій, і я зателефоную до служби, я очікую, що вона працює, і я очікую відповіді. Якщо мені (os, app, dev) просто потрібно виконати окреме завдання, то я виконаю завдання, але якщо я розраховую на спілкування, можливо, двосторонній зв’язок, я хочу послугу. Це стосується найбільш ефективного способу спілкування двох речей або однієї речі, яка хоче виконати одне завдання.
Тоді є аспект планування. Якщо ви хочете щось запустити в певний час, розкладіть. Якщо ви не знаєте, коли вам це буде потрібно, або вам це потрібно "на льоту", послуга.
Моя відповідь має більш філософський характер, оскільки це дуже схоже на те, як люди взаємодіють і працюють з іншим. Чим більше ми розуміємо мистецтво спілкування, а «сутності» розуміють їх роль, тим легше стає це рішення.
З урахуванням філософії, коли ви «швидко розробляєте прототипи», як це часто робить мій відділ ІТ, ви робите все, що вам потрібно, щоб звести кінці з кінцями. Після того, як складання прототипів та доказовості концептуальних матеріалів не вдається, як правило, на початку планування та виявлення, ви повинні вирішити, що є більш надійним для довгострокової стійкості.
Гаразд, на закінчення, це сильно залежить від безлічі факторів, але, сподіваємось, це забезпечило розуміння замість плутанини.
У службі Windows не потрібно, щоб хтось входив у систему, а Windows має засоби для зупинки, запуску та реєстрації результатів служби.
Заплановане завдання не вимагає, щоб ви навчилися писати службу Windows.
NT AUTHORITY\LocalService
, або NT AUTHORITY\NetworkService
). Будь-який наданий пароль ігнорується, оскільки в облікових записах немає пароля.
Чому б не забезпечити обидва?
Раніше я поміщав "основні" біти в бібліотеку і завершив дзвінок до Wever.GoGoGo () як в сервісі, так і в консольному додатку.
Щось ви знімаєте кожні дві хвилини, шанси пристойні, це не дуже сильно (наприклад, лише функція типу "ping"). Обгортки не повинні містити більше, ніж один виклик методу та деякий журнал.
Це давнє питання, але я хотів би поділитися тим, з чим зіткнувся.
Нещодавно мені поставили вимогу знімати скріншот радіолокатора (з Метеорологічного веб-сайту) і зберігати його на сервері кожні 10 хвилин.
Це вимагало від мене використання WebBrowser. Зазвичай я роблю сервіси Windows, тому вирішив зробити цю послугу теж, але вона не впаде. Це те, що я бачив у шляху модуля перегляду подій, який виникла несправності: C: \ Windows \ system32 \ MSHTML.dll
Оскільки завдання було невідкладним, і у мене було зовсім менше часу на дослідження та експерименти, я вирішив скористатися простим консольним додатком і запустив його як завдання, і воно виконувалося плавно.
Мені дуже сподобалася стаття Джона Галлоуей, рекомендована у прийнятій відповіді Марком Рансом.
Нещодавно паролі на серверах були змінені, не підтверджуючи мене, і всі служби не вдалося виконати, оскільки вони не змогли ввійти. Тож ppl, що стверджує у статті, коментує, що це проблема. Я думаю, що сервіси Windows можуть зіткнутися з тією самою проблемою (будь ласка, виправте мене, якщо я помиляюся, я юнак)
Також згадана річ, якщо з використанням планувальників завдань спливають вікна або спливає вікно консолі. Я ніколи з цим не стикався. Він може спливати, але це, принаймні, дуже миттєво.
Як правило, основним повідомленням є і має бути те, що сам код повинен виконуватися з кожного "тригера / клієнта". Тож не слід ракетній науці переходити з одного на інший підхід.
Раніше ми використовували більш-менш завжди Послуги Windows, але оскільки все більше і більше наших клієнтів переходять на Azure поетапно, а поміняти з додатка Console (розгорнутого як заплановане завдання) на WebJob в Azure набагато простіше, ніж з Служба Windows, зараз ми орієнтуємося на заплановані завдання. Якщо ми стикаємося з обмеженнями, ми просто збільшуємо проект служби Windows і викликаємо туди ж логіку (поки клієнти працюють на OnPrem ..) :)
БР, у
Служби Windows хочуть більше терпіння, поки це не буде зроблено. Він має трохи жорсткий налагодження та встановлення. Це безлике. Якщо вам потрібно завдання, яке потрібно виконати щосекунди, хвилини або години, вам слід обрати службу Windows.
Заплановане завдання швидко розробляється і має обличчя. Якщо вам потрібно щоденне або щотижневе завдання, ви можете скористатись запланованим завданням.