Что нового

Вопрос по 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

Благодарю
 

Glass4217

Осваивающий
Сообщения
266
Репутация
48
самый простой способ проверки, это запустить процесс нужного приложения. и проверять его.
вполне можно брать имя процесса из диспетчера задач. как вариант использовать "пул" имён, перечисляя их в массиве или поштучно в зависимости от разрядности системы.
например: если не найдено никаких процессов 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
Сообщения
223
Репутация
52
Код:
$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

Осваивающий
Сообщения
59
Репутация
27
имя файла .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 КБ · Просмотры: 8

Glass4217

Осваивающий
Сообщения
266
Репутация
48
как это не прокатит? использовался мной на протяжении полугода на кассах на 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

...


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

Glass4217

Осваивающий
Сообщения
266
Репутация
48
Да верно, но грубо говоря чтобы работало везде надо чтобы вариант проверки процесса работал во всех вариантах которые могут встретиться в диспетчере задач. этот вариант не панацея, так как строго рекомендуется проверить все возможные варианты, и перечислить их в коде, но ход вашей мысли верный.
лишний подход "если" не нужен, 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
А про регистр все игнорируют мой вопрос (
 

Glass4217

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

---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 не проверяет регистр.
 
Верх