Пишем менеджер служб Windows средствами командной строки и Windows Script Host

Пишем менеджер служб Windows средствами командной строки и Windows Script Host Примеры скриптов и макросов для Word и WSH

В этой статье мы рассмотрим утилиты для возобновления, запуска, перезапуска и остановки служб Windows из командной строки и средствами WMI с использованием возможностей сервера Windows Script Host. Скажу сразу, статья будет объемная и интересная, так что запаситесь пивом и чипсами. Что именно мы изучим: утилиты командной строки, которые позволяют производить запуск службы через командную строку, возобновления, остановку и перезапуск служб Windows; напишем два примера (один на языке jscript, а другой на языке vbscript) – это будет своеобразный менеджер служб, в нем будет выводиться список всех сервисов в формате колонок (в каждой колонке будут отображаться параметры сервиса, например, имя, тип, тип запуска и так далее). Ссылку на архив с примерами я дам в конце, что бы вы не мучились копируя код. Как он будет выглядеть, вы можете увидеть на картинках ниже:

Ладно, давайте для начала рассмотрим азы, а именно, какие утилиты командной строки применяются для управления службами:

управление службами из командной строки

Утилита sc (я ее уже рассматривал частично в статье Получение списка служб средствами командной строки и сервера Windows Script Host), из нее нам понадобятся только некоторые команды, а именно:

Sc start Имя_Службы –запуск службы из командной строки
Sc pause Имя_Службы – приостановка службы Windows из командной строки
Sc continue Имя_Службы – возобновление службы из командной строки
Sc stop Имя_Службы – остановка службы из командной строки

Параметр Имя_Службы определяет имя сервиса. Так же стоит учитывать, что у сервиса могут быть зависимые от него службы.

Однако, тут есть один подводный камень – тип запуска, так если служба полностью остановлена, то вам сначала нужно изменить тип запуска, а уже потом запускать службу Windows через командную строку. Для изменения типа запуска, можно использовать следующую команду:

Sc config Имя_Службы start= флаг

Обязательно после знака равенства ставьте пробел, иначе произойдет ошибка. Флаг может принимать три значения:

Auto – автоматический запуск при старте системы
Demand – ручной запуск
Disabled – отключение

перезапуск службы из командной строки

Что бы запустить или остановить службу из командной строки, есть еще две утилиты:

net stop Имя_Службы
net start Имя_Службы

Скажу честно, в свое время на старом сайте я уже писал подобную статью, вник во все подробности данной темы, так сказать, но, материалы пришлось удалить, так как тот ресурс я закинул, а по правилам поисковой системы Яндекс не желательно, что бы два сайта одно владельца конкурировали в выдаче. Да и сама тема довольно скучная – так, для любителя. Поэтому, основной акцент данной публикации будет сделан на использование WMI для управления сервисами Windows и компонент WSO для реализации графического интерфейса. Ну а сейчас, еще немного лирики…

Не забывайте, что управлять службами Windows можно из Панели Управления, папка Администрирование, ярлык Службы.

Вообще, данную публикацию я бы физически не смог написать, если бы не два момента:

  1. Как только я начинал вести блог, то для реализации оконного интерфейса использовал программу LangMF, о нее довольно широкие возможности, но, как только я познакомился с компонентом WSO, то она мне больше не понадобилась.
  2. Как то мне взбрело в голову написать файловый менеджер с помощью языка jscript, с последующим переводом кода в область vbscript. Я накинул начальные штрихи, но … что то у меня не получалось, за советом я пошел на форум, и там мне все грамотно пояснили, и я понял … что ничего не понял. После того момента мне пришлось многое переучить и переосмыслить, как результат, я удалил практически все статьи на блоге и написал новые.
Управляющие кнопки на форме

Хорошо, теперь настало время приступить к программированию, я сначала покажу пример на языке jscript. Далее дам его описанию и информативные картинки, ну а потом уже пример на языке vbscript.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
//**************************************************************************
// Менеджер служб Windows
// service_manager.js
//**************************************************************************
 
// Формируем ссылки на объект
var WSO = new ActiveXObject("Scripting.WindowSystemObject");
var WshShell = new ActiveXObject("WScript.Shell");
var FSO = new ActiveXObject("Scripting.FileSystemObject");
var objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\\\.\\root\\cimv2");
 
var list_view_obj, shared_data_array = [];
var Button_Update, Button_Stop, Button_Run, Button_Pause;
var Button_Continue, Button_Auto, Button_Manual, Button_Disable;
 
var wbemFlagForwardOnly = 0x20; //32
var wbemFlagReturnImmediately = 0x10; //16
 
var vbOKCancel = 1;
var vbOK = 1;
var vbInformation = 64;
var vbCancel = 2;
 
// путь к временному файлу
var temp_file = WshShell.ExpandEnvironmentStrings("%TEMP%") + "\\" + FSO.GetTempName();
 
// ************************* Параметры формы ************************************************
var f = WSO.CreateForm(0, 0, 0, 0, WSO.Translate("WS_CONTROLBOX | WS_MINIMIZEBOX"));
with(f){
     Text = "Менеджер служб Windows";
     ClientWidth = 700;
     ClientHeight = 600;
     CenterControl();
}
 
//******************************************************************************
//                       Оформление
//*****************************************************************************
var b = f.Bevel(510, 90, 150,170, WSO.Translate("BS_LOWERED"))
b.Color = 0xFFFFE0
var c = f.Bevel(510, 300, 150,130, WSO.Translate("BS_LOWERED"))
c.Color = 0xFFFFE
//*******************************************************************************
 
//********************************************************************************
//                  Управляющик кнопки
//********************************************************************************
 
// Обновить списк служб
Button_Update = f.CreateButton(530,10,100,25,"Обновить список");
Button_Update.OnClick = ServiceUpdate;
 
t = f.CreateHyperLink(530,40,250,25,"scriptcoding.ru");
 
// Остановить службу из командной строки
Button_Stop = f.CreateButton(530,100,100,25,"Остановить");
Button_Stop.OnClick = ServiceStop;
 
// Запустить службу из командной строки
Button_Run= f.CreateButton(530,130,100,25,"Запустить");
Button_Run.OnClick = ServiceRun;
 
// Пристановить службу из командной строки
Button_Pause = f.CreateButton(530,160,100,25,"Пауза");
Button_Pause.OnClick = ServicePause;
 
// Возобновить службу из командной строки
Button_Continue = f.CreateButton(530,190,100,25,"Возобновить");
Button_Continue.OnClick = ServiceContinue;
 
//********************************************************************************
//********************************************************************************
 
// Перевод в автоматический режим
Button_Auto = f.CreateButton(520,310,135,25,"Автоматический режим");
Button_Auto.OnClick = ServiceAuto;
 
// Перевод в ручной режим
Button_Manual = f.CreateButton(520,340,130,25,"Ручной режим");
Button_Manual.OnClick = ServiceManual;
 
// Отключение
Button_Disable = f.CreateButton(520,370,130,25,"Отключение");
Button_Disable.OnClick = ServiceDisable;
 
//********************************************************************************
 
// функция для формирования массива с данными
function fill_data_array(data_array){
var objItem, colItems
   data_array.length = 0; // !!!!!
 
     // формируем коллекцию служб
     colItems = new Enumerator(objWMIService.ExecQuery("Select * From Win32_Service"));
 
     // произвдим перебор коллекции
     for (; !colItems.atEnd(); colItems.moveNext()){
                 objItem = colItems.item();
 
                 // добавляем в массив объект
                 data_array.push({
                            Name: objItem.Name,
                            DisplayName: objItem.DisplayName,
                            State: objItem.State,
                            PathName: objItem.PathName,
                            StartMode: objItem.StartMode
                 });
     }
};
//***************************************************************
 
// массив с данными
var def_columns = [
     { name: "Имя",      width: 100, type: 1,
                 set_data: function(item, data) { item.Text = data.Name;        }},
 
     { name: "Псевдоним",      width:  100, type: 1,
                 set_data: function(item, data) { item.SubItems(0) = data.DisplayName;  } },
 
     { name: "Статус",      width:  80, type: 1,
                 set_data: function(item, data) { item.SubItems(1) = data.State;  } },
 
     { name: "Путь",   width: 130, type: 1,
                 set_data: function(item, data) { item.SubItems(2) = data.PathName; } },
 
     { name: "Режим",     width: 100, type: 1,
                 set_data: function(item, data) { item.SubItems(3) = data.StartMode; } }
];
 
// Формируем панель со списком
function CreateListView(){
     //Создаем объект ListView
     list_view_obj = f.CreateListView( 0, 0, 500, 600,WSO.Translate("LVS_REPORT | LVS_OWNERDATA | LVS_SHOWSELALWAYS"));
    //Свойства объекта ListView
     list_view_obj.GridLines = true;
     list_view_obj.RowSelect = true;
     list_view_obj.ReadOnly = false;
     list_view_obj.ItemIndex = 1;
 
     /*--------------------------------------------------------------*/
     //         Определяем имя и тип колонок
     /*--------------------------------------------------------------*/
 
     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);
                 column.DataType = def_col.type;
     }
 
    /*--------------------------------------------------------------*/
     //                задаем обработчик событий
     /*--------------------------------------------------------------*/
     list_view_obj.OnData = function (sender, item){
                 //начало
                 sender.BeginUpdate(); 
                 //задаем текущий элемент
                 // массив shared_data_array является обработчиком через него идет обработка событий
                 var data = shared_data_array[item.Index];
 
                 //назначаем свойства для текущего элемента
                 for(var ix = 0; ix < def_columns.length; ++ix){
                            def_columns[ix].set_data(item, data);
                 }
 
                 //конец
                 sender.EndUpdate();
     };
     /* callbacks *************************************************** */
 
     // вызываем функцию получения списка данных
     fill_data_array(shared_data_array);
     //Определяем количество элементов
     list_view_obj.Count = shared_data_array.length;
};
 
// Функция обновления списка
function ServiceUpdate(){
     //очищаем поле с данными
     list_view_obj.Clear();
 
     fill_data_array(shared_data_array);
     list_view_obj.Count = shared_data_array.length; // !!!!!
};
 
//-------------------------------------------------------------------------------
//               управляющие функции
//-------------------------------------------------------------------------------
 
// Функция остановки службы из командной строки
function ServiceStop(Sender){ 
var cur_service_name, objStopService
     //если элемент не выбран
     if (list_view_obj.ItemIndex<0){
                 WScript.Echo ("Выберите службу для обработки");
     //если нажато ОК
     }else if (ServiceDialog() == 1){
                 cur_service_name = shared_data_array[list_view_obj.ItemIndex].Name;
                 objStopService = objWMIService.Get("Win32_Service.Name=\'" + cur_service_name + "\'");
                 ReturnCode = objStopService.StopService()
                 if (ReturnCode == 0) {
                            ServiceUpdate();
                 }
                 WScript.Echo("Код возврата: " + ReturnCode)
     }
};
 
// Функция запуска службы из командной строки
function ServiceRun(Sender){
var cur_service_name, objRunService
     //если элемент не выбран
     if (list_view_obj.ItemIndex<0){
                 WScript.Echo ("Выберите службу для обработки");
     //если нажато ОК
     }else if (ServiceDialog() == 1){
                 cur_service_name = shared_data_array[list_view_obj.ItemIndex].Name;
                 objRunService = objWMIService.Get("Win32_Service.Name=\'" + cur_service_name + "\'");
                 ReturnCode = objRunService.StartService()
                 if (ReturnCode == 0) {
                            ServiceUpdate();
                 }
                 WScript.Echo("Код возврата: " + ReturnCode)
     }
};
 
// Функция приостановки службы из командной строки
function ServicePause(Sender){
var cur_service_name, objPauseService
     //если элемент не выбран
     if (list_view_obj.ItemIndex<0){
                 WScript.Echo ("Выберите службу для обработки");
     //если нажато ОК
     }else if (ServiceDialog() == 1){
                 cur_service_name = shared_data_array[list_view_obj.ItemIndex].Name;
                 objPauseService = objWMIService.Get("Win32_Service.Name=\'" + cur_service_name + "\'");
                 ReturnCode = objPauseService.PauseService()
                 if (ReturnCode == 0) {
                            ServiceUpdate();
                 }
                 WScript.Echo("Код возврата: " + ReturnCode)
     }
};
 
// Функция возобновления службы из командной строки
function ServiceContinue(Sender){
var cur_service_name, objResumeService
     //если элемент не выбран
     if (list_view_obj.ItemIndex<0){
                 WScript.Echo ("Выберите службу для обработки");
     //если нажато ОК
     }else if (ServiceDialog() == 1){
                 cur_service_name = shared_data_array[list_view_obj.ItemIndex].Name;
                 objResumeService = objWMIService.Get("Win32_Service.Name=\'" + cur_service_name + "\'");
                 ReturnCode = objResumeService.ResumeService()
                 if (ReturnCode == 0) {
                            ServiceUpdate();
                 }
                 WScript.Echo("Код возврата: " + ReturnCode)
     }
};
 
// Перевод службы в автоматический режим
function ServiceAuto(Sender){
var cur_service_name, cur_service_state
     //если элемент не выбран
     if (list_view_obj.ItemIndex<0){
                 WScript.Echo ("Выберите службу для обработки");
     //если нажато ОК
     }else if (ServiceDialog() == 1){
                 cur_service_name = shared_data_array[list_view_obj.ItemIndex].Name;
                 cur_service_state = shared_data_array[list_view_obj.ItemIndex].State
                 WshShell.Run ("cmd.exe /c sc config " + cur_service_name + " start= Auto" + " > " + temp_file,1,true);
                 open_temp_file()
                 ServiceUpdate()
     }
};
 
// Перевод службы в ручной режим
function ServiceManual(Sender){
var cur_service_name, cur_service_state
     //если элемент не выбран
     if (list_view_obj.ItemIndex<0){
                 WScript.Echo ("Выберите службу для обработки");
     //если нажато ОК
     }else if (ServiceDialog() == 1){
                 cur_service_name = shared_data_array[list_view_obj.ItemIndex].Name;
                 cur_service_state = shared_data_array[list_view_obj.ItemIndex].State
                 WshShell.Run ("cmd.exe /c sc config " + cur_service_name + " start= Demand" + " > " + temp_file,1,true);
                 open_temp_file()
                 ServiceUpdate()
     }
};
 
// Отключение службы
function ServiceDisable(Sender){
var cur_service_name, cur_service_state
     //если элемент не выбран
     if (list_view_obj.ItemIndex<0){
                 WScript.Echo ("Выберите службу для обработки");
     //если нажато ОК
     }else if (ServiceDialog() == 1){
                 cur_service_name = shared_data_array[list_view_obj.ItemIndex].Name;
                 cur_service_state = shared_data_array[list_view_obj.ItemIndex].State
                 WshShell.Run ("cmd.exe /c sc config " + cur_service_name + " start= Disabled" + " > " + temp_file,1,true);
                 open_temp_file()
                 ServiceUpdate()
     }
};
 
//*****************************************************************
 
// вывод диалогового окна
function ServiceDialog(Sender){
var cur_service_name, Msg, Title, result;
     cur_service_name = shared_data_array[list_view_obj.ItemIndex].Name
     Msg = "Вы уверены, что хотите изменить состояние службы " + cur_service_name + " ?";
     Title = "Запуск службы из командной строки, остановка службы из командной строки и перезапуск ";
     result = WshShell.Popup(Msg,0,Title, vbOKCancel + vbInformation);
     // Условие для проверки, на что нажал пользователь
     if (result == vbOK) {   
                 return 1;
     }else{
                 return 0;
     }
};
 
// открытие временного файла
function open_temp_file(){
var get_file_data, data_file
     get_file_data=FSO.OpenTextFile(temp_file, 1, false)
     data_file = get_file_data.ReadAll()
     get_file_data.Close()
     WshShell.Run ("wordpad.exe " + temp_file);
}
 
//вызываем функцию для формирования списка
CreateListView();
 
f.Show();
WSO.Run();
Классы в сценарии VBSCript для управления колонками на форме

В сценарии мы создали два массива def_column и data_array, давайте рассмотрим их:

def_columns – данный массив хранит в себе объекты, которые будут отвечать за обработку каждой колонки. Реализация массива объектов для языка vbscript (прочитайте “Урок 9 по VBScript: Массивы”) и jscript (прочитайте “ Урок 5 по JScript: Работа с массивами ”) разная, поэтому давайте разберем все по отдельности:

Реализация на jscript

def_columns = [{бъект_1},{объект_2},…,{объект_n}] – как видим, через запятую в фигурных скобках мы должны указать объекты, но не имена, а весь код. Каждый объект содержит информацию об имени колонки, ее размер, тип данных и функцию, которая отвечает за доступ к выбранному элементу в списке.

Реализация на vbscript

def_columns = Array(объект_1, объект_2, …, объект_n) – на первый взгляд все просто, нам только нужно прописать через переменную имена объектов (классов), но есть одно но. Сперва нам пришлось создать эти классы, и так как колонок пять, то и классов должно быть пять, как создавать классы, почитайте в статье “ Урок 8 по VBScript: Объекты и классы ”. Прямо перед формированием массива мы создали ссылки на классы, иначе никак.

Формирование ссылки на объект для управления формой, через которую происходит запуски остановка служб из командной строки

data_array – данный массив как и предыдущий, состоит из объектов каждый объект хранит в себе информацию о выбранной службе (имя, статус, псевдоним и так далее). Каждый раз при попытке запустить службу из командной строки, остановить службу из командной строки, поставить на паузу или возобновить, или при попытке обработать выбранную службу Windows средствами WMI, будет происходить обращение к данному массиву по индексу и получение данных из текущего объекта. В большинстве случаев нам понадобится только одно свойство Name, всего объекты хранят пять свойств (число колонок).

Сам массив является динамическим, в примере на jscript добавление данных происходит с помощью функции push. В vbscript такой возможности нет, поэтому мне пришлось сначала определить длину коллекции со службами, и уже потом с помощью ключевого слова ReDim задать длину массива.

Управляющие кнопки что бы запустить или остановить службу из командной строки

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

function ServiceRun – отвечает за запуск. В теле функции сначало происходит проверка, выбрал ли пользователь служб (то есть, нажал на элемент списка), если нет – выводится предупреждающее сообщение, иначе, происходит вызов функции ServiceDialog(), данная функция выводит диалоговое окно, если вы нажнете ОК, то произойдет процесс выполнения заданной операции над служно, если нет – ничего не произойдет. Это необходимо, иначе можно наломать дров нечаянными кликами. Далее происходит процесс работы с WMI (подробней читайте в рубрике “ Windows Management Instrumentation”). Фактически, происходит подключение класса Win32_Service с фильтром по имени выбранной службы и отправка запроса. После происходит вывод кода возврата, если он равен нолю, значит все прошло успешно, иначе, что то не так. Я не стал тут приводить все коды, можете посмотреть их на странице Майкросовт.

Создание массива для обработки колонок

function ServiceStop, function ServicePause, ServiceContinue – функции, отвечающие за остановку, приостановку и возобновление сервиса Windows. Код практически тот же, что у предыдущей функции, только меняется имя метода.

А вот сейчас начинается самое забавное..

function ServiceAuto – данная функция отвечает за перевод службы в автоматический режим. Я не стал использовать функционал WMI, а решил прибегнуть к утилитам командной строки. За весь процесс отвечает следующая сточка:

WshShell.Run «cmd.exe /c sc config » & cur_service_name & » start= Auto» & » > » + temp_file,1,true

Тут происходит запуск командной строки с параметром “/c”, то есть, она автоматически завершится после выполнения команды sc config. Однако, данные будут записываться во временный файл. После выполнения команды происходит открытие файла, что бы пользователь увидел, успешной была команда или нет.

Процесс создания массива jscript для обработки колонок

ServiceManual() и ServiceDisable() – функции перевода службы Windows в ручной режим и ее отключения, код практически тот же, меняется только команда.

Ладно, вот код на vbscript:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
'**************************************************************************
' Менеджер служб Windows
' service_manager.vbs
'**************************************************************************
Option Explicit
 
' Формируем ссылки на объект
dim WSO, FSO, WshShell, objWMIService
 
set WSO = CreateObject("Scripting.WindowSystemObject")
set FSO = CreateObject("Scripting.FileSystemObject")
set WshShell = 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_Stop, Button_Run, Button_Pause
dim Button_Continue, Button_Auto, Button_Manual, Button_Disable
dim Name_class, DisplayName_class, State_class, PathName_class, StartMode_class
 
Const wbemFlagForwardOnly =32
Const wbemFlagReturnImmediately =16
 
' путь к временному файлу
dim temp_file
temp_file = WshShell.ExpandEnvironmentStrings("%TEMP%") & "\" & FSO.GetTempName()
 
'*************************************************
'            пользовательские классы
'*************************************************
Class new_class
     Dim  Name, DisplayName, State, PathName, StartMode
End Class
 
Class N_class
     Property Get name
                 name = "Имя"
     End Property
     Property Get width
                 width = 100
     End Property
     Property Get type_f
                 type_f = 1
     End Property
 
     function set_data(item, data)
                 item.Text = data.Name  
     end function
End Class
 
Class DN_class
    Property Get name
                 name = "Псевдним"
     End Property
     Property Get width
                 width = 100
     End Property
     Property Get type_f
                 type_f = 1
     End Property
 
     function set_data(item, data)
                 item.SubItems(0) = data.DisplayName
     end function
End Class
 
Class S_class
     Property Get name
                 name = "Статус"
     End Property
     Property Get width
                 width = 80
     End Property
     Property Get type_f
                 type_f = 1
     End Property
 
     function set_data(item, data)
                 item.SubItems(1) = data.State
     end function
End Class
 
Class PT_class
     Property Get name
                 name = "Путь"
     End Property
     Property Get width
                 width = 130
     End Property
     Property Get type_f
                 type_f = 1
     End Property
 
     function set_data(item, data)
                 item.SubItems(2) = data.PathName
     end function
End Class
 
Class SM_class
     Property Get name
                 name = "Режим"
     End Property
     Property Get width
                 width = 100
     End Property
     Property Get type_f
                 type_f = 1
     End Property
 
     function set_data(item, data)
                 item.SubItems(3) = data.StartMode
     end function
End Class
'***************************************************
 
' ************************* Параметры формы ************************************************
set f = WSO.CreateForm(0, 0, 0, 0, WSO.Translate("WS_CONTROLBOX | WS_MINIMIZEBOX"))
 
f.Text = "Менеджер служб Windows"
f.ClientWidth = 700
f.ClientHeight = 600
f.CenterControl()
'***********************************************************************************************
 
'******************************************************************************
'                       Оформление
'*****************************************************************************
dim b, c
set b = f.Bevel(510, 90, 150,170, WSO.Translate("BS_LOWERED"))
b.Color = &HFFFFE0
set c = f.Bevel(510, 300, 150,130, WSO.Translate("BS_LOWERED"))
c.Color = &HFFFFE
'*******************************************************************************
 
'********************************************************************************
'                  Управляющик кнопки
'********************************************************************************
 
' Обновить списк служб
set Button_Update = f.CreateButton(530,10,100,25,"Обновить список")
Button_Update.OnClick = getref("ServiceUpdate")
 
set t = f.CreateHyperLink(530,40,250,25,"scriptcoding.ru")
 
' Остановить службу из командной строки
set Button_Stop = f.CreateButton(530,100,100,25,"Остановить")
Button_Stop.OnClick = getref("ServiceStop")
 
' Запустить службу из командной строки
set Button_Run= f.CreateButton(530,130,100,25,"Запустить")
Button_Run.OnClick = getref("ServiceRun")
 
' Пристановить службу из командной строки
set Button_Pause = f.CreateButton(530,160,100,25,"Пауза")
Button_Pause.OnClick = getref("ServicePause")
 
' Возобновить службу из командной строки
set Button_Continue = f.CreateButton(530,190,100,25,"Возобновить")
Button_Continue.OnClick = getref("ServiceContinue")
 
'********************************************************************************
'********************************************************************************
 
' Перевод в автоматический режим
set Button_Auto = f.CreateButton(520,310,135,25,"Автоматический режим")
Button_Auto.OnClick = getref("ServiceAuto")
 
' Перевод в ручной режим
set Button_Manual = f.CreateButton(520,340,130,25,"Ручной режим")
Button_Manual.OnClick = getref("ServiceManual")
 
' Отключение
set Button_Disable = f.CreateButton(520,370,130,25,"Отключение")
Button_Disable.OnClick = getref("ServiceDisable")
 
'********************************************************************************
 
'********************************************************************************
 
' функция для формирования массива с данными
function fill_data_array()
dim colItems, objItem, inc, my_class, len_col
     Redim data_array(0)
    inc = 0
     ' формируем коллекцию служб
     set colItems = objWMIService.ExecQuery("Select * From Win32_Service")
     len_col = colItems.count
     Redim data_array(len_col)
 
     ' произвдим перебор коллекции
     For Each objItem in colItems
     set my_class = new new_class
                 with my_class
                            .Name = objItem.Name
                            .DisplayName = objItem.DisplayName
                            .State = objItem.State
                            .PathName = objItem.PathName
                            .StartMode = objItem.StartMode
                 end with
 
                 set data_array(inc) = my_class
                 inc = inc +1
     Next
 
end function
'***************************************************************
 
'***************************************************************
' массив с данными
'***************************************************************
 
set Name_class = new N_class
set DisplayName_class = new DN_class
set State_class = new S_class
set PathName_class = new PT_class
set StartMode_class = new SM_class
 
def_columns = Array(Name_class, DisplayName_class, State_class, PathName_class, StartMode_class)
'***************************************************************
 
' Формируем панель со списком
function CreateListView()
dim def_col, column, ix
 
     'Создаем объект ListView
     set list_view_obj = f.CreateListView( 0, 0, 500, 600,WSO.Translate("LVS_REPORT | LVS_OWNERDATA | LVS_SHOWSELALWAYS"))
    'Свойства объекта ListView
     list_view_obj.GridLines = true
     list_view_obj.RowSelect = true
     list_view_obj.ReadOnly = false
     list_view_obj.ItemIndex = 1
 
     '***************************************************************
     '         Определяемя имя и тип колонок
     '***************************************************************
 
     for ix = 0 to UBound(def_columns)
                 set column = list_view_obj.Columns.Add(def_columns(ix).name, def_columns(ix).width)
                 column.DataType = def_columns(ix).type_f
     next
 
     '********************************************************
     '               задаем обработчик событий
     '********************************************************
     list_view_obj.OnData = getref("on_data")
 
     ' вызываем функцию получения списка данных
     fill_data_array()
     'Определяем количество элементов
     list_view_obj.Count = UBound(data_array)
end function
 
' Функция обновления списка
function ServiceUpdate()
     'очищаем поле с данными
     list_view_obj.Clear()
 
     fill_data_array()
     list_view_obj.Count = UBound(data_array)
end function
 
'-------------------------------------------------------------------------------
'               управляющие функции
'-------------------------------------------------------------------------------
 
' Функция остановки службы из командной строки
function ServiceStop(Sender)
     dim cur_service_name, ReturnCode, objStopService
     'если элемент не выбран
     if list_view_obj.ItemIndex<0 then
                 WScript.Echo "Выберите службу для обработки"
     'если нажато ОК
     elseif ServiceDialog() = 1 then
                 cur_service_name = data_array(list_view_obj.ItemIndex).Name
                 set objStopService = objWMIService.Get("Win32_Service.Name=" & Chr(39) & cur_service_name & Chr(39))
                 ReturnCode = objStopService.StopService()
                 if ReturnCode = 0 then
                            ServiceUpdate()
                 end if
                 WScript.Echo "Код возврата: " & ReturnCode
     end if
end function
 
' Функция запуска службы из командной строки
function ServiceRun(Sender)
     dim cur_service_name, ReturnCode, objRunService
     'если элемент не выбран
     if list_view_obj.ItemIndex<0 then
                 WScript.Echo "Выберите службу для обработки"
     'если нажато ОК
     elseif ServiceDialog() = 1 then
                 cur_service_name = data_array(list_view_obj.ItemIndex).Name
                 set objRunService = objWMIService.Get("Win32_Service.Name=" & Chr(39) & cur_service_name & Chr(39))
                 ReturnCode = objRunService.StartService()
                 if ReturnCode = 0 then
                            ServiceUpdate()
                 end if
                 WScript.Echo "Код возврата: " & ReturnCode
     end if
end function
 
' Функция приостановки службы из командной строки
function ServicePause(Sender)
     dim cur_service_name, ReturnCode, objPauseService
     'если элемент не выбран
     if list_view_obj.ItemIndex<0 then
                 WScript.Echo "Выберите службу для обработки"
     'если нажато ОК
     elseif ServiceDialog() = 1 then
                 cur_service_name = data_array(list_view_obj.ItemIndex).Name
 
                 set objPauseService = objWMIService.Get("Win32_Service.Name=" & Chr(39) & cur_service_name & Chr(39))
                 ReturnCode = objPauseService.PauseService()
                 if ReturnCode = 0 then
                            ServiceUpdate()
                 end if
                 WScript.Echo "Код возврата: " & ReturnCode
     end if
end function
 
' Функция возобновления службы из командной строки
function ServiceContinue(Sender)
     dim cur_service_name, ReturnCode, objResumeService
     'если элемент не выбран
     if list_view_obj.ItemIndex<0 then
                 WScript.Echo "Выберите службу для обработки"
     'если нажато ОК
     elseif ServiceDialog() = 1 then
                 cur_service_name = data_array(list_view_obj.ItemIndex).Name
 
                 set objResumeService = objWMIService.Get("Win32_Service.Name=" & Chr(39) & cur_service_name & Chr(39))
                 ReturnCode = objResumeService.ResumeService()
                 if ReturnCode = 0 then
                            ServiceUpdate()
                 end if
                 WScript.Echo "Код возврата: " & ReturnCode
     end if
end function
 
' Перевод службы в автоматический режим
function ServiceAuto(Sender)
     dim cur_service_name, cur_service_state
     'если элемент не выбран
     if list_view_obj.ItemIndex<0 then
                 WScript.Echo "Выберите службу для обработки"
     'если нажато ОК
     elseif ServiceDialog() = 1 then
                 cur_service_name = data_array(list_view_obj.ItemIndex).Name
                 cur_service_state = data_array(list_view_obj.ItemIndex).State
                 WshShell.Run "cmd.exe /c sc config " & cur_service_name & " start= Auto" & " > " + temp_file,1,true
                 open_temp_file()
                 ServiceUpdate()
     end if
end function
 
' Перевод службы в ручной режим
function ServiceManual(Sender)
     dim cur_service_name, cur_service_state
     'если элемент не выбран
     if list_view_obj.ItemIndex<0 then
                 WScript.Echo "Выберите службу для обработки"
     'если нажато ОК
     elseif ServiceDialog() = 1 then
                 cur_service_name = data_array(list_view_obj.ItemIndex).Name
                 cur_service_state = data_array(list_view_obj.ItemIndex).State
                 WshShell.Run "cmd.exe /c sc config " + cur_service_name + " start= Demand" + " > " + temp_file,1,true
                 open_temp_file()
                 ServiceUpdate()
     end if
end function
 
' Отключение службы
function ServiceDisable(Sender)
     dim cur_service_name, cur_service_state
     'если элемент не выбран
     if list_view_obj.ItemIndex<0 then
                 WScript.Echo "Выберите службу для обработки"
     'если нажато ОК
     elseif ServiceDialog() = 1 then
                 cur_service_name = data_array(list_view_obj.ItemIndex).Name
                 cur_service_state = data_array(list_view_obj.ItemIndex).State
                 WshShell.Run "cmd.exe /c sc config " + cur_service_name + " start= Disabled" + " > " + temp_file,1,true
                 open_temp_file()
                 ServiceUpdate()
     end if
end function
 
' вывод диалогового окна
function ServiceDialog()
dim cur_service_name, Msg, Title, result
     cur_service_name = data_array(list_view_obj.ItemIndex).Name
 
     Msg = "Вы уверены, что хотите изменить состояние службы " & cur_service_name & " ?"
     Title = "Запуск, остановка и перезапуск службы из командной строки"
                 result = MsgBox(Msg, vbOKCancel + vbInformation, Msg)
     ' Условие для проверки, на что нажал пользователь
                 if result = vbOK then
                            ServiceDialog = 1
                 else
                            ServiceDialog = 0
                 end if
end function
 
' открытие временного файла
function open_temp_file()
dim get_file_data, data_file
     set get_file_data=FSO.OpenTextFile(temp_file, 1, false)
     data_file = get_file_data.ReadAll()
     get_file_data.Close()
     WshShell.Run "wordpad.exe " & temp_file
end function
 
Sub on_data(sender, item)
     dim data, ix
     'начало
     sender.BeginUpdate()
 
     'назначаем свойства для текущего элемента
     for ix = 0 to UBound(def_columns)
                 def_columns(ix).set_data item, data_array(item.Index)'data
     next
 
     'конец
     sender.EndUpdate()
end sub
 
'вызываем функцию для формирования списка
CreateListView()
 
f.Show()
WSO.Run()

Смотрите, если у вас возникнут вопросы по коду, то обязательно напишите в комментариях. Я сами примеры тестировал на системе Windows XP Sp3, и как они себя поведут на другой платформе не знаю. Не забывайте, что за создание оконного интерфейса отвечает компонент WindowSystemObject. При желании вы можете поэкспериментировать над кодом так, что бы можно было не средствами WMI, а через командную строку запустить, остановить, приостановить и возобновить службы Windows. И еще, а конечно не мастер, так что возможно с точки зрения профессионала код написан коряво.

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

  1. Kolis

    service_manager.vbs

    Строка: 10
    Символ: 1
    Ошибка: Невозможно создание объекта контейнером ActiveX: ‘Scripting.WindowSystemObject’
    Код: 800A01AD

    Ответить
    1. Coding автор

      ‘Не забывайте, что за создание оконного интерфейса отвечает компонент WindowSystemObject’…
      Для создания оконного интерфейса используется компонент: https://scriptcoding.ru/okonnyi-interfeys/ В статьях это упоминается…

      Ответить