Что нового

Вопрос по ProcessExists

Chang

Новичок
Сообщения
45
Репутация
0
Приветствую. Пока ковыряюсь со своей автоматизацией, возникло 2 вопроса:
1. ProcessExists чувствителен к регистру ? В справки информации не нашел, тесты показали, что нет, но вдруг у меня такой процесс универсальный...
2. Как проверить, запущен ли один из процессов ? Пытался выполнить это через Or, исполняемый файл компилируется, но проверка не происходит:
Код:
If Not ProcessExists($Backup) And Not ProcessExists("sync.exe" Or "teamviewer.exe" Or "anydesk.exe" Or "rdp.exe") Then

Аналогично и с вариантом
Код:
If Not ProcessExists($Backup) And Not ProcessExists("sync.exe") Or Not ProcessExists("teamviewer.exe") Or Not ProcessExists("anydesk.exe") Or Not ProcessExists("rdp.exe") Then

Благодарю
 

All2khoff

Продвинутый
Сообщения
347
Репутация
65
самый простой способ проверки, это запустить процесс нужного приложения. и проверять его.
вполне можно брать имя процесса из диспетчера задач. как вариант использовать "пул" имён, перечисляя их в массиве или поштучно в зависимости от разрядности системы.
например: если не найдено никаких процессов 1с то запустить 1с.
Код:
Select
   Case ProcessExists("1cv8.exe")
   Case ProcessExists("1cv8s.exe")
   Case ProcessExists("1cv8c.exe")
   Case ProcessExists("1cv8.exe *32")
   Case ProcessExists("1cv8s.exe *32")
   Case ProcessExists("1cv8c.exe *32")
   Case Else
   Run ("C:\Program Files (x86)\1cv8\common\1cestart.exe")
EndSelect

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

IMStrelcov

CTPEJIbLLOB
Сообщения
253
Репутация
64
Код:
$sProcessList = 'sync.exe|teamviewer.exe|anydesk.exe|rdp.exe'

If (Not ProcessExists($Backup)) And (Not IsAnyProcessExists_($sProcessList)) Then

Func IsAnyProcessExists_($_vProcessList)
   If Not IsArray($_vProcessList) Then $_vProcessList = StringSplit($_vProcessList, '|', 3)
   For $_sProcess In $_vProcessList
      If ProcessExists($_sProcess) Then Return 1
   Next
   Return 0
EndFunc
 

Alecsis

Осваивающий
Сообщения
98
Репутация
41
имя файла .exe не всегда соответствует имени процесса
Да, это факт. А конструкция вида
Код:
ProcessExists[/URL]("1cv8.exe *32")
не прокатит.
Вот «лабораторная работа» + на всякий случай скрин Диспетчера задач W7: во 2 и 3 случаях летим мимо кассы…
Код:
Opt('MustDeclareVars', True)
ChkProcess('Punto.exe')       ; этот процесс 32-битный даже под x64
ChkProcess('Punto.exe *32')         ; попытка в стиле Win7 приводит к облому
ChkProcess('Punto.exe (32 бита)')   ; попытка в стиле Win10 = тот же случай
;
Func ChkProcess($sName)
  Local $sMsg, $iIcon
  If ProcessExists($sName) Then
      $sMsg = $sName & ' работает'
      $iIcon = 0x40
    Else
      $sMsg = $sName & ' не найден'
      $iIcon = 0x30
  EndIf
  MsgBox($iIcon, @ScriptName, $sMsg)
EndFunc
 

Вложения

  • Taskmgr_W7.png
    Taskmgr_W7.png
    33.3 КБ · Просмотры: 9

All2khoff

Продвинутый
Сообщения
347
Репутация
65
как это не прокатит? использовался мной на протяжении полугода на кассах на 7й винде в 1с розница. там была возможность у кассира из "РМК" (рабочее место кассира) выйти в операционную систему, собственно код отслеживал пропадание процесса 1с. и запускал 1с заново. таким образом обращение в it отдел по поводу закрывшейся РМК упал на 100% так как 1с запускалась обратно спустя 5 секунд.
использовалась Windows 7 Enterprise x64
Сообщение автоматически объединено:

тут как раз тема в избыточности, чем более подробно перечислить варианты имени процесса тем больше шансов его отловить. опять же никто не мешает использовать массивы, но если вариантов не много то проще просто перечислить.
Код:
Select
   Case ProcessExists("1cv8.exe")
   Case ProcessExists("1cv8s.exe")
   Case ProcessExists("1cv8c.exe")
   Case ProcessExists("1cv8.exe *32")
   Case ProcessExists("1cv8s.exe *32")
   Case ProcessExists("1cv8c.exe *32")
   Case ProcessExists("1cv8.exe (32 бита)")
   Case ProcessExists("1cv8s.exe (32 бита)")
   Case ProcessExists("1cv8c.exe (32 бита)")
   Case Else
   Run ("C:\Program Files (x86)\1cv8\common\1cestart.exe")
EndSelect
 
Последнее редактирование:
Автор
C

Chang

Новичок
Сообщения
45
Репутация
0
Всем здравствуйте. Массивы это конечно хорошо и возможно даже более правильно, но с учетом уровня моей компетенции, способ перечисления куда более близок и понятен. Glass4217, спасибо. Вечером попробую запустить, пока не особо понимаю, как это внедрить в мой код. Выглядит этот кусок кода примерно следующим образом:

Код:
$Backup = "SysDump3817.exe" ; Исполняемый файл содержит версию сборки!

While Sleep(5000)

    If _Timer_GetIdleTime() > 7200000 Then ; если время простоя рабочей станции более 2х часов

    If Not ProcessExists($Backup) And Not ProcessExists("sync.exe" Or "teamviewer.exe" Or "anydesk.exe" Or "rdp.exe") Then

    Run($Backup)

...


В итоге у меня должно получится так?
Код:
$Backup = "SysDump3817.exe" ; Исполняемый файл содержит версию сборки!

While Sleep(5000)

    If _Timer_GetIdleTime() > 7200000 Then ; если время простоя рабочей станции более 2х часов

    If Not ProcessExists($Backup) And Not ProcessExists("sync.exe" Or "teamviewer.exe" Or "anydesk.exe" Or "rdp.exe") Then

Select
   Case ProcessExists($Backup)
   Case ProcessExists("sync.exe")
   Case ProcessExists("teamviewer.exe")
   Case ProcessExists("anydesk.exe")
   Case ProcessExists("rdp.exe")
   Case Else
    Run($Backup)
EndSelect

...


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

All2khoff

Продвинутый
Сообщения
347
Репутация
65
Да верно, но грубо говоря чтобы работало везде надо чтобы вариант проверки процесса работал во всех вариантах которые могут встретиться в диспетчере задач. этот вариант не панацея, так как строго рекомендуется проверить все возможные варианты, и перечислить их в коде, но ход вашей мысли верный.
лишний подход "если" не нужен, Case работает аналогичным образом, но с большим числом перечисляемых вариантов
Код:
$Backup = "SysDump3817.exe" ; Исполняемый файл содержит версию сборки!

While Sleep(5000)

    If _Timer_GetIdleTime() > 7200000 Then ; если время простоя рабочей станции более 2х часов

Select
   Case ProcessExists($Backup)
   Case ProcessExists("sync.exe")
   Case ProcessExists("sync.exe *32")
   Case ProcessExists("sync.exe (32 бита)")
   Case ProcessExists("teamviewer.exe")
   Case ProcessExists("teamviewer.exe *32")
   Case ProcessExists("teamviewer.exe (32 бита)")  
   Case ProcessExists("anydesk.exe")
   Case ProcessExists("anydesk.exe *32")
   Case ProcessExists("anydesk.exe (32 бита)")  
   Case ProcessExists("rdp.exe")
   Case Else
    Run($Backup)
EndSelect

собственно каждый первый case в состоянии true можно воспринимать как "if ProcessExists(имяпроцесса) then действие".
Case Else воспринимается если никто из тех кто выше то значит я.
 
Последнее редактирование:
Автор
C

Chang

Новичок
Сообщения
45
Репутация
0
Glass4217, в очередной раз благодарю за разъяснение.

Подскажите пожалуйста, регистр написания процесса играет роль ? Т.е. насколько критично, если я напишу anydesk.exe, Anydesk.exe или AnyDesk.exe

Лично у меня запустился во всех 3х видах написания.
 

---Zak---

Скриптер
Сообщения
455
Репутация
120
2 @ll
Мой вариант
Код:
#include <Array.au3>

Local $pList[] = ['sync', 'teamviewer', 'anydesk', 'rdp'] ;~ можно использовать '.' в конце для ограничения имени запущенного процесса или указывать имя процесса с расширением файла ('sync.exe').

While Sleep(5000)
   If Not _IsProcessList($pList) Then
      ConsoleWrite('Run ?'&@CRLF)
   EndIf
WEnd

Func _IsProcessList($_nPID)
   For $_PID In $_nPID
      $iIndex = _ArraySearch(ProcessList(), $_PID, 0, 0, 0, 1)
      If Not @error Then Return $iIndex
   Next
   Return False
EndFunc

PS: 5 параметр функции _ArraySearch - $iCase = 0 - Поиск без учёта регистра

2 IMStrelcov
Чуть-чуть взял идею... Так что :drinks:
 
Последнее редактирование:
Автор
C

Chang

Новичок
Сообщения
45
Репутация
0
А про регистр все игнорируют мой вопрос (
 

All2khoff

Продвинутый
Сообщения
347
Репутация
65
не могу сказать про регистр ничего, у меня никогда не возникало проблемм, но я всегда брал имя процесса из диспетчера задач именно так как там записано.
предлагаю просто в качестве эксперимента. напиши имя процесса ЗаБоРчИкОм и проверь будет ли ловить. ну так ради смеха просто.
 

---Zak---

Скриптер
Сообщения
455
Репутация
120
А про регистр все игнорируют мой вопрос (
Код:
If ProcessExists("notepad.exe") Then ; проверяет, существует ли процесс
       MsgBox(4096, "Пример", "Блокнот запущен.")
   Else
       MsgBox(4096, "Пример", "Блокнот не запущен.")
   EndIf
Local $iPID = Run("notepad.exe", "", @SW_SHOWMAXIMIZED)
   If ProcessExists("NoTePaD.EXE") Then ;ЗаБоРчИк от Glass4217
       MsgBox(4096, "Пример", "Блокнот запущен.")
   Else
       MsgBox(4096, "Пример", "Блокнот не запущен.")
   EndIf
ProcessClose($iPID)


Исходя из данного примера - ProcessExists не проверяет регистр.
 

JohnWind

Новичок
Сообщения
57
Репутация
0
Доброго времени суток всем...

Столкнулся с проблемой: ProcessExists не видит Microsoft Edge.
Из хелпа по AutoIT взял пример и чуть подправил:

Код:
If ProcessExists("MicrosoftEdge.exe") = 0 Then
        MsgBox(0, 'STATUS', 'Microsoft Edge  - EXIST')
Else
        MsgBox(0, 'STATUS', 'Microsoft Edge  - DOES NOT EXIST')
EndIf

это условие подчерпнул из англо-язычного форума... пробовал прямое имя приложения - msedge.exe
пробовал как отображается процесс в списке (см. скриншот) - Microsoft Edge

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

подскажите плз в чём затык?
заранее спасибо...

=================
фигня какая-то...

запустил скрипт с ProcessList() + сохранил результат в текст-лог-файл

1. запустил Edge + запустил скрипт с ProcessList() =>> 9 записей - msedge.exe
2. выключил Edge + запустил скрипт с ProcessList() =>> 0 записей - msedge.exe

снова запустил Edge + скрипт выше с условием
If ProcessExists("msedge.exe") = 1 Then

результат >> DOES NOT EXIST

=================

кол-во фигни возрастает...
добавил в код переменную: $zzz = ProcessExists("msedge.exe")
и затем в обоих условиях распечатываю её:

Код:
$zzz = ProcessExists("msedge.exe")
If ProcessExists("msedge.exe") = 1 Then
        MsgBox(0, 'STATUS', 'Microsoft Edge  - EXIST')
        MsgBox(0, 'STATUS', $zzz)
Else
        MsgBox(0, 'STATUS', 'Microsoft Edge  - DOES NOT EXIST')
        MsgBox(0, 'STATUS', $zzz)
EndIf


в результате я похоже получаю PID (каждый раз это: 4368, см 2й скриншот) 1го найденного msedge.exe процесса, вместо 1 или 0 как это указанно в хелпе:

Функция ProcessExists
Возвращаемое значение

Значение 1 означает наличие процесса, иначе 0.
========================

по сути я могу играть от значения 0 при ProcessExists - если значение НЕ 0 - значит процесс есть, и далее его можно например удалять...
а если любое другое значение - значит Edge запущен

но вопрос к хелпу - остаётся.
 

Вложения

  • zzzz0000000000000000000000000000000.png
    zzzz0000000000000000000000000000000.png
    4.5 КБ · Просмотры: 7
  • zzzz00000000000000000000000000001111.png
    zzzz00000000000000000000000000001111.png
    10.7 КБ · Просмотры: 4
Последнее редактирование:

Norm

Продвинутый
Сообщения
270
Репутация
70
Имя процесса у Вас не соответствует указанному
Код:
#include <Array.au3> ; для _ArrayDisplay

; Список всех процессов
$aProcessList = ProcessList("msedge.exe")
_ArrayDisplay($aProcessList, 'Process/PID') ; функция просмотра массивов

If ProcessExists("msedge.exe") Then
    MsgBox(0,Default,"Подтверждение, что роцесс msedge.exe существует")
Endif
 
Последнее редактирование:

JohnWind

Новичок
Сообщения
57
Репутация
0
Имя процесса у Вас не соответствует указанному
Код:
#include <Array.au3> ; для _ArrayDisplay

; Список всех процессов
$aProcessList = ProcessList("msedge.exe")
_ArrayDisplay($aProcessList, 'Process/PID') ; функция просмотра массивов

If ProcessExists("msedge.exe") Then
    MsgBox(0,Default,"Подтверждение, что роцесс msedge.exe существует")
Endif
простите... я видимо не точно выразился:

процесс ЕСТЬ... и он в списке через ProcessList находится...
проблема в том, что согласно хелпу АвтоИТ -

Функция ProcessExists
Возвращаемое значение


Значение 1 означает наличие процесса, иначе 0.

т.е. выглядит как то что это логическая/буленовская функция, которая возвращает:
1 - да - процесс есть
0 - нет - процесса нет

у меня же выходит так:

если Edge НЕ запущен, то возвращается значение 0 - и типа это ок
но если Edge ЗАПУЩЕН - возвращается PID некоторого из процессов Edge, что при проверке на единицу (1 - да процесс есть) выдаёт фейл

и вот тут противоречие....

P.S. я уже воспользовался вариантом проверки на <> 0, что даёт нам понимание того, что процесс есть и запущен.. .и какой именно у него PID в данных условиях не важно, в т.ч. потому, что при ProcessClose ("msedge.exe") убиваются ВСЕ открытые процессы Edge.
 

Вложения

  • zzAA0001.png
    zzAA0001.png
    62.9 КБ · Просмотры: 5
Последнее редактирование:

JohnWind

Новичок
Сообщения
57
Репутация
0
у меня такого процесса "MicrosoftEdge.exe" нет

Возможно Вы используете старую версию Aotoit или справки от него
Посмотрите этот вариант ProcessExists
видимо моя - AutoIt3_2_5_4_ru.chm - версия устарела

а у вас случайно нет под рукой chm свежей версии хелпа? или линки на неё?
 
Верх