Появилась проблема со службой и для того, чтобы временно решить её необходимо периодически перезапускать службу. Перезапуск помогает примерно на два часа и потом приходится снова выполнять перезапуск.
Задача:
- Найти имя нужной службы;
- Остановить службу;
- Запустить службу;
- Повторять эти действия каждые два часа.
Решение:
Для решения моей задачи мне пришлось найти имена сервисов которые необходимо перезапустить. Заходим через поиск в services или через «Панель управления» -> «Администрирование» -> «Службы». Находим нужную службу и кликаем на неё два раза и получаем имя службы.
Функция для операций со службой
Функция _Service_Proc имеет два параметра:
- $sService — имя сервиса;
- $sAction — действие.
Основную работу выполняет Run посылающий команду «net stop/start Service «, которая приводит либо к завершению, либо к старту службы.
В результате работы этой функции получаем массив $aRet который содержит два элемента:
- $aRet[0] — указатель дочернего потока STDOUT
- $aRet[1] — указатель дочернего потока STDERR
Вот пример самой функции:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
Func _Service_Proc($sService, $sAction) Local $iPID = Run('net ' & $sAction & ' "' & $sService & '"', '', @SW_HIDE, 2 + 4) Local $sStdRead, $sStdErrRead, $stBuffer, $aRet, $aRet[2] While 1 $sStdRead &= StdoutRead($iPID) If @error Then ExitLoop $sStdErrRead &= StderrRead($iPID) If @error Then ExitLoop WEnd $aRet[0] = $sStdRead $aRet[1] = $sStdErrRead For $i = 0 To 1 $stBuffer = DllStructCreate("char[" & StringLen($aRet[$i])+1 & "]") $aOemToChar = DllCall("User32.dll", "int", "OemToChar", "str", $aRet[$i], "ptr", DllStructGetPtr($stBuffer)) If Not IsArray($aOemToChar) Then ContinueLoop ;ошибка DLL If $aOemToChar[0] = 0 Then ContinueLoop ;ошибка функции $aRet[$i] = DllStructGetData($stBuffer, 1) Next Return $aRet EndFunc |
Ну и конечно сам скрипт перезапуска службы:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
Func _servReboot() $aRet_Info = _Service_Proc("iphlpsvc", "stop") $sFoematted_Info = StringFormat("Std Out Return:\t%s\nStd Error Return:\t%s\n", $aRet_Info[0], $aRet_Info[1]) MsgBox(64, 'Title', $sFoematted_Info,2) $aRet_Info = _Service_Proc("Winmgmt", "stop") $sFoematted_Info = StringFormat("Std Out Return:\t%s\nStd Error Return:\t%s\n", $aRet_Info[0], $aRet_Info[1]) MsgBox(64, 'Title', $sFoematted_Info,2) $aRet_Info = _Service_Proc("iphlpsvc", "start") $sFoematted_Info = StringFormat("Std Out Return:\t%s\nStd Error Return:\t%s\n", $aRet_Info[0], $aRet_Info[1]) MsgBox(64, 'Title', $sFoematted_Info,2) $aRet_Info = _Service_Proc("Winmgmt", "start") $sFoematted_Info = StringFormat("Std Out Return:\t%s\nStd Error Return:\t%s\n", $aRet_Info[0], $aRet_Info[1]) MsgBox(64, 'Title', $sFoematted_Info,2) EndFunc |
Можно конечно сделать намного проще и обойтись всего парой строк, но пример выше отображает результат и ошибки скрипта.
Запуск функции каждые 2 часа
UDF AdlibRegister каждые 2 часа (или указанное в параметре time 2*60*60*1000 мс) вызывается указанная функция(_servReboot)
1 2 3 4 |
AdlibRegister("_servReboot", 2*60*60*1000) While 1 Sleep(1000) WEnd |
Завершение работы
Ну и для того чтобы завершить работу скрипта можно добавить горячую клавишу F7.
1 2 3 4 5 |
HotKeySet('{F7}', '_Quit') Func _Quit() Exit EndFunc ;==>_Quit |
Скрипт готов, исходник можно скачать ниже по ссылке.
[sdm_download id=»726″ fancy=»0″]