Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   Автоматизация запущенного процесса (http://forum.oszone.net/showthread.php?t=348982)

АннаКузнецова 10-06-2021 12:41 2959926

Автоматизация запущенного процесса
 
Здравствуйте, уважаемые форумчане. Хочу попросить Вас о помощи в написании скрипта
Попробую описать подробно задачку:

На компьютере, должен постоянно быть запущен процесс sefmail.exe, но по причине человеческих рук, либо сверхестественных сил, этот процесс постоянно закрывается. (человеские руки считаю более очевидным :) )
Хочется чтобы скрипт, если программа не запущена- писал в лог сообщение о недоступности или в конце концов просто 0 выводил, а затем эту программу бы запускал.
Путь до программы: E:\Program Files (x86)\POST\Sefmail\

Прошу помощи в автоматизации моего процесса :)

АннаКузнецова 10-06-2021 12:49 2959927

Нашла готовый скрипт здесь: http://forum.oszone.net/thread-348778.html но он лог не пишет, если программа не работает :(

Elven 10-06-2021 14:05 2959938

Цитата:

Цитата АннаКузнецова
Нашла готовый скрипт »

какой из? там несколько решений на разных языках и все рабочие.

alpap 10-06-2021 14:15 2959939

Цитата:

Цитата АннаКузнецова
но он лог не пишет »

так допишите
и да, это на PowerShell
Код:

# Мониторинг процесса (каждые 5 сек), пропал - получим сообщение и запустим процесс через Хсек
$proc = "calc"
Function jbPrc {
  $query    = "Select * from __InstanceDeletionEvent within 5 where TargetInstance ISA 'Win32_Process' and TargetInstance.Name like '%$proc%'"
  $sourceId = "job$proc"
  Register-CimIndicationEvent -Query $query -SourceIdentifier $sourceId -Action {
    Write-Host "Process '$proc' disconnected!"
    'Process - False : '+(Get-Date -f 'dd.MM.yyyy-HH.mm.ss') >> log.txt
    Start-Sleep -s 10
    start $proc
  }
}
jbPrc

принцип тут такой:
-программа, которую он контролирует, должна быть запущена
-после этого запускается скрипт и висит ... везде, в процессах. его окно (можно свернуть. но нельзя закрывать)
-в случае если процесс программы пропал будет сообщение в окне об этом и напишется время в лог
-программа запустится после таймера, в данном скрипте - 10сек
-все начнется заново

АннаКузнецова 10-06-2021 14:39 2959941

Вложений: 1
Я запустила скрипт, при этом поменяла calc на процесс wmail. Но по моему ничего не получилось. Картинку прилагаю. Подскажите пожалуйста, что делаю не так

АннаКузнецова 10-06-2021 14:54 2959944

Elven, я имела ввиду этот скрипт:
'*******************************************************************
' Описание: Запуск отсутствующей программы
'*******************************************************************

Exe = "Notepad.exe" ' Исполнимый файл программы
PathExe = "C:\WINDOWS\system32" ' Путь к файлу (без \ на конце)

On Error Resume Next

If Err.Number = 0 Then
Set WMI = GetObject("winMgmts:")
Set Processes = WMI.ExecQuery("SELECT * FROM Win32_Process Where Name=""" + Exe + """")

Present = False
For Each Process In Processes
Present = (UCase(Process.Name) = UCase(Exe))
' MsgBox Process.Name + vbCrLf + Exe
Next

Set WS = CreateObject("WScript.Shell")

If Not Present Then
WS.Exec PathExe + "\" + Exe
End If

End If

DJ Mogarych 10-06-2021 16:17 2959959

АннаКузнецова, если Sefmail запущен, что у вас в Powershell выводит команда
Код:

get-process |? path -Match 'Sefmail'
?

АннаКузнецова 10-06-2021 17:03 2959961

DJ Mogarych,
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
636 58 41588 78456 289 4*617,75 120 sefwmail

DJ Mogarych 10-06-2021 17:50 2959965

Что-то вроде того (powershell):
Код:

if (!(get-process sefwmail -ErrorAction SilentlyContinue)) {
"$((get-date).tostring()) Sefmail не запущен, запускаю" >> 'E:\Program Files (x86)\POST\Sefmail\SefmailErrorLog.txt'
Start-Process 'E:\Program Files (x86)\POST\Sefmail\sefmail.exe'
}

В планировщике выставляете интервал запуска, предположим, каждую минуту.

Программа - powershell
Добавить аргументы:
Код:

-file "путь к скрипту\script.ps1" -executionpolicy bypass

АннаКузнецова 10-06-2021 20:04 2959972

DJ Mogarych, очень Вам признательна :) все зааботало. Только вопрос- скрипт ведь не проверяет запущен ли процесс? потому как, работает программа или нет, он в лог пишет Sefmail не запущен, запускаю

DJ Mogarych 10-06-2021 20:57 2959977

Вообще-то, проверяет.

Потестируйте с запущенной и незапущенной программой:
Код:

if (!(get-process sefwmail -ErrorAction SilentlyContinue)) {
"Не работает"
}
else {
"Работает"
}


Iska 10-06-2021 22:03 2959994

Коллеги, да не надо ничего проверять. Надо запускать процесс из самого пакетного файла/скрипта с ожиданием завершения.

Наподобие (на WSH):
Скрытый текст
Код:

Option Explicit

With WScript.CreateObject("WScript.Shell")
        Do
                ' "E:\Program Files (x86)\POST\Sefmail\sefmail.exe"
                .Run "c:\windows\system32\notepad.exe", 1, True
               
                With WScript.CreateObject("Scripting.FileSystemObject").OpenTextFile("C:\Мои проекты\0344\log.txt", 8, True)
                        .WriteLine Now() & vbTab & "сообщение о недоступности"
                        .Close
                End With
        Loop
End With

WScript.Quit 0


Уже ж было такое недавно.

alpap 11-06-2021 05:02 2960006

Цитата:

Цитата АннаКузнецова
Но по моему ничего не получилось »

все так и должно быть
вот теперь отключите (закройте окно крестиком) процесс и подождите более 10 сек, ну информацию о исчезновении процесса сразу покажет как и запись в лог
иначе скорее всего низкая версия PowerShell, надо обновить

YuS_2 12-06-2021 13:45 2960100

Цитата:

Цитата Iska
Уже ж было такое недавно. »

Навеяло: Было-было-было... но прошло... :)
Вот тут было, обратное действие...


Цитата:

Цитата АннаКузнецова
Хочется чтобы скрипт, если программа не запущена- писал в лог сообщение о недоступности или в конце концов просто 0 выводил, а затем эту программу бы запускал.
Путь до программы: E:\Program Files (x86)\POST\Sefmail\
Прошу помощи в автоматизации моего процесса »

Если адаптировать скрипт под задачу, то как-то так:
Слежение за выключением процесса script.ps1
Код:

# Не работает в версиях новее PS v5.1, https://github.com/PowerShell/PowerShell/issues/13999
[cmdletbinding()]
param(
        # Процесс для слежения можно задать в командной строке:
        # .\script.ps1 'notepad.exe','win32calc.exe'
        # или здесь:
        [string[]]$process = 'Sefmail.exe'
add-type -assembly system.windows.forms
#$control = {ps $process -ea 0}

function enable-processdeletedevent {
        $query = new-object system.management.wqleventquery "__instancedeletionevent",
        (new-object timespan 0,0,1), "targetinstance isa 'win32_process'"
        $processwatcher = new-object system.management.managementeventwatcher $query
        $argsevents = @{
                InputObject = $processwatcher
                EventName = "eventarrived"
                Action = {
                        [void] (new-event -sourceid "processdeleted" -sender $sender `
                        -eventarguments $eventargs.newevent.targetinstance)
                }
        }
        $script:job = register-objectevent  @argsevents
}
$id = "processdeleted"
enable-processdeletedevent

$form = new-object windows.forms.form
$form.autosizemode = [windows.forms.autosizemode]::growandshrink
$form.formborderstyle = [windows.forms.formborderstyle]::fixedtoolwindow
$form.windowstate = [windows.forms.formwindowstate]::maximized
$form.controlbox = $true
$form.sizegripstyle = [windows.forms.sizegripstyle]::hide
$form.text = 'Продолжить слежение?'
$form.showintaskbar = $false
$form.topmost = $true
$form.startposition = 'CenterScreen'
$btnyes = new-object windows.forms.button
$btnyes.text = 'Да'
$btnyes.location = new-object system.drawing.point(3,10)
$btnyes.dialogresult = [windows.forms.dialogresult]::ok
$form.controls.add($btnyes)
$btnno = new-object windows.forms.button
$btnno.text = 'Нет'
$btnno.location = new-object system.drawing.point(110,10)
$btnno.dialogresult = [windows.forms.dialogresult]::no
$form.controls.add($btnno)

do{
        wait-event $id|out-null
        #$p = &$control
        if($process -contains ($a = (get-event $id).sourceargs.name)){
                write-host Процесс $a был выключен $(get-date)
                #start $a
                start "E:\Program Files (x86)\POST\Sefmail\Sefmail.exe"
                remove-event $id
                $res = $form.showdialog()
        } else {
                write-host Это процесс не из списка для слежения `($a`)
                remove-event $id
        }
} while ($res -ne 'No')
if(get-event $id -ea 0){get-event $id|remove-event}
get-eventsubscriber -sub $job.id|unregister-event
get-job -id $job.id|remove-job -force



Изначально, процесс должен быть запущен. При закрытии процесса, в консоль будет выдаваться соответствующее сообщение и запуск необходимого процесса, а также при закрытии других процессов, тоже будут сообщения, но без запусков...

greg zakharov 12-06-2021 23:16 2960134

Цитата:

Цитата АннаКузнецова
человеские руки считаю более очевидным

Так для чего тогда строчить сценарий, когда можно обойтись политиками доступа? Другое дело, если процесс падает в виду, скажем, некой внутренней логической ошибки.

servad 29-06-2021 08:32 2961132

Привет, можно сделать таким образом.

$Date = Get-Date -Format "yyyy-mm-dd HH:mm:ss"
$filename = $args[0]
$process = @()
$process += Get-Process Sefmail -ea SilentlyContinue
if ($process[0]){
echo "$date 1" > $filename
}
else{
echo "$date 0" > $filename
}

Только не забудте сделать в планировщике аргумент -executionpolicy unrestricted -file "<Каталог со скриптом>" "<Каталог с логами>"


Время: 12:16.

Время: 12:16.
© OSzone.net 2001-