Мне нужен worker, который сможет запускать и останавливать Python-скрипты на Windows. В настоящий момент я работаю на тестовом стенде с Windows 10 PRO. У меня есть API, к которому Python-скрипт периодически обращается для получения задач и отправляет статус. Запуск скриптов происходит корректно, и никаких вопросов по этому поводу нет. Однако возникла проблема с остановкой скриптов. Логически процесс выглядит так: worker получает задачу на запуск определенного скрипта, запускает его, получает ID запущенного процесса и сохраняет его. В самом Python-скрипте устанавливается заголовок окна как "Agent for phone XXXXXXXXX". После некоторого времени API решает, когда отправить задачу STOP, и передает её. Однако после этого ничего не происходит.
<blockquote>//В скрипте PowerShell могут быть остатки других наработок, где я присваиваю ID процесса в заголовок окна, не обращайте внимания</blockquote>
Вот как выглядит скрипт запуска:
<pre><code># Запуск скрипта через PowerShell с названием окна по ID процесса
function Start-Script($phone) {
$scriptPath = Join-Path $SCRIPT_FOLDER "$phone.py"
if (Test-Path $scriptPath) {
# Получаем уникальное название окна на основе ID процесса
$process = Start-Process -FilePath "powershell.exe" -ArgumentList "-NoExit", "-Command", "cd '$SCRIPT_FOLDER'; Start-Sleep 1; [System.Console]::Title = 'Process_$($PID)'; python $phone.py" -PassThru
# Сохраняем ID процесса для дальнейшей остановки
$RUNNING_PROCESSES[$phone] = $process.Id
Write-Host "Скрипт $phone.py запущен с ID процесса: $($process.Id)"
} else {
Write-Host "Скрипт $phone.py не найден."
}
}</code></pre>
Все работает хорошо, скрипт запускается и выполняется, но остановить его не удается.
Чтобы остановить запущенный Python-скрипт через PowerShell, вы можете использовать `Stop-Process`, передав ему ID процесса, который вы сохранили. Предполагая, что у вас есть доступ к ID процесса (который сохраняется в массиве `$RUNNING_PROCESSES`), вы можете написать функцию для остановки скрипта.
Вот пример того, как это может выглядеть:
```powershell
# Функция для остановки скрипта по его имени
function Stop-Script($phone) {
if ($RUNNING_PROCESSES.ContainsKey($phone)) {
$processId = $RUNNING_PROCESSES[$phone]
try {
# Остановка процесса по ID
Stop-Process -Id $processId -Force
Write-Host "Скрипт $phone.py остановлен, ID процесса: $processId"
# Удаление записи о процессе
$RUNNING_PROCESSES.Remove($phone)
} catch {
Write-Host "Не удалось остановить процесс с ID $processId: $_"
}
} else {
Write-Host "Скрипт $phone.py не запущен."
}
}
```
### Примечания:
1. **Сохранение ID процесса**: Убедитесь, что вы правильно сохраняете ID процесса в `$RUNNING_PROCESSES` при запуске скрипта.
2. **Форсированная остановка**: В приведенном примере используется `-Force` для принудительной остановки процесса. Убедитесь, что это приемлемо для вашего приложения.
3. **Проверка существования процесса**: Вы можете добавить дополнительную логику для проверки, существует ли процесс перед попыткой его остановки, что может помочь избежать ошибок.
4. **Обработка ошибок**: Лучше обернуть вызов `Stop-Process` в блок `try-catch`, чтобы ловить возможные ошибки и соответствующим образом их обрабатывать.
Просто вызовите `Stop-Script` с именем телефона, когда получите команду на остановку:
```powershell
Stop-Script "XXXXXXXXX"
```
Это остановит соответствующий процесс Python-скрипта, присоединившегося к вашему worker.
На ваших скринах видно, что питон (11104) всё ещё работает. Консолька, видимо, ждёт когда дочерний процесс закроется. При этом в процессах консоль уже не отображается, встречал подобное.
Но зачем так сложно ? почему не запускать сразу питон и уже с ним работать ?
И ещё видно, что питон запускает хром с селениумом, так что тут целое дерево убивать надо.
Гораздо логичнее выставлять флажок скрипту (файлик писать куда-нибудь, например, kill-pid-11104), видя который, питон сам себя корректно завершит, безо всяких убийств