Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » CMD/BAT - [решено] Запуск без видимого окна с получением PID дочернего процесса

Ответить
Настройки темы
CMD/BAT - [решено] Запуск без видимого окна с получением PID дочернего процесса

Старожил


Сообщения: 415
Благодарности: 257

Профиль | Отправить PM | Цитировать


Изменения
Автор: Anonymоus
Дата: 26-06-2019
Описание: опечатка
Приветствую уважаемых форумчан.
Есть скрипт — загрузчик, который стартует портабельную сборку 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
Благодарности: 8086

Профиль | Отправить PM | Цитировать


Цитата Anonymоus:
я запускаю через hidcon, »
А Вы не запускайте через hidecon.exe. Вам для чего hidecon.exe? Для того, чтобы скрыть консоль от пакетного файла. А Вы используйте не пакетный файл, а WSH.

Цитата Anonymоus:
Код: Выделить весь код
CD /D "%~dp0"
»
…может сыграть с Вами очень злую шутку при попытке исполнения данного пакетного файла с разделённого ресурса.
Это сообщение посчитали полезным следующие участники:

Отправлено: 03:40, 27-06-2019 | #2



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


Старожил


Сообщения: 415
Благодарности: 257

Профиль | Отправить PM | Цитировать


Цитата Iska:
А Вы используйте не пакетный файл, а WSH »
Да, похоже это единственный вменяемый вариант (кроме написания самостоятельно аналога hidcon, который будет возвращать PID)
Тогда попрошу подсказки, как в VBS вернуть PID процесса в stdout или errorlevel, чтобы получить его основным скриптом.

Отправлено: 23:24, 27-06-2019 | #3


Старожил


Сообщения: 415
Благодарности: 257

Профиль | Отправить PM | Цитировать


Вложения
Тип файла: zip easy_spawner.zip
(14.2 Kb, 21 просмотров)

WSH оказался не лучшим вариантом, в тестовой сборке у пользователей пошли ложно-положительные срабатывания антивирусов именно на сам vbs, а обьяснять каждому, как в этом зоопарке антивирусов добавить в исключения, мне честно говоря лень.
Пришлось идти по сложному варианту и просить друга помочь с написанием аналога hidcon. Выкладываю здесь, вдруг кому ещё пригодится, исходники в том же архиве, C++, собрано под x86.

Синтаксис: easy_spawner "<имя программы>" <аргумент 1> ... <аргумент N>
Вызываемая программа может как находиться в PATH, так и быть указана полным или относительным путем. Второй и последующий аргументы передаются вызываемой программе.
PID запущенного процесса выводится в stdout и легко получается конструкцией вида
Код: Выделить весь код
For /F "delims=" %%P In ('easy_spawner' "program.exe" -arg1=test --test') Do Set PID=%%~P
Если вызываемая программа не смогла запуститься, easy_spawner устанавливает errorlevel в 1 и выводит сообщение об ошибке от программы.

Последний раз редактировалось Anonymоus, 28-06-2019 в 04:55.


Отправлено: 04:48, 28-06-2019 | #4


Пользователь


Сообщения: 87
Благодарности: 4

Профиль | Отправить PM | Цитировать


А на какой ОС вы используете easy_spawner?
А то у меня на 10 х64 не фурычит.
Какие-то окошки мигают но в таскменеджере видно что ничего не запущенно.

Отправлено: 21:29, 07-07-2019 | #5


Старожил


Сообщения: 415
Благодарности: 257

Профиль | Отправить PM | Цитировать


Patroklos, тестировалось на x64 Win10 Enterprise, тестовые сборки проверял на x86 Win10 Home. Имейте в виду, у файла нету цифровой подписи, поэтому при первом запуске его может блокировать SmartScreen.
Попробуйте добавить в path ту директорию, из которой запускаете целевой exe. Вот живой пример того, как используется у меня:
HTML код: Выделить весь код
Set PHP_Pool[]="9123","9124","9125" For %%A In (%PHP_Pool[]%) Do ( For /F "delims=" %%P In ('easy_spawner "php-cgi.exe" "-b 127.0.0.1:%%~A -c .\php.ini"') Do ( Call :Log New PHP worker on port :%%~A with PID %%P Set _PHP_%%~A=%%P ) )


Отправлено: 16:20, 21-07-2019 | #6



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » CMD/BAT - [решено] Запуск без видимого окна с получением PID дочернего процесса

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
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




 
Переход