Поиск ИД запущенного процесса

29.12.24

База данных - Администрирование СУБД

Много вариантов определения номера собственного процесса самого 1С8. В ходе поиска, опираясь на общедоступную информацию, дополнил алгоритм, но с учетом определения ИД запущенного приложения.

Удивительно то, что по умолчанию разработчики в компонентах не дополняют свойство номера используемого процесса, хотя это было-бы полезно. Поэтому как видим на рисунке вопрос о номере двусторонний. Ни одно из приложений не знает под каким ИД оно находится, приходится изощряться применяя не специализированные алгоритмы вызова. 

Итак, приступим. Пример использования.
Если указать команду:

Excel=Новый COMОбъект("Excel.Application");

То сможем узнать его номер процесса. По этому номеру, например, можно процесс выгрузить, если он по какой-то причине остался.

Подготовим инструменты функций для поставленной задачи (3 функции)

Функция №1 получения таблицы значений всех запущенных процессов, чтобы отслеживать указанный процесс в параметре можно указать любой из них, например приложение Excel

//Функция получения таблицы значений всех запущенных процессов
//Параметры
//ПоФильтруПриложения - Строка -Указать имя приложения. Например "EXCEL.EXE"
//-Если не указано тогда по всем процессам
//Возвращаемое значение
//ТаблицаЗначений с именами колонок
//	-Приложение - Строка
//	-ИД - Число
//	-РодительскийИД - Число
Функция ТабЗнач_ПолучитьВсеПроцессы(Знач ПоФильтруПриложения="") Экспорт
	ПоФильтруПриложения=НРег(ПоФильтруПриложения);
	ТабЗн=Новый ТаблицаЗначений;
	ТабЗн.Колонки.Добавить("Приложение");
	ТабЗн.Колонки.Добавить("ИД");
	ТабЗн.Колонки.Добавить("РодительскийИД");
	
	Локатор=Новый COMОбъект("wbemscripting.swbemlocator");
	Сервис=Локатор.ConnectServer(".", "\root\cimv2");
	ComputerSystems = Сервис.ExecQuery("Select * from Win32_Process");
	
	Для Каждого ComputerSystem Из ComputerSystems Цикл
		ИмяПриложения=ComputerSystem.Name;
		Если ПоФильтруПриложения="" ИЛИ НРег(ИмяПриложения)=ПоФильтруПриложения Тогда
			СтрТаб=ТабЗн.Добавить();
			СтрТаб.Приложение=ИмяПриложения;
			СтрТаб.ИД=ComputerSystem.ProcessID;
			СтрТаб.РодительскийИД=ComputerSystem.ParentProcessID;
		КонецЕсли;
	КонецЦикла;
	Возврат ТабЗн	
КонецФункции


Функция №2 по объединению таблиц

//Объединяет две таблицы в одну (Необходимо чтобы имена колонок обеих таблиц были идентичными)
//Параметры
//Таблица1 - ТаблицаЗначений - Таблица значения (Будет скопирована для пополнения)
//Таблица2 - ТаблицаЗначений - Таблица значений как добавляемая
//Возвращаемое значение
//Таблица значений - Новая (Объединённая)
Функция ТабЗнач_ОбъединитьТаблицы(Таблица1, Таблица2) Экспорт
	Таблица=Таблица1.Скопировать();
	Для Каждого СтрТаб Из Таблица2 Цикл
		ЗаполнитьЗначенияСвойств(Таблица.Добавить(), СтрТаб);
	КонецЦикла;
	Возврат Таблица
КонецФункции


Функция №3 для работы с таблицами значений. Необходима для отслеживания изменений до и после загрузки стороннего приложения

//Вывести массив строк из обеих таблиц непохожие друг-на-друга. Таблицы должны быть идентичные по итменам колонок
//Параметры
//Таблица1 - ТаблицаЗначений - Таблица значений в произвольном порядке, но с идентичными именами колонок
//Таблица2 - ТаблицаЗначений - Таблица значений в произвольном порядке, но с идентичными именами колонок
//Возвращаемое значение
//МассивСтрок - массив строк объединённой таблицы, имеющие различия
Функция МассивСтрок_ПолучитьМассивОтличающихсяСтрок(Таблица1, Таблица2) Экспорт
	СистемнаяКолонка="_ГруппаКолонка";
	мКолонки=Таблица1.Колонки; //Получить массив имён колонок
	СтрКолонки="";
	Для Каждого ИмяК Из мКолонки Цикл
		СтрКолонки=СтрКолонки+ИмяК.Имя+",";
	КонецЦикла;
	СтрКолонки=Лев(СтрКолонки, СтрДлина(СтрКолонки)-1);
	
	Таблица3=ТабЗнач_ОбъединитьТаблицы(Таблица1, Таблица2);
	Таблица3.Колонки.Добавить(СистемнаяКолонка);
	Таблица3.ЗаполнитьЗначения(1,СистемнаяКолонка);
	Таблица3.Свернуть(СтрКолонки,СистемнаяКолонка);
	мСтр=Таблица3.НайтиСтроки(Новый Структура(СистемнаяКолонка, 1));
	Возврат мСтр
КонецФункции


Результирующая функция. Теперь как это совместить для определения ИД процесса

//Подключает компоненту методом  - Новый COMОбъект(ИмяКомпоненты)
//Параметры
//ИмяКомпоненты - Строка - Имя компоненты. Например: "Excel.Application"
//ИмяПроцесса - Строка - Имя, например: "EXCEL.EXE", так как оно называется в окне Диспетчера задач, по колонке [Имя образа]
//Возвращаемое значение
//Структура - с именами ключей:
//	-Приложение - COM-Объект
//	-ИД- Число/Неопределено
//	-РодительскийИД- Число/Неопределено
Функция ПодключитьКомпоненту(ИмяКомпоненты, ИмяПроцесса) Экспорт
	Стрк=Новый Структура;
	Стрк.Вставить("Приложение", Неопределено);	
	Стрк.Вставить("ИД", Неопределено);
	Стрк.Вставить("РодительскийИД", Неопределено);
	
	ТЗ1=ТабЗнач_ПолучитьВсеПроцессы(ИмяПроцесса);
	Попытка
		COM=Новый COMОбъект(ИмяКомпоненты);
		Стрк.Приложение=COM;
		
		ТЗ2=ТабЗнач_ПолучитьВсеПроцессы(ИмяПроцесса);
		мСтр=МассивСтрок_ПолучитьМассивОтличающихсяСтрок(ТЗ1, ТЗ2);
		Если мСтр.Количество()=1 Тогда
			Стрк.ИД=мСтр[0].ИД;
			Стрк.РодительскийИД=мСтр[0].РодительскийИД;
		КонецЕсли
		
	Исключение
		Сообщить("Не удалось загрузить компоненту: "+ИмяКомпоненты);
		Сообщить(ОписаниеОшибки());
	КонецПопытки;	
	Возврат Стрк	
КонецФункции


Теперь у нас есть всё необходимое. Для получения приложения с его ИД, пишем команду:

Стрк=ПодключитьКомпоненту("Excel.Application", "EXCEL.EXE");
Excel=Стрк.Приложение;
НомерПроцесса=Стрк.ИД;




Послесловие
ДЛЯ ЛЕНИВЫХ
Эта функция "ВСЁ В ОДНОМ" без прочих подготовок.

//Подключает компоненту методом  - Новый COMОбъект(ИмяКомпоненты)
//Параметры
//ИмяКомпоненты - Строка - Имя компоненты. Например: "Excel.Application"
//ИмяПроцесса - Строка - Имя, например: "EXCEL.EXE", так как оно называется в окне Диспетчера задач, по колонке [Имя образа]
//_ПолучитьТаблицуПроцессов - Булево - Не использовать. Это для внутреннего использования
//Возвращаемое значение
//Структура - с именами ключей:
//	-Приложение - COM-Объект/Неопределено
//	-ИД - Число/Неопределено
//	-РодительскийИД - Число/Неопределено
Функция ПодключитьКомпоненту(ИмяКомпоненты, ИмяПроцесса, _ПолучитьТаблицуПроцессов=Ложь) Экспорт
	
	Если _ПолучитьТаблицуПроцессов Тогда
		ПоФильтруПриложения2=НРег(ИмяПроцесса);
		ТабЗн=Новый ТаблицаЗначений;
		ТабЗн.Колонки.Добавить("Приложение");
		ТабЗн.Колонки.Добавить("ИД");
		ТабЗн.Колонки.Добавить("РодительскийИД");
		
		Локатор=Новый COMОбъект("wbemscripting.swbemlocator");
		Сервис=Локатор.ConnectServer(".", "\root\cimv2");
		ComputerSystems = Сервис.ExecQuery("Select * from Win32_Process");
		
		Для Каждого ComputerSystem Из ComputerSystems Цикл
			ИмяПриложения=ComputerSystem.Name;
			Если ИмяПроцесса="" ИЛИ НРег(ИмяПриложения)=ПоФильтруПриложения2 Тогда
				СтрТаб=ТабЗн.Добавить();
				СтрТаб.Приложение=ИмяПриложения;
				СтрТаб.ИД=ComputerSystem.ProcessID;
				СтрТаб.РодительскийИД=ComputerSystem.ParentProcessID;
			КонецЕсли;
		КонецЦикла;
		Возврат ТабЗн
	КонецЕсли;
	
	Стрк=Новый Структура;
	Стрк.Вставить("Приложение", Неопределено);	
	Стрк.Вставить("ИД", Неопределено);
	Стрк.Вставить("РодительскийИД", Неопределено);
	
	ТЗ1=ПодключитьКомпоненту(ИмяКомпоненты, ИмяПроцесса, Истина);
	Попытка
		COM=Новый COMОбъект(ИмяКомпоненты);
	Исключение
		Сообщить("Не удалось загрузить компоненту: "+ИмяКомпоненты);
		Сообщить(ОписаниеОшибки());
		Возврат Стрк
	КонецПопытки;
	
	Стрк.Приложение=COM;
	
	ТЗ2=ПодключитьКомпоненту(ИмяКомпоненты, ИмяПроцесса, Истина);
	
	//=Получить отличающиеся строки
	СистемнаяКолонка="_ГруппаКолонка";
	мКолонки=ТЗ1.Колонки; //Получить массив имён колонок
	СтрКолонки="";
	Для Каждого ИмяК Из мКолонки Цикл
		СтрКолонки=СтрКолонки+ИмяК.Имя+",";
	КонецЦикла;
	СтрКолонки=Лев(СтрКолонки, СтрДлина(СтрКолонки)-1);
	
	//=Объединить таблицы
	Таблица3=ТЗ1.Скопировать();
	Для Каждого СтрТаб Из ТЗ2 Цикл
		ЗаполнитьЗначенияСвойств(Таблица3.Добавить(), СтрТаб);
	КонецЦикла;
	Таблица3.Колонки.Добавить(СистемнаяКолонка);
	Таблица3.ЗаполнитьЗначения(1,СистемнаяКолонка);
	Таблица3.Свернуть(СтрКолонки,СистемнаяКолонка);
	мСтр=Таблица3.НайтиСтроки(Новый Структура(СистемнаяКолонка, 1));
	
	Если мСтр.Количество()=1 Тогда
		Стрк.ИД=мСтр[0].ИД;
		Стрк.РодительскийИД=мСтр[0].РодительскийИД;
	КонецЕсли;	
	
	Возврат Стрк	
КонецФункции

Вопрос для всех.
Интересно узнать как всё это провернуть более простыми решениями для определения ИД запущенного процесса?

Вступайте в нашу телеграмм-группу Инфостарт

PID ИД Процесс Идентификатор Эксель Excel Убить Зависает Отслеживание Выгрузить GUID

См. также

Администрирование СУБД Технологический журнал Мониторинг Системный администратор Программист Бесплатно (free)

Рассказываем, почему высоконагруженным бэкендам на 1С нужен регулярный мониторинг и что происходит, когда его нет: производительность и стабильность деградируют, а обращения пользователей копятся. Показываем, как построили легкую систему наблюдаемости для бэкендов корпоративных порталов. Она включает сбор метрик из технологического журнала, Apdex, журнала регистрации и динамики размеров таблиц с последующим анализом в связке ClickHouse и служебной информационной базы на 1С. Объясняем, какие отчеты и метрики быстрее всего помогают находить критичные проблемы производительности, и демонстрируем интерфейс расследования. Разбираем несколько кейсов оптимизации, найденных по итогам мониторинга, включая доработки функционала БСП «управление доступом» и «присоединенные файлы».

15.12.2025    3541    tystik    1    

8

HighLoad оптимизация Администрирование СУБД 1С:Предприятие 8 1С:ERP Управление предприятием 2 Бесплатно (free)

Завершаем цикл статей по совместному докладу Алены Генераловой и Александра Симонова на INFOSTART TECH EVENT 2025 о нагрузочном тестировании (НТ) на 30 000 АРМ на машине баз данных Tantor XData. В заключительной части расскажем о том, что нас ждало при запусках теста, и какие доработки СУБД Tantor Postgres были сделаны, чтобы его пройти с высоким результатом.

27.11.2025    2370    Tantor    28    

16

HighLoad оптимизация Администрирование СУБД Программист Бесплатно (free)

Продолжаем знакомить вас с улучшениями СУБД Tantor Postgres для работы с продуктами 1С. В рамках предыдущей статьи мы разобрали арсенал специализированных функций, призванных существенно ускорить выполнение типичных для 1С операций, снизить нагрузку на инфраструктуру и упростить администрирование. Сегодня мы рассмотрим, с какими проблемами можно столкнуться при высоких значениях default_statistics_target, расскажем о новых оптимизациях для ускорения выполнения запросов, и, конечно, коснемся временных таблиц.

11.11.2025    1607    Tantor    10    

5

Администрирование СУБД 1С:Элемент Системный администратор Программист Бесплатно (free)

1С:Управление ландшафтом – это инструмент, способный объединить десятки разрозненных систем, серверов и баз данных в единое управляемое пространство, где установка, обновление, администрирование и контроль за инфраструктурой 1С происходят из одной точки, а рутинные задачи решаются за пару минут. Расскажем о том, как сделать свой ИТ-ландшафт управляемым.

23.10.2025    4397    user2169944    2    

14

Администрирование СУБД Программист 1С:Предприятие 8 Россия Бесплатно (free)

Ошибка реструктуризации: "Запись не найдена в менеджере имен баз данных". Диагностика и решение проблемы.

22.08.2025    3046    a13k55    0    

17

Информационная безопасность Администрирование СУБД Системный администратор Бесплатно (free)

Рассказываем о безопасной и удобной организации доступа к кластеру 1С для всей ИТ-команды с помощью централизованного приложения управления. Автор показывает, как настроить разграничение прав, избежать типичных уязвимостей и эффективно управлять сеансами, не рискуя целостностью системы. Особое внимание уделено работе с объектной моделью 1С, прерыванию тяжелых запросов и диагностике проблем через технологический журнал.

11.08.2025    4766    evvakra    4    

9

Администрирование СУБД Программист 1С:Предприятие 8 1C:ERP Бесплатно (free)

Небольшая инструкция, откуда взять функциональную модель для системы 1С: СППР и как её загрузить.

06.08.2025    2930    Senator_I    2    

6
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. SerVer1C 998 09.12.24 08:29 Сейчас в теме
Операционная система
Не имеет значения

Это неправда
4. artly2000 4 09.12.24 13:22 Сейчас в теме
2. ixijixi 2097 09.12.24 08:51 Сейчас в теме
Что такое в коде
ПоТаблицамЗначений.СкопироватьТаблицу(Таблица1);
SemandCheb; +1 Ответить
3. SemandCheb 09.12.24 10:57 Сейчас в теме
(2) На сервере можно было так сделать:
Таблица = Таблица1.Скопировать();

Наверное на клиенте выполняет код,

Хотя добавляет таблицу значений, тогда код должен выполняться на сервере
6. artly2000 4 09.12.24 13:24 Сейчас в теме
(3) Это уже частности. По умолчанию: Толстый клиент
5. artly2000 4 09.12.24 13:23 Сейчас в теме
(2) Дополнено комментарием
7. user1857699 22.05.25 01:21 Сейчас в теме
// Объявление внешней функции в глобальном модуле
ВнешняяФункция("GetCurrentProcessId", "kernel32.dll", "GetCurrentProcessId")
Функция ПолучитьТекущийPID() Экспорт
Возврат GetCurrentProcessId();
КонецФункции

// Пример использования
Сообщить("PID текущего процесса: " + ПолучитьТекущийPID());
Для отправки сообщения требуется регистрация/авторизация