Запуск java как сервис windows
Однажды вы задумаетесь, как превратить скрипт или приложение в Windows-службу. Скорее всего, задача окажется не такой уж тривиальной – приложению как минимум потребуется специальный интерфейс для получения команд от системы. А раз есть требования и ограничения, то есть и скрипты, и милые сердцу костылики для преодоления.
Статья будет полезна тем, кто, как и я — «программист не настоящий».
В отличие от назначенных заданий служба работает постоянно, запускается при старте ПК и может управляться средствами Windows. А еще регулярно запускаемому скрипту могут понадобиться данные с предыдущего запуска, и может быть полезно получение данных из внешних источников — например, в случае TCP или Web сервера.
Лично мне за последние пять лет приходилось создавать службу три с половиной раза:
- Потребовалось создать сервис на fail2ban для Windows 2003., который работал с логами FileZilla и Apache, а при подозрении на брутфорс блокировал IP штатными средствами Windows — ipsec.
- Аналог телнет-сервера для домашних версий Windows. Понадобилось выполнять команды на удаленных рабочих станциях, которые были под управлением Windows 7 Home. По сути, вторая попытка поиграть в службы.
- Музыкальный проигрыватель для торгового зала под Windows. Задачу по ТЗ можно было решить при помощи mpd и пачки скриптов, но я решил — если уж делать скрипты, то почему бы и не «сваять» проигрыватель самому. За основу взял библиотеку BASS.dll.
- Когда выбирали веб-сервер с поддержкой загрузки файлов под Windows, одним из вариантов был HFS. Сам по себе работать он не может, поэтому пришлось «запихивать» его в службу. В результате решение не понравилось, и просто установили «тему» Apaxy на web-сервере Apache.
Для создания службы можно использовать взрослые языки программирования вроде C. Но если вы не хотите связываться с Visual Studio, то возьмите готовые утилиты. Существуют платные решения вроде FireDaemon Pro или AlwaysUp, но мы традиционно сосредоточимся на бесплатных.
Этот уже немолодой механизм состоит из двух компонентов: утилиты instsrv.exe для установки сервиса и srvany.exe — процесса для запуска любых исполняемых файлов. Предположим, что мы создали веб-сервер на PowerShell при помощи модуля Polaris. Скрипт будет предельно прост:
Работа так называемого «сервера».
Теперь попробуем превратить скрипт в службу. Для этого скачаем Windows Resource Kit Tools, где будут наши утилиты. Начнем с того, что установим пустой сервис командой:
Где WebServ — имя нашего нового сервиса. При необходимости через оснастку services.msc можно задать пользователя, под которым будет запускаться служба, и разрешить взаимодействие с рабочим столом.
Теперь пропишем путь к нашему скрипту при помощи магии реестра. Параметры службы есть в разделе реестра HKLM\SYSTEM\CurrentControlSet\Services\WebServ. В нем нам нужно добавить новый раздел Parameters и создать там строковый параметр Application, указав в нем путь к исполняемому файлу. В случае скрипта PowerShell он будет выглядеть так:
Настроенная служба.
Можно запустить и радоваться.
Работающая служба.
Однако у этого способа есть недостатки:
- Утилиты старые, разработаны до изобретения PowerShell, UAC и прочих вещей.
- Srvany не контролирует работу приложения. Даже если оно выпадет в ошибку, служба продолжит свое дело как ни в чем не бывало.
- Придется донастраивать и копаться в реестре. Вы же помните, что копаться в реестре небезопасно?
Поэтому перейдем к методу, частично лишенному этих проблем.
Существует утилита под названием NSSM — Non-Sucking Service Manager, что можно перевести как не-плохой менеджер служб. В отличие от предыдущей, она поддерживается разработчиком, и исходный код опубликован на сайте. Помимо обычного способа, доступна и установка через пакетный менеджер Chocolately.
Создать сервис можно из обычной командной строки, вооружившись документацией на сайте разработчика. Но мы воспользуемся PowerShell. Потому что можем, разумеется.
Установка через PowerShell.
Для разнообразия проверим работу службы не браузером, а тоже через PowerShell командой Invoke-RestMethod.
И вправду работает.
В отличие от srvany, этот метод позволяет перезапускать приложение на старте, перенаправлять stdin и stdout и многое другое. В частности, если не хочется писать команды в командную строку, то достаточно запустить GUI и ввести необходимые параметры через удобный интерфейс.
GUI запускается командой:
Настроить можно даже приоритет и использование ядер процессора.
Действительно, возможностей куда больше, чем у srvany и ряда других аналогов. Из минусов бросается в глаза недостаточный контроль над всем процессом.
Налицо нехватка «жести». Поэтому я перейду к самому хардкорному методу из всех опробованных.
Поскольку я давний любитель этого скриптового языка, то не смог пройти мимо библиотеки под названием _Services_UDF v4. Она снабжена богатой документацией и примерами, поэтому под спойлером сразу приведу полный текст получившегося скрипта.
Итак, попробуем «завернуть» в нее наш веб-сервис:
Разберу подробнее момент запуска приложения. Он начинается после операции $bServiceRunning = True и превращается в, казалось бы, бесконечный цикл. На самом деле этот процесс прервется, как только служба получит сигнал о завершении — будь то выход из системы или остановка вручную.
Поскольку программа для скрипта является внешней (powershell.exe), то после выхода из цикла нам нужно закончить ее работу с помощью ProcessClose.
Для этого скрипт необходимо скомпилировать в .exe, а затем установить службу, запустив exe с ключом -i.
Оно работает!
Разумеется, этот способ не самый удобный, и все дополнительные возможности придется реализовывать самостоятельно, будь то повторный запуск приложения при сбое или ротация логов. Но зато он дает полный контроль над происходящим. Да и сделать в итоге можно куда больше — от уведомления в Telegram о сбое службы до IPC-взаимодействия с другими программами. И вдобавок — на скриптовом языке, без установки и изучения Visual Studio.
Почему 80% фермеров кода не могут быть архитекторами? >>>
Что касается вопроса о том, как превратить программу Java в службу Windows, не говорите мне об интерфейсе Win, я не знаком с ним.
Во-первых, превратить программу exe в службу Win
Пакетная команда запуска Java скомпилирована в программу win. Пакетный Сталкер V6.0 или quickbfc 3.6.1 Реализовать;
Затем используйте команду sc, которая поставляется с системой, чтобы создать ее как системную службу: (Чтобы проверить эффект, я добавил параметры для интерактивного запуска службы)
Обратите внимание, что команда Windows всегда была необычной:
- После "=" должен быть пробел
- Если вы хотите использовать параметр типа, вы должны установить значение 2. Например, к указанным выше каштанам добавляется первый «запустить независимо», а затем «интерактивный» для вступления в силу. В противном случае он сообщит об ошибке: [SC] CreateService FAILED 87
Using some of the options will trigger a "[SC] CreateService FAILED 87" this usually means the option used like "type" needs another declaration. In case for instance when using type= interact, the type= option must be declared again with an alternative type like own. So effectivly the service type will be type= own interactive.
После завершения создания вы можете запустить сервис: net start test
Выяснилось, что программа запускалась нормально, но служба всегда запускалась. После закрытия программы служба стала останавливаться. Почему?
Поскольку системная служба не знает, в каком состоянии была запущена ваша программа, что считается успешным запуском, а также не знает, была ли программа остановлена нормально или завершилась ненормально.
В конечном итоге способ добавления общей программы в качестве системной службы с помощью команды sc не реализует интерфейс службы Win и не соответствует требованиям для стандартной программы-демона.
Поиск в Интернете и обнаружение, что доступны инструменты разработки Microsoft:Запустите любую программу как службу Windows, используя srvany.exe
Выше статья отличная, и автор также разработал легкий инструментSrvanyUIУдобно создавать пользовательские сервисы.
Но мне не удалось после эксперимента по неизвестным причинам. Фоновый мониторинг обнаружил, что java-программа мигает, а затем быстро закрывается, возможно, причина в том, что classpath установлен неправильно.
В общем, этот метод недостаточно гибок, здесь нет намека на ошибки, а только устранение неполадок на основе опыта;
Кроме того, как упоминалось в статье, средство больше не поддерживается Microsoft, и проблемы совместимости могут возникать с версиями win7 и выше.
Инструменты из мира Java
Различные люди из крупного рогатого скота выразили свои взгляды в этом Q & A:
- The Java Service Wrapper , Самое известное и зрелое решение в отрасли
Я использовал JSW в течение долгого времени, и стабильность и масштабируемость хорошие. Усовершенствованная версия также обеспечивает обработку исключений Java, например, следует ли автоматически перезапускать службу при генерации OOM.
Недостатком является то, что платные 64-битные версии требуют покупки лицензии. Пять лет назад вам, возможно, не нужно было беспокоиться о том, нужна ли вам 64-битная JVM, но сегодня 1,5-битной кучи 32-битной памяти немного недостаточно.
wrapper.conf Пример файла конфигурации выглядит следующим образом: (официальный пакет загрузки содержит более подробные примеры и инструкции)
- Yet Another Java Service Wrapper Реализация с открытым исходным кодом, похожая на JSW
Возможно, YAJSW заменил JSW, потому что он с открытым исходным кодом и бесплатный, и поддерживает Быстрая и плавная миграция с JSW , Но есть Друзья сказали, что они напуганы загрузкой пакета 19M . так что .
- Apache Commons Daemon , Член знаменитого инструментария Apache Commons
- WinRun4J, Коллекция Java2exe2service, дополнительный экспорт в один клик плагина eclipse!
Следующие инструменты не были проверены мной, но не означают, что они не применимы:
javaservice (Не обновляется после 2006 года, метод использования неизвестен)
Java Service Launcher(Компактный, поддерживает 64-битную JVM и JRockit и другие сторонние виртуальные машины, но, к сожалению, документация относительно сырая)
Launch4jИнструмент для упаковки Jar в качестве исполняемого файла, но, к сожалению, используя конфигурацию XML, лично ничего не чувствую
Смотрите больше инструментов с открытым исходным кодом:Java-пакет с открытым исходным кодом
Давно потерянный демон Apache Commons
Сначала поговорим о чувствах: Tomcat, я думаю, многие студенты знакомы с ним с первого дня изучения Java. Увидев значок ACD, я обнаружил, что оригинальная версия установки Tomcat win использует его!
Давайте поговорим об использовании: программа ввода для версии WinprocrunИспользовать его для создания сервиса очень просто:
Есть много параметров, вы можете понять, посмотрев на комментарии. Здесь также есть китайский перевод: Procrun of Commons Daemon 。
Procrun может не только генерировать Java-классы в сервисы, но и изменять exe-сервисы в сервисах. Подробнее см. В настройках параметров.
В-четвертых, посмотрите на мощный WinRun4J
Давайте сначала поговорим о его недостатках: ему нужен класс входа, который зависит от пакета WinRun4J.jar, который имеет определенную степень связности по сравнению с ACD, вместо того, чтобы напрямую использовать основной класс запуска. Кроме того, все выглядит хорошо
The only drawback is that it requires a special class for working as a service (instead of simply calling standard main class)На официальном веб-сайте есть служба создания каштанов, которая также включена в загруженный пакет, но есть некоторые проблемы:
Вызывается в вышеуказанном классе EventLog.report Журнал, созданный методом, будет записан только в системный журнал. Управление компьютером-Инструменты системы-Просмотр событий-Приложения Чтобы увидеть
Расположение соответствующего файла журнала в системе XP: C:\WINDOWS\system32\config\ SysEvent.Evt
Очевидно, что мы хотим, чтобы журналы были более управляемыми, чем операционная система. Но я не нашел подходящий параметр для его установки, он может быть указан только программой Java.
Скомпилируйте вышеупомянутые классы, чтобы сгенерировать файл класса, а затем отредактируйте файл конфигурации. WinRun4Jc.ini :
- WinRun4Jc.ini и WinRun4Jc.exe Должен быть в том же каталоге и иметь то же имя, потому что нет параметров для указания пути к профилю .
- Вышеуказанные параметры являются обязательными, и service.id и service.name Обязательно напишите одно и то же название сервиса
- classpath.2 Указано как WinRun4J.jar Путь, потому что класс записи службы выше реализует класс в пакете
Создайте и удалите сервисы с помощью следующих команд:
WinRun4J также обеспечиваетEclipse плагинИ небольшой инструмент для добавления иконки ico в программу exe, использование очень простое, есть инструкции на официальном сайте.
В любом случае, WinRun4J эквивалентен комбинации ACD и Launch4j. Хотя общая функция не такая мощная, как у двух, у них тоже все хорошо.
Специально для студентов, использующих Eclipse, это намного удобнее: взгляните на его интимную функцию экспорта.
• 1. Для удобства поместил упакованный проект jar и winsw в один каталог, здесь я поместил его на диск D.
• 2. Переименуйте winsw-1.19-bin.exe на то же имя, что и myapp.jar: myapp.exe.
• 3. Создайте новый XML-файл в текущем каталоге: myapp.xml, его содержимое будет следующим:
Связанные параметры следующие:
• 4. Выполните следующую команду, чтобы зарегистрировать приложение как службу: myapp.exe install
• 5. После выполнения указанной выше команды вы увидите службу с именем myapp в службе Windows, и установка будет успешной.
• 6. В дополнение к команде установки есть другие команды: uninstall: удалить службу start: запустить службу stop: остановить перезапуск службы: перезапустить состояние службы: вывести текущую статус службы
эталонное изображение:
Эталонная конфигурация:
Интеллектуальная рекомендация
Michael.W Поговорите о Hyperledger Fabric. Проблема 20 - Подробная индивидуальная сортировка узла с пятью порядками с исходным кодом для чтения.
Michael.W Поговорите о Hyperledger Fabric. Проблема 20 - Подробная индивидуальная сортировка узла с пятью порядками с исходным кодом чтения Fabric Файл исходного кода одиночного режима находится в ord.
Мяу Пасс Матрица SDUT
Мяу Пасс Матрица SDUT Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Problem Description Лянцзян получил матрицу, но эта матрица была особенно уродливой, и Лянцзян испытал отвращение. Чт.
Гессенская легкая двоичная структура удаленного вызова
Hessian - это легкая двоичная структура удаленного вызова, официальный адрес документа, в основном он включает протокол удаленного вызова Hessian, протокол сериализации Hessian, прокси-сервер клиента .
TCP Pasket и распаковка и Нетти Solutions
Основные введение TCP является ориентированным на соединение, обеспечивая высокую надежность услуг. На обоих концах (клиенты и терминалы сервера) должны иметь один или более гнезда, так что передающий.
Введение
В рамках одного из проектов требовалось разработать Windows службу, которая могла бы выполнять ряд действий с помощью Windows API, Websocket и стандартных средств Java. Далее в статье будут описаны шаги, которые были сделаны для создания такой службы.
Потребность в Windows службе возникла из-за необходимости иметь программу со следующими возможностями:
- она должна быть постоянно запущена,
- выполнялась от системного пользователя,
- автоматически запускалась при старте системы,
- чтобы её сложно было остановить обычному пользователю.
Создание минимизированной версии JRE
Так как GraalVM всё ещё не поддерживает создание исполняемых файлов под Windows, было решено воспользоваться другими возможностями, которые предоставляет экосистема Java, а именно создание минимизированной версии JRE.
Для того, чтобы создать минимизированную версию JRE, для начала необходимо узнать зависимости на определенные пакеты, которые будут включены в JRE.
В первую очередь необходимо собрать jar-файл “fat jar” со всеми зависимостями.
Затем выполнить команду jdeps -s <путь к jar-файлу>, чтобы получить список всех зависимостей. Например:
Далее создаём нашу версию JRE с данными зависимостями:
jlink —module-path <путь к папке jmods, которая находится в jdk> —add-modules
Обратите внимание, что перечисление пакетов для опции —add-modules необходимо разделять запятой и не ставить между ними пробелов. Остальные опции отвечают за сжатие и убирание файлов и другой информации, которая не пригодится для выполнения программы.
После выполнения этих действий JRE будет занимать порядка 30 mb, вместо сотен.
Создание Windows службы из любого приложения
Java не имеет стандартных средств по созданию служб, поэтому были изучены сторонние инструменты и был выбран WinSW в силу его бесплатности и простоты использования.
WinSW
Необходимо поместить эти два файла в директорию. Переименовать исполняемый файл на своё усмотрение и дать такое же название файлу конфигурации, затем поместить в эту директорию jar-файл приложения и созданную JRE.
В конфигурационном файле необходимо прописать минимальную конфигурацию:
jre\bin\java.exe — относительный путь внутри нашей папки к исполняемому файлу нашей JRE.
После этих действий можно установить службу, для этого необходимо выполнить команду от имени администратора:
Список команд можно посмотреть здесь .
Взаимодействие Java и Windows API
Для использования функций Windows (таких как создание нового процесса или добавление ключей реестра) в нашем приложении был использован JNA.
JNA (Java Native Access) предоставляет Java-программам легкий доступ к библиотекам, написанным на другом языке, без написания чего-либо, кроме кода Java. JNA позволяет напрямую вызывать нативные функции, используя обычный вызов метода Java. Большинство методов не требуют специальной обработки или конфигурации; не требуется шаблон или сгенерированный код.
Подключить и работать с JNA очень просто, для этого необходимо скачать jar-файл или подключить зависимость в сборщик проекта — в нашем случает Maven:
В нашем проекте мы использовали JNA для достижения следующих целей: заблокировать и сделать вновь доступным диспетчер задач 1) по комбинации Ctrl+Shift+Esc и 2) в меню, доступном по комбинации Ctrl+Alt+Del.
Для достижения этого были использованы класс Advapi32Util (удобная обёртка над библиотекой advapi32.dll) и интерфейс WinReg с полезными константами , которые предоставляют функциональность для внесения изменений в реестр Windows (Рисунок 1. Класс TaskManager с методами enable() и disable() для изменения ключей реестра диспетчера задач).
Рисунок 1. Класс TaskManager с методами enable() и disable() для изменения ключей реестра диспетчера задач.
- Создать новый процесс от имени определённого пользователя Windows. Для этого мы использовали метод CreateProcessAsUser()интерфейса Advapi32. В метод необходимо передать следующие параметры:
- hToken — дескриптор токена пользователя, для которого мы запускаем процесс.
- lpApplicationName — имя модуля, который должен быть выполнен.
- lpCommandLine — командная строка для выполнения.
- lpProcessAttributes — указатель на структуру SECURITY_ATTRIBUTES, которая определяет дескриптор безопасности для нового объекта процесса и определяет, могут ли дочерние процессы наследовать возвращенный дескриптор процесса.
- lpThreadAttributes — указатель на структуру SECURITY_ATTRIBUTES, который определяет дескриптор безопасности для нового объекта потока и определяет, могут ли дочерние процессы наследовать возвращенный дескриптор потока.Создать новый процесс от имени определённого пользователя Windows. Для этого мы использовали метод CreateProcessAsUser() интерфейса Advapi32. В метод необходимо передать следующие параметры:
- bInheritHandles — если этот параметр TRUE, каждый наследуемый дескриптор вызывающего процесса наследуется новым процессом. Если параметр FALSE, процессы не наследуются.
- dwCreationFlags — флаги, которые контролируют класс приоритета и создают процесс.
- lpEnvironment — указатель на блок среды для нового процесса. Если этот параметр равен NULL, новый процесс использует среду вызывающего процесса. Блок среды состоит из блока с нулевым завершением строк с нулевым завершением. Каждая строка имеет следующий вид: name = value \ 0.
- lpCurrentDirectory — полный путь к текущему каталогу для процесса. Строка также может указывать путь UNC (universal naming convention).
- lpStartupInfo — указатель на структуру STARTUPINFO или STARTUPINFOEX.lpProcessInformation — указатель на структуру PROCESS_INFORMATION, которая получает идентификационную информацию о новом процессе.
Рисунок 2. Метод для создания нового процесса для определённого пользователя Windows.
- Получить токен активного пользователя, т.к. он необходим для создания процесса от определённого пользователя.
Работа с процессами
Для работы и слежения за процессами в Windows был использован, добавленный в Java 9, класс ProcessHandle. ProcessHandle позволяет получать и производить различные манипуляции с процессами. В частности, при решении задачи, требовалось собирать PID процессов, фильтровать процессы на основе имени и принудительно завершать необходимые процессы.
Рисунок 3. Класс ProcessHandler с методами takeSnapshot() для создания снимка текущих процессов и closeNewProcesses() для завершения процессов, отличных от снимка.
Взаимодействие с другими компонентами системы
WebSocket
Для Java существует стандартизированный API для работы с WebSocket.
Но одного API недостаточно, поэтому для запуска кода была выбрана одна из его реализаций — Tyrus.
Далее можно создать минималистичный сервер и указать обработчики (EndPoints).
Заготовка обработчика выглядит следующим образом:
Для создания экземпляра клиента необходимо воспользоваться билдером. В простейшем случае:
Далее необходимо создать запрос(request), например:
Затем этот запрос можно использовать для отправки на сервер:
ЗаключениеБлагодаря модульной организации версий Java 9 и выше, утилите WinSW, обновлённому Process API для взаимодействия с процессами операционной системы и библиотеки JNA (Java Native Access), которая предоставляет программам Java простой доступ к нативным библиотекам, мы смогли создать Windows службу с использованием языка Java, на котором была реализована и серверная часть. Что в итоге позволило не вводить в процесс разработки новый язык.
Читайте также: