Мені потрібно написати надійний код у .NET, щоб служба Windows (сервер 2003) перезапустилася. Який найкращий спосіб зробити це? Чи є якийсь .NET API для цього?
Мені потрібно написати надійний код у .NET, щоб служба Windows (сервер 2003) перезапустилася. Який найкращий спосіб зробити це? Чи є якийсь .NET API для цього?
Відповіді:
Встановіть перезапуск служби після відмови (двічі клацніть службу на панелі керування та огляньте їх на цих вкладках - я забув її назву). Потім, коли ви хочете, щоб послуга перезапустилася, просто зателефонуйте Environment.Exit(1)
(або будь-яке ненульове повернення), і ОС перезапустить її для вас.
Service.ExitCode = 1
а потім виконати, Service.Stop()
а також включити прапорець "Увімкнути дії для зупинок з помилками" на екрані налаштування відновлення служби. Це робиться таким чином, забезпечує належне відключення і все ще викликає перезапуск.
Dim proc As New Process()
Dim psi As New ProcessStartInfo()
psi.CreateNoWindow = True
psi.FileName = "cmd.exe"
psi.Arguments = "/C net stop YOURSERVICENAMEHERE && net start YOURSERVICENAMEHERE"
psi.LoadUserProfile = False
psi.UseShellExecute = False
psi.WindowStyle = ProcessWindowStyle.Hidden
proc.StartInfo = psi
proc.Start()
Ви не можете бути впевнені, що обліковий запис користувача, під яким працює ваша служба, має навіть дозволи зупинити та перезапустити службу.
Ви можете створити процес, який є командним рядком DOS, який перезавантажиться самостійно:
Process process = new Process();
process.StartInfo.FileName = "cmd";
process.StartInfo.Arguments = "/c net stop \"servicename\" & net start \"servicename\"";
process.Start();
const string strCmdText = "/C net stop \"SERVICENAME\"&net start \"SERVICENAME\"";
Process.Start("CMD.exe", strCmdText);
де SERVICENAME
назва вашого сервісу (подвійні лапки, включені до облікового запису пробілів у назві послуги, інакше не можна).
Очистити, конфігурація автоматичного перезавантаження не потрібна.
Це залежало б від того, чому ви хочете, щоб він перезапустився.
Якщо ви просто шукаєте спосіб періодично очищати службу, у вас може працювати таймер, який періодично викликає процедуру очищення.
Якщо ви шукаєте спосіб перезапустити при відмові - сам хост сервісу може надати таку можливість під час налаштування.
То чому вам потрібно перезапустити сервер? Чого ви намагаєтесь досягти?
Я не думаю, що можна скористатися автономною службою (коли ви зателефонуєте Перезапустити, вона зупинить службу, яка перерве команду Перезавантаження, і вона ніколи не запуститься знову). Якщо ви можете додати другий .exe (додаток консолі, що використовує клас ServiceManager), ви можете вимкнути автономний файл .exe і перезапустити його, а потім вийти.
По-друге, ви, ймовірно, могли б змусити службу зареєструвати заплановану задачу (наприклад, використовуючи командний рядок команди «at»), щоб запустити службу, а потім змусити її зупинитись; це, мабуть, спрацює.
Проблема з обшивкою пакетного файлу або EXE полягає в тому, що служба може мати або не мати дозволів, необхідних для запуску зовнішньої програми.
Найчистіший спосіб зробити це, що я знайшов, - це використовувати метод OnStop (), який є вхідною точкою для диспетчера служб управління. Тоді весь ваш код очищення запуститься, і ви не матимете підвісних сокет або інших процесів, якщо ваш стоп-код виконує свою роботу.
Для цього вам потрібно встановити прапор перед тим, як скасувати, який повідомляє методу OnStop вийти з кодом помилки; тоді SCM знає, що послугу потрібно перезапустити. Без цього прапора ви не зможете зупинити послугу вручну з SCM. Це також передбачає, що ви налаштували службу для перезавантаження з помилкою.
Ось мій стоп-код:
...
bool ABORT;
protected override void OnStop()
{
Logger.log("Stopping service");
WorkThreadRun = false;
WorkThread.Join();
Logger.stop();
// if there was a problem, set an exit error code
// so the service manager will restart this
if(ABORT)Environment.Exit(1);
}
Якщо служба стикається з проблемою і потребує перезавантаження, я запускаю потік, який зупиняє службу з SCM. Це дозволяє службі прибирати після себе:
...
if(NeedToRestart)
{
ABORT = true;
new Thread(RestartThread).Start();
}
void RestartThread()
{
ServiceController sc = new ServiceController(ServiceName);
try
{
sc.Stop();
}
catch (Exception) { }
}
Я б використовував Планувальник Windows для планування перезавантаження вашої служби. Проблема полягає в тому, що ви не можете перезапустити себе, але можете зупинити себе. (Ви, по суті, відпиляли гілку, на якій сидите ... якщо ви отримаєте мою аналогію) Вам потрібен окремий процес, щоб зробити це за вас. Планувальник Windows - це відповідний. Сплануйте одноразове завдання, щоб перезапустити службу (навіть із самої служби), щоб її виконати негайно.
В іншому випадку вам доведеться створити процес «вівчарства», який робить це за вас.
Перша відповідь на питання - це найпростіше рішення: "Environment.Exit (1)" Я використовую це на Windows Server 2008 R2, і він працює чудово. Послуга припиняється, O / S чекає 1 хвилину, після чого перезапускає її.
Кращим підходом може бути використання служби NT в якості обгортки для вашої програми. Коли запускається служба NT, ваша програма може запускатися в режимі очікування, очікуючи запуску команди (або налаштовується на автоматичний запуск).
Подумайте про машину, коли вона запущена, вона починається в режимі очікування, чекаючи, коли ваша команда рухатиметься вперед або назад. Це також дозволяє отримати інші переваги, наприклад, краще віддалене адміністрування, оскільки ви можете вибрати, як виставити заявку.
Тільки проходячи: і подумав, що я додам додаткову інформацію ...
Ви також можете кинути виняток, це автоматично закриє службу Windows, а параметри автоматичного перезапуску просто запускаються. Єдине питання з цього полягає в тому, що якщо у вас на комп’ютері є середовище dev, тоді JIT намагається запустити, і ви отримаєте підказку про налагодження Y / N. скажіть ні, тоді воно закриється, а потім перезапустіть належним чином. (на ПК без JIT це все працює). причина ім тролінгу, це JIT є новим для Win 7 (він працював нормально з XP тощо), і я намагаюся знайти спосіб відключення JIT .... я можу спробувати метод Environment.Exit, згаданий тут, дивіться, як це теж працює.
Крістіан: Брістоль, Великобританія
Створіть файл restart.bat таким чином
@echo on
set once="C:\Program Files\MyService\once.bat"
set taskname=Restart_MyService
set service=MyService
echo rem %time% >%once%
echo net stop %service% >>%once%
echo net start %service% >>%once%
echo del %once% >>%once%
schtasks /create /ru "System" /tn %taskname% /tr '%once%' /sc onstart /F /V1 /Z
schtasks /run /tn %taskname%
Потім видаліть завдання% taskname%, коли запуститься% service%
Створіть окремий додаток для розміщення коду програми. Коли потрібен перезапуск, ми можемо вивантажити та перезавантажити додаток замість процесу (служба Windows). Ось як працює пул додатків IIS, вони не запускають додаток asp.net безпосередньо, вони використовують окрему програму appdmain.
Найпростіший спосіб - мати пакетний файл із:
net stop net start
і додайте файл до планувальника з потрібним інтервалом часу
private static void RestartService(string serviceName)
{
using (var controller = new ServiceController(serviceName))
{
controller.Stop();
int counter = 0;
while (controller.Status != ServiceControllerStatus.Stopped)
{
Thread.Sleep(100);
controller.Refresh();
counter++;
if (counter > 1000)
{
throw new System.TimeoutException(string.Format("Could not stop service: {0}", Constants.Series6Service.WindowsServiceName));
}
}
controller.Start();
}
}