|
Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » CMD/BAT - [решено] Запуск без видимого окна с получением PID дочернего процесса |
|
CMD/BAT - [решено] Запуск без видимого окна с получением PID дочернего процесса
|
Старожил Сообщения: 415 |
Профиль | Отправить PM | Цитировать
Приветствую уважаемых форумчан.
Есть скрипт — загрузчик, который стартует портабельную сборку nginx + php + mysql + доп. модули, он рассчитан на запуск как от юзера, так и в качестве сервиса (например, через nssm). Хотелось бы организовать пул процессов интерпретатора php-cgi на разных портах, и такая возможность в принципе есть через конфиг бэкенда в nginx, но для отслеживания возможных падений (а у php это не столько редко случается) и перезапуска конкретного экземпляра мне нужен PID запущенного процесса. Я знаю о возможности запуска через wmic process call create с получением PID дочернего процесса, но тут есть проблема: я запускаю через hidcon, соответственно получаю PID hidcon-а, а не php-cgi. Собственно, вопрос: как запустить без видимого окна и получить PID? Или каким ещё образом можно отслеживать одинаковые процессы, запущенные с разными аргументами? Скрипт в текущем виде
@Echo Off :: Portable nginx+php+mysql for Windows :: Inquisitor, 2013-2019 :: nginx 1.17.1 :: php 7.2.19 + composer :: mysql 5.7.23 CD /D "%~dp0" :: Лог работы скрипта Set LogFile=%~dpn0.log :: Формат даты в логе Set TimestampFormat=[%%Date%% %%Time:~,8%%] :: Периодичность проверки запроса на отключение и перезапуска процессов при падении, секунды Set WatcherTimeout=10 :: Обрабатываем команду на выключение If /I "%~1"=="shutdown" ( If Exist "%~dp0.loader.lock" ( Call :Log Received termination signal, shutting down Del "%~dp0.loader.lock" 2>nul ) Else ( Call :Log [WARNING] Received termination signal, server not started ) Exit /B ) :: Обрабатываем запуск сервиса If /I "%~1"=="service" ( Call Echo.>>"%LogFile%" Call :Log Loader started as service GoTo :service ) :: Перезапускаем себя как скрытый процесс, если запущено без аргументов If "%~1"=="" ( Start "" "%~dp0tools\hidcon" %~nx0 restart_hidden Call Echo.>>"%LogFile%" Call :Log Loader started Exit ) :service :: Сохраняем оригинальный path Set OSPath=%Path% :: Добавляем пути к бинарникам в системный path для этого скрипта и дочерних процессов Set Path=%~dp0tools;%~dp0nginx;%~dp0php;%~dp0mysql\bin :: Добавляем модули :: FFMpeg 4.1.3 Set Path=%Path%;%~dp0modules\ffmpeg :: ImageMagick 6.9.3 (php7) Set Path=%Path%;%~dp0modules\imagick-php7\ImageMagick Set LOCALAPPDATA=%~dp0modules\imagick-php5 :: Меняем системный temp на наш Set Temp=%~dp0\tmp :: Добавляем системный path с низшим приоритетом Set Path=%Path%;%OSPath% :: Обрабатываем запуск консоли в рабочем окружении (Composer \ RIOX) If /I "%~1"=="console" ( PushD nginx\wwwroot Start cmd Exit /B 0 ) :: Запускаем каждый процесс из его рабочей директории :: MySQL Call :Log Starting MySQL... :start-mysql PushD .\mysql\ Start bin\mysqld --defaults-file="my.ini" --user=root --standalone||Call :Log [ERROR] Can't start MySQL PopD If "%1"=="restart" ( Call :Log [WARNING] MySQL crashed, restarting Exit /B ) :: PHP Call :Log Starting PHP-FPM... :start-php PushD .\php :: меняя что-то тут, не забываем изменить в nginx\conf\nginx.conf, секция upstream backend Start hidcon php-cgi -b 127.0.0.1:9123 -c ".\php.ini"||Call :Log [ERROR] Can't start PHP ::Start hidcon php-cgi -b 127.0.0.1:9124 -c ".\php.ini"||Call :Log [ERROR] Can't start PHP PopD If "%1"=="restart" ( Call :Log [WARNING] PHP-FPM crashed, restarting Exit /B ) :: nginx Call :Log Starting NginX... :start-nginx PushD .\nginx Start nginx||Call :Log [ERROR] Can't start NginX PopD If "%1"=="restart" ( Call :Log [WARNING] NginX crashed, restarting Exit /B ) :: Убиваем уже не нужные процессы hidcon TaskKill /F /IM "hidcon.exe" :: Повышаем приоритет для запущенных процессов For %%A In ("mysqld.exe", "php-cgi.exe", "nginx.exe") Do ( wmic process where name="%%~A" CALL setpriority "high priority" ) :: Создаём lock-файл и следим за его наличием Set LockFile=.\.%~n0.lock Echo.>"%LockFile%" :Watcher Ping -n %WatcherTimeout% 127.0.0.1>nul 2>nul :: Проверяем наличие процессов и перезапускаем в случае падения TaskList /FI "imagename EQ php-cgi.exe" /FO:CSV|FindStr /I /C:"php-cgi.exe">nul||Call :start-php restart :: Запускаем процесс выключения, если файл удалён If Not Exist "%LockFile%" ( Call :Log Lockfile not found, killing child processes rem Останавливаем nginx PushD .\nginx nginx -s stop PopD rem Останавливаем MySQL mysqladmin -u root -p%_DBPASS% shutdown rem Останавливаем PHP-CGI rem эта дрянь не поддерживает корректное отключение rem поэтому просто дергаем TerminateProcess() aka SIGKILL TaskKill /F /T /IM php-cgi.exe Call :Log Loader stopped Exit ) GoTo :Watcher :Log Call Echo %TimestampFormat% %*>>"%LogFile%" Exit /B |
|
Отправлено: 18:07, 26-06-2019 |
Ветеран Сообщения: 27449
|
Профиль | Отправить PM | Цитировать Цитата Anonymоus:
Цитата Anonymоus:
|
||
Отправлено: 03:40, 27-06-2019 | #2 |
Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети. Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля. |
Старожил Сообщения: 415
|
Профиль | Отправить PM | Цитировать Цитата Iska:
Тогда попрошу подсказки, как в VBS вернуть PID процесса в stdout или errorlevel, чтобы получить его основным скриптом. |
|
Отправлено: 23:24, 27-06-2019 | #3 |
Старожил Сообщения: 415
|
Профиль | Отправить PM | Цитировать WSH оказался не лучшим вариантом, в тестовой сборке у пользователей пошли ложно-положительные срабатывания антивирусов именно на сам vbs, а обьяснять каждому, как в этом зоопарке антивирусов добавить в исключения, мне честно говоря лень.
Пришлось идти по сложному варианту и просить друга помочь с написанием аналога hidcon. Выкладываю здесь, вдруг кому ещё пригодится, исходники в том же архиве, C++, собрано под x86. Синтаксис: easy_spawner "<имя программы>" <аргумент 1> ... <аргумент N> Вызываемая программа может как находиться в PATH, так и быть указана полным или относительным путем. Второй и последующий аргументы передаются вызываемой программе. PID запущенного процесса выводится в stdout и легко получается конструкцией вида Если вызываемая программа не смогла запуститься, easy_spawner устанавливает errorlevel в 1 и выводит сообщение об ошибке от программы. |
Последний раз редактировалось Anonymоus, 28-06-2019 в 04:55. Отправлено: 04:48, 28-06-2019 | #4 |
Пользователь Сообщения: 87
|
Профиль | Отправить PM | Цитировать А на какой ОС вы используете easy_spawner?
А то у меня на 10 х64 не фурычит. Какие-то окошки мигают но в таскменеджере видно что ничего не запущенно. |
|
Отправлено: 21:29, 07-07-2019 | #5 |
Старожил Сообщения: 415
|
Профиль | Отправить PM | Цитировать Patroklos, тестировалось на x64 Win10 Enterprise, тестовые сборки проверял на x86 Win10 Home. Имейте в виду, у файла нету цифровой подписи, поэтому при первом запуске его может блокировать SmartScreen.
Попробуйте добавить в path ту директорию, из которой запускаете целевой exe. Вот живой пример того, как используется у меня:
|
Отправлено: 16:20, 21-07-2019 | #6 |
Участник сейчас на форуме | Участник вне форума | Автор темы | Сообщение прикреплено |
| |||||
Название темы | Автор | Информация о форуме | Ответов | Последнее сообщение | |
CMD/BAT - Запуск процесса из папки без доступа | san1kan | Скриптовые языки администрирования Windows | 14 | 10-06-2018 21:58 | |
CMD/BAT - [решено] Как узнать PID дочернего процесса? | dima05605 | Скриптовые языки администрирования Windows | 12 | 17-10-2013 20:17 | |
.NET - Получение PID процесса, запущенного из программы | Delirium | Программирование и базы данных | 2 | 07-12-2009 02:17 | |
[решено] как узнать pid активного окна ??? | shyra1976 | AutoIt | 7 | 30-06-2009 11:22 | |
Разное - [решено] Что такое PID процесса ? | S-400 | Microsoft Windows 2000/XP | 3 | 09-05-2009 14:48 |
|