Получение характеристик и управление текущим процессом 1С на основе WMI
Функционал для работы из 1С с текущим процессом класса Win32_Process. Пример получает текущее значение ОЗУ занятое процессом 1С. По описанной методике можно получать значения пиковых нагрузок на ОЗУ, время запуска текущей сессии 1С с точностью до миллисекунд. Определять загрузку активного ядра процессом и даже поменять приоритет самого процесса.
- Описание
- Подробнее
Описание
Все началось с этого топика. Ну, а точнее с поднятой темы. Идея использовать для получения размера временной структуры в ОЗУ средства WMI оказалось живучей и в конце концов привела меня к набору инструментов, позволяющих исследовать и управлять процессом 1С при помощи инструментария в общем-то диспетчера задач Windows.
Определение размера объекта, созданного в 1С при помощи замеров свободной ОЗУ оказалось не слишком информативно, так как память одновременно с 1С могут занимать и высвобождать другие процессы, поэтому пришлось идентифицировать и изучать запущенный процесс 1С. Наилучшим средством оказался класс Win32_Process, который по сути и представляет собой основу диспетчера задач Windows и при помощи нехитрых изменений базовый код функции определения объема занятой процессом ОЗУ может применяться также и для определения пиковых нагрузок, времени работы процесса, процента загрузки процессора и еще многого другого. Также можно выполнять некоторые действия с процессом типа изменения приоритета процесса.
Подробнее о доступных свойствах и методах, конечно в MSDN по классу здесь.
Ну а теперь собственно функция. Сначала для 7.7
Функция ПамятьПодПроцессом()
//Возвращает объем ОЗУ, занимаемой текущим процессом 1С 7.7 в байтах
//Через rundll32 получаем ID текущего процесса 1С
WSHShell = СоздатьОбъект(«WScript.Shell»);
l = СоздатьОбъект(«wbemscripting.swbemlocator»);
oExec = WshShell.Exec(«rundll32 kernel32,SleepEx»);
s = l.connectserver();
ProcessID = s.get(«win32_process.Handle=»+oExec.ProcessID).ParentProcessID;
УбитьРандл = oExec.ProcessID;
oExec = «»;
// Убиваем запущеный rundll32
Скрипт = «
|Function KillProc(ProcessID)
|strComputer = «».»»
|Set objWMIService = GetObject(«»winmgmts:\\»» & strComputer & «»\root\CIMV2″»)
|Set colProcesses = objWMIService.ExecQuery(«»select * from win32_process where ProcessId =»» &ProcessID)
|For Each objProcess in colProcesses
|objProcess.Terminate()
|Next
|End Function
|»;
ИспСкрипт = СоздатьОбъект(«MSScriptControl.ScriptControl»);
ИспСкрипт.Language=«vbscript»;
ИспСкрипт.AddCode(Скрипт);
ИспСкрипт.Modules(«Global»).CodeObject.KillProc(УбитьРандл);
//Находим память под текущим процессом 1С — ProcessID
Скрипт = «
|Function UsedMemory(ProcessID)
|strComputer = «».»»
|Set objWMIService = GetObject(«»winmgmts:\\»» & strComputer & «»\root\CIMV2″»)
|Set colProcesses = objWMIService.ExecQuery(«»select * from win32_process where ProcessId =»» &ProcessID)
|For Each objProcess in colProcesses
|UsedMemory = objProcess.PageFileUsage
|Next
|End Function
|»;
ИспСкрипт= СоздатьОбъект(«MSScriptControl.ScriptControl»);
ИспСкрипт.Language=«vbscript»;
ИспСкрипт.AddCode(Скрипт);
Возврат Число(ИспСкрипт.Modules(«Global»).CodeObject.UsedMemory(ProcessID));
КонецФункции
Так как работа с COM объектами и скриптами в 8-ке устроена несколько иначе, то для этой платформы та же функция будет выглядеть так:
Функция ПамятьПодПроцессом()
//Возвращает объем ОЗУ, занимаемой текущим процессом 1С 8 в байтах
WSHShell = Новый COMОбъект(«WScript.Shell»);
l= Новый COMОбъект(«wbemscripting.swbemlocator»);
oExec=WshShell.Exec(«rundll32 kernel32,SleepEx»);
s=l.connectserver();
ProcessID=s.get(«win32_process.Handle=»+СтрЗаменить(Строка(oExec.ProcessID),Символ(160),«»)).ParentProcessID;
УбитьРандл = oExec.ProcessID;
//Убиваем запущеный rundll32
Скрипт = «
|Function KillProc(ProcessID)
|strComputer = «».»»
|Set objWMIService = GetObject(«»winmgmts:\\»» & strComputer & «»\root\CIMV2″»)
|Set colProcesses = objWMIService.ExecQuery(«»select * from win32_process where ProcessId =»» &ProcessID)
|For Each objProcess in colProcesses
|objProcess.Terminate()
|Next
|End Function
|»;
ИспСкрипт = Новый COMОбъект(«MSScriptControl.ScriptControl»);
ИспСкрипт.Language = «vbscript»;
ИспСкрипт.AddCode(Скрипт);
ИспСкрипт.CodeObject.KillProc(УбитьРандл);
//Возвращает память под текущим процессом 1С
Скрипт = «
|Function UsedMemory(ProcessID)
|strComputer = «».»»
|Set objWMIService = GetObject(«»winmgmts:\\»» & strComputer & «»\root\CIMV2″»)
|Set colProcesses = objWMIService.ExecQuery(«»select * from win32_process where ProcessId =»» &ProcessID)
|For Each objProcess in colProcesses
|UsedMemory = objProcess.PageFileUsage
|Next
|End Function
|»;
ИспСкрипт = Новый COMОбъект(«MSScriptControl.ScriptControl«);
ИспСкрипт.Language = «vbscript»;
ИспСкрипт.AddCode(Скрипт);
Возврат ИспСкрипт.Run(«UsedMemory»,ProcessID);
КонецФункции
UsedMemory = objProcess.PageFileUsage и есть процесс возврата нужной информации свойством PageFileUsage класса Win32_Process. Если, допустим, нас интересует когда был запущен текущий процесс с 1С нужно использовать свойство CreationDate. Ну, а изменить приоритет выполнения процесса можно с помощью метода SetPriority().
Обе функции протестированы на работоспособность в XP SP3 и Win7 32. Не предполагаю проблем и с другими ОС, но ничего другого под рукой не было, так что ограничился этими вариантами.
Пытался использовать данный инструментарий для исследования принципов заполнения и высвобождения памяти клюшкой. Из общеметодологических выводов отмечу лишь такие, показавшиеся мне интересными моменты:
1. В большинстве случаев создание крупной структуры данных, вызывает увеличение объема занятой процессом ОЗУ (но НЕ ВСЕГДА!).
2. Конструкция типа Объект = «»; не высвобождает ОЗУ, занятую процессом и соответственно объектом
3. Чаще всего (но опять же не всегда) моментальное освобождение памяти происходит через инструкцию Объект = СоздатьОбъект() когда мы создаем новый объект по имени предыдущего.
Ну вот собственно и все. Для чего использовать данный инструмент, кроме исследования памяти занимаемой процессом решите сами. Я же если еще вернусь к более детальному исследованию особенностей поведения и использования ресурсов Windows процессом 1С, постараюсь свести свои результаты в более-менее солидное исследование и опубликую анализ полученных данных.

