В заметке Проверить, запущена ли программа описано, как определить, работает ли в системе процесс с заданным именем образа, т.е. с именем исполняемого файла *.EXE, с помощью встроенной программы TASKLIST. Это хорошее решение для EXE программ. Но встречается похожая задача и для CMD/JS/VBS файлов, например, будет правильно, если командный файл проверяет при запуске, не запущена ли уже другая его копия.
Особенности запуска bat файлов и WSH скриптов
Почему tasklist не подходит
Чтобы проверить, работает ли в настоящий момент командный файл CMD или скрипт JS или VBS, нужно другое решение, потому что командные файлы выполняются процессом CMD.EXE, а конкретный командный файл передаётся в виде параметра командной строки:
cmd /c ""D:\Test\w.cmd" "
Поэтому TASKLIST даст только список процессов CMD.EXE без указания, какие именно командные файлы они выполняют.
Соответственно, для решения этой задачи нам надо получить список процессов с параметрами командной строки и выбрать строку с интересующим нас командным файлом.
Реализация через WMI
Получение списка процессов через WMI Win32_Process
Воспользуемся возможностями WSH и WMI для получения более подробной информации о процессах (фрагмент написан на JScript, можно переписать и на VBS):
// processes.js - поиск процессов по имени файла
var wmi = GetObject("winmgmts:\\\\.\\root\\CIMV2");
// Имя исполняемого файла задаётся параметром командной строки
var imagename = WScript.Arguments(0);
// Выбираем процессы cmd.exe
var items = wmi.ExecQuery("SELECT * FROM Win32_Process WHERE Name = '" + imagename + "'");
// Перебираем список и для каждого выводим PID и командную строку
var i = new Enumerator(items);
for(; !i.atEnd(); i.moveNext()){
var process = i.item();
WScript.Echo(
process.ProcessId + " " +
process.CommandLine);
}
Вывод скрипта будет примерно таким:
5472 cmd /c ""D:\Test\w.cmd" " 6668 cmd /c ""D:\Test\w2.cmd" " 7228 "C:\Windows\system32\cmd.exe" /C "C:\Windows\system32\cscript.EXE processes.js cmd.exe"
Проверка определенного bat файла
Соответственно, чтобы проверить, запущен ли командный файл w2.cmd, мы должны сделать поиск имени командного файла по выводу processes.js cmd.exe
:
@echo off
set imagename=w2.cmd
cscript processes.js cmd.exe | find /i "%imagename%"
if errorlevel 1 (
echo %imagename% не запущен
rem Выполняем действия...
) else (
echo %imagename% запущен
rem Выполняем действия...
)
Проверка определенного WSH JS/VBS скрипта
Аналогично можно проверить, запущен ли JS/VBS скрипт, которые выполняются процессами CSCRIPT.EXE (консольная версия) и WSCRIPT.EXE и фильтровать по имени JS/VBS файла.
Ну и последний штрих – как сделать всё то же самое, т.е. найти процесс, но на удалённом компьютере!
Для этого в PROCESSES.JS всего лишь изменяем текст запроса, теперь он будет содержать сетевое имя удалённого компьютера:
var computer = "."; var wmi = GetObject("winmgmts:\\\\" + computer + "\\root\\CIMV2"); // остальное остаётся без изменений