VBScript: Остановка процесса из командной строки

VBScript: Остановка процесса из командной строки Примеры скриптов и макросов для Word и WSH

В данной статье мы попробуем закрыть заданный процесс из командной строки через диалоговою форму, созданную с помощью сервера сценариев Windows Script Host на языке vbscript.

Я решил не повторять ошибку, допущенную в статье “Создаем менеджер служб”, там я впихнул сразу два огромных сценариях, и, фактически получилась сплошная каша на 12 тысяч символов. Просто я хотел сэкономить время, в результате – позиции в выдаче были хуже, чем я ожидал.

Как и прежде, для создания оконного интерфейса мы будем использовать компонент WindowSystemObject, ссылку на архив с примером вы найдете в конце статьи. Задача примера – получить список процессов, выделить нужный и (закрыть) остановить процесс из командной строки, для этого мы будем использовать утилиту taskkill.

'**************************************************************************
' Закрытие процесса из командной строки
' process-killer.vbs
'**************************************************************************
Option Explicit
 
' Формируем ссылки на объект
dim WSO, WshShell, objWMIService
 
set WSO = WScript.CreateObject("Scripting.WindowSystemObject")
set WshShell = WScript.CreateObject("WScript.Shell")
set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
 
dim list_view_obj, data_array(), t, f, def_columns
dim Button_Update, Button_Kill
dim Caption_class, GetOwner_class, ProcessId_class, ParentProcessId_class
 
'*************************************************
'            пользовательские классы
'*************************************************
Class new_class
     Dim  Caption, GetOwner, ProcessId, ParentProcessId
End Class
 
Class C_class
     Property Get name
                 name = "Описание"
     End Property
     Property Get width
                 width = 100
     End Property
 
     function set_data(item, iy)
                 item.Text = data_array(iy).Caption  
     end function
End Class
 
Class UN_class
    Property Get name
                 name = "Имя пользователя"
     End Property
     Property Get width
                 width = 120
     End Property
 
     function set_data(item, iy)
                 item.SubItems(0) = data_array(iy).GetOwner
     end function
End Class
 
Class Pid_class
     Property Get name
                 name = "PID процесса"
     End Property
     Property Get width
                 width = 80
     End Property
 
     function set_data(item, iy)
                 item.SubItems(1) = data_array(iy).ProcessId
     end function
End Class
 
Class PidP_class
     Property Get name
                 name = "PID родителя"
     End Property
     Property Get width
                 width = 80
     End Property
 
     function set_data(item, iy)
                 item.SubItems(2) = data_array(iy).ParentProcessId
     end function
End Class
'***************************************************
 
' ************************* Параметры формы ************************************************
set f = WSO.CreateForm(0, 0, 0, 0, WSO.Translate("WS_CONTROLBOX | WS_MINIMIZEBOX"))
f.Text = "Остановка процесса через командную строку"
f.ClientWidth = 560
f.ClientHeight = 300
f.CenterControl()
'***********************************************************************************************
 
'********************************************************************************
'                  Управляющие кнопки
set Button_Update = f.CreateButton(420,10,100,25,"Обновить список")
Button_Update.OnClick = getref("ProcessUpdate")
 
set t = f.CreateHyperLink(410,40,250,25,"scriptcoding.ru")
 
' Закрыть процесс через командную строку
set Button_Kill = f.CreateButton(420,70,100,25,"Остановить")
Button_Kill.OnClick = getref("ProcessKill")
 
' функция для формирования массива с данными
function fill_data_array()
dim colItems, objItem, inc, my_class, len_col, output
dim strUser, strDomain, Domain_User
     Redim data_array(0)
    inc = 0
     ' формируем коллекцию
     set colItems = objWMIService.ExecQuery("Select * from Win32_Process")
     len_col = colItems.count
     Redim data_array(len_col)
 
     ' произвдим перебор коллекции
     For Each objItem in colItems
     set my_class = new new_class
                 output = objItem.GetOwner(strUser,strDomain)
                 if output = 0 then
                            Domain_User = strDomain & "\" & strUser
                 else
                            Domain_User="Нет Доступа"
                 end if
                 with my_class
                            .Caption = objItem.Caption
                            .GetOwner = Domain_User
                            .ProcessId = objItem.ProcessId
                            .ParentProcessId = objItem.ParentProcessId
                 end with
 
                 set data_array(inc) = my_class
                 inc = inc +1
     Next
end function
 
'***************************************************************
'                      массив с данными
set Caption_class = new C_class
set GetOwner_class = new UN_class
set ProcessId_class = new Pid_class
set ParentProcessId_class = new PidP_class
def_columns = Array(Caption_class, GetOwner_class, ProcessId_class, ParentProcessId_class)
 
' Формируем панель со списком
function CreateListView()
dim def_col, column, ix, iy
 
     'Создаем объект ListView
     set list_view_obj = f.CreateListView( 0, 0, 400, 300,WSO.Translate("LVS_REPORT | LVS_SHOWSELALWAYS"))
    'Свойства объекта ListView
     list_view_obj.GridLines = true
     list_view_obj.RowSelect = true
     list_view_obj.ReadOnly = false
     ' Определяем имя и тип колонок
     for ix = 0 to UBound(def_columns)
                 set column = list_view_obj.Columns.Add(def_columns(ix).name, def_columns(ix).width)
     next
     ' Заполняем список
     fill_data_array()
     list_view_obj.Count = UBound(data_array)
     for ix = 0 to UBound(def_columns)
                 for iy=0 to list_view_obj.Count-1
                            def_columns(ix).set_data list_view_obj.item(iy), iy
                 next
     next
end function
 
'вызываем функцию для формирования списка
CreateListView()
 
f.Show()
WSO.Run()
 
'************************************************************************
'               управляющие функции
function ProcessUpdate()
dim ix, iy
     list_view_obj.Clear()
     ' Заполняем список
     fill_data_array()
     list_view_obj.Count = UBound(data_array)
     for ix = 0 to UBound(def_columns)
                 for iy=0 to list_view_obj.Count-1
                            def_columns(ix).set_data list_view_obj.item(iy), iy
                 next
     next
end function
 
' Остановить процесс из командной строки
function ProcessKill(sender)
dim cur_process_pid
     if list_view_obj.ItemIndex<0 then
                 WScript.Echo "Выберите процесс для завершения"
     elseif ServiceDialog() = 1 then
                 cur_process_pid = data_array(list_view_obj.ItemIndex).ProcessId
                 WshShell.Run "cmd.exe /c taskkill /PID " & cur_process_pid,1,true
                 WScript.Sleep 2000
                 ProcessUpdate()
     end if
end function
 
function ServiceDialog()
dim cur_process_caption, Msg, Title, result
     cur_process_caption = data_array(list_view_obj.ItemIndex).Caption
     Msg = "Вы уверены, что хотите закрыть процесс из командной строки " & cur_process_caption & " ?"
     Title = "Закрытие процесса из командной строки"
     result = MsgBox(Msg, vbOKCancel + vbInformation, Msg)
     if result = vbOK then
                 ServiceDialog = 1
     else
                 ServiceDialog = 0
     end if
end function

Первое на что стоит обратить внимание – это пользовательские классы, их всего пять:

new_class – класс содержит четыре свойства (по числу колонок в списке), в каждом свойстве хранится заданная информация о процессе (Ими (Описание), Учетный данные, под которыми работает процесс, идентификатор и идентификатор родителя).

Остальные четыре класса хранят имя колонки, ее ширину и функция, которая отвечает за добавление данных в список для текущей колонки

На форме находятся две кнопки:

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

Button_Kill – нужна, что бы остановить заданный процесс из командной строки. При нажатии будет вызываться функция ProcessKill.

Обратите внимание, что бы вызвать нужную функцию, мы используем функцию vbscript GetRef, и в качестве параметра передаем ей имя функции, но не целиком, а в виде строки. Это особенности самого языка vbscript. Фактически, GetRef формируют ссылку на копию заданной функции.

Далее идет формирование массива data_array в функции fill_data_array. Тут мы получаем доступ к классу Win32_Process, который возвращает коллекцию процессов и извлекаем четыре свойства. Сам массив data_array хранит в себе объекты с заданными свойства, число объектов ровно числу элементов в списке.

Для заполнения колонок мы обращаемся к массиву def_columns, который тоже хранит в себе объекты.

Функция CreateListView отвечает за создание списка, формирование колонок и добавление элементов.

Скачать архив с примером

Сам компонент WindowSystemObject содержит довольно широкие возможности, но… слабую справку по применению и описанию. Так, я пока не разобрался, как корректно произвести сортировку элементов, что бы было удобней остановить процесс из командной строки. Так как при сортировке данных меняется их индексы, и соответственно, должно измениться содержимое самого массива data_array.

Оцените статью
Технологии программирования и ведение блога
Добавить комментарий