JScript: Завершение процесса из командной строки

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

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

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

//**************************************************************************
// Завершение процесса из командной строки
// process-killer.js
//**************************************************************************
 
var WSO = WScript.CreateObject("Scripting.WindowSystemObject");
var WshShell = WScript.CreateObject("WScript.Shell");
var objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\\\.\\root\\cimv2");
 
var list_view_obj, data_array = [];
var Button_Update, Button_Kill;
 
// ************************* Параметры формы ************************************************
var f = WSO.CreateForm(0, 0, 0, 0, WSO.Translate("WS_CONTROLBOX | WS_MINIMIZEBOX"));
with(f){
     Text = "Завершение процесса через командную строку";
     ClientWidth = 560;
     ClientHeight = 300;
     CenterControl();
}
 
// Обновить списк
Button_Update = f.CreateButton(420,10,100,25,"Обновить список");
Button_Update.OnClick = ProcessUpdate;
 
t = f.CreateHyperLink(410,40,250,25,"scriptcoding.ru");
 
// Завершить процесс через командную строку
Button_Kill = f.CreateButton(420,70,100,25,"Остановить");
Button_Kill.OnClick = ProcessKill;
 
// функция для формирования массива с данными
function fill_data_array(){
var objItem, colItems, output;
     data_array.length = 0;
 
     // формируем коллекцию процессов
     colItems = new Enumerator(objWMIService.ExecQuery("Select * from Win32_Process"));
 
     // производим перебор коллекции
     for (; !colItems.atEnd(); colItems.moveNext()){
                 objItem = colItems.item();
 
                 output = objItem.ExecMethod_("GetOwner");
                 if(output.ReturnValue == 0){
                            Domain_User = output.Domain + "\\" + output.User;
                 }else Domain_User="Нет Доступа";
 
                 // добавляем в массив объект
                 data_array.push({
                            Caption: objItem.Caption,
                            GetOwner: Domain_User,
                            ProcessId: objItem.ProcessId,
                            ParentProcessId: objItem.ParentProcessId
                 });
     }
};
 
// массив с данными о колонках
var def_columns = [
     { name: "Описание", width:100, set_data: function(item, it) { item.Text = data_array[it].Caption; }},
     { name: "Имя пользователя", width:120, set_data: function(item, it) { item.SubItems(0) = data_array[it].GetOwner;  } },
     { name: "PID процесса", width:80, set_data: function(item, it) { item.SubItems(1) = data_array[it].ProcessId;  } },
     { name: "PID родителя", width:80, set_data: function(item, it) { item.SubItems(2) = data_array[it].ParentProcessId; } }
];
 
// Формируем список
function CreateListView(){
     list_view_obj = f.CreateListView( 0, 0, 400, 300,WSO.Translate("LVS_REPORT | LVS_SHOWSELALWAYS"));
     list_view_obj.GridLines = true;
     list_view_obj.RowSelect = true;
     list_view_obj.ReadOnly = false;
     // Определяем имя и тип колонок
     for(var ix = 0; ix < def_columns.length; ++ix){
                 var def_col = def_columns[ix];
                 var column = list_view_obj.Columns.Add(def_col.name, def_col.width);
     }
     // Заполняем список
     fill_data_array();
     list_view_obj.Count = data_array.length;
     for(var ix = 0; ix < def_columns.length; ++ix){
                 for (var iy=0; iy<list_view_obj.Count; iy++){
                            def_columns[ix].set_data(list_view_obj.item(iy), iy);
                 }
     }         
};
 
//вызываем функцию для формирования списка
CreateListView();
 
f.Show();
WSO.Run();
 
//************************************************************************
//               управляющие функции
 
function ProcessUpdate(){
     list_view_obj.Clear();
     list_view_obj.Count = 0;
     fill_data_array();
     list_view_obj.Count = data_array.length;
     for(var ix = 0; ix < def_columns.length; ++ix){
                 for (iy=0; iy<list_view_obj.Count; iy++){
                            def_columns[ix].set_data(list_view_obj.item(iy), iy);
                 }
     }         
};
 
function ProcessKill(sender, item){      
var cur_process_pid;
     if (list_view_obj.ItemIndex<0){
                 WScript.Echo ("Выберите процесс для завершения");
     }else if (ServiceDialog() == 1){
                 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();
     }
};
 
function ServiceDialog(sender, item){
var cur_process_caption, Msg, Title, result;
var vbOKCancel = 1, vbOK = 1, vbInformation = 64, vbCancel = 2;
 
     cur_process_caption = data_array[list_view_obj.ItemIndex].Caption
     Msg = "Вы уверены, что хотите завершить процесс " + cur_process_caption + " ?";
     Title = "Завершение процесса из командной строки";
     result = WshShell.Popup(Msg,0,Title, vbOKCancel + vbInformation);
     // Условие для проверки, на что нажал пользователь
     if (result == vbOK) { return 1; }else{ return 0;}
};

В сценарии используются три пользовательские функции:

ProcessUpdate() – отвечает за очистку текстового поля со списком процессов и вывод данных заново. Данная функция нужна в том случае, что, если вы завершили процесс через командную строку, то нужно обновить данные, что бы увидеть, прошло все успешно или нет.

ProcessKill – функции выполняет завершение процесса из командной строки. Тут вначале идет проверка – был ли выбран элемент, если нет, идет вывод предупреждающего сообщения. Если да, идет снова вызов диалогового окна, где пользователю нужно подтвердить или отменить свое действие. Если пользователь нажал ОК, то идет вызов строки:

WshShell.Run ("cmd.exe /c taskkill /PID " + cur_process_pid,1,true);

Как видим, мы используем утилиту taskkill что бы завершить процесс через командную стоку, в качестве параметра передается идентификатор. Любопытно заметить, что утилита позволяет завершить даже процесс, работающий под администратором, хотя сам скрипт работает под гостем с ограниченными павами, в диспетчере задач такое не прокатывает. Хотя, может и у меня глюк, так как целую ночь не спал.

ServiceDialog – собственно, вывод диалогового окна и проверка, что нажал пользователь.

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

Конечно, можно не завершать процесс через командную строку, а использовать возможности класса Win32_Process инструментария WMI. Но, данный пример всеровно предоставляет чисто теоретический интерес, так как с точки зрения практики, было бы не плох написать полный аналог Диспетчера Задач… полагаю, это возможно. Просто сейчас мне нужно увеличить количество материала на блоге и свой опыт, для создания нового видео-курса.

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