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

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

См. также

Администрирование СУБД Системный администратор Платформа 1С v8.3 Россия Бесплатно (free)

В очередной раз столкнулся с тем, что очередные обновления тонкого клиента 1С для Mac OS, загруженные с сайта обновления ПО 1С, не устанавливаются через стандартный инсталлятор и дают ошибку. Но можно все установить вручную без сторонних приложений. Описываю процесс ручной установки тонкого клиента для платформы 8.3.27.1559 на Маке с OS Sequoia 15.5.

02.06.2025    807    user1914479    11    

3

HighLoad оптимизация Администрирование СУБД Системный администратор Программист Платформа 1С v8.3 Бесплатно (free)

В финальной статье по докладу «Дамп – не приговор, а повод задуматься», с которым выступили на осенней конференции INFOSTART TECH EVENT 2024, рассказываем, чем может быть полезна информация, полученная из дампа.

27.05.2025    1411    it-expertise    0    

12

Администрирование СУБД Системный администратор Платформа 1С v8.3 Бесплатно (free)

Клиент-серверная архитектура 1С Предприятия 8.3 подразумевает работу в связке с так называемой системой управления базами данных (СУБД). Одной из самых распространённых и популярных до сих пор остается MS SQL Server.

19.05.2025    1289    Kostin1978    4    

4

HighLoad оптимизация Администрирование СУБД Системный администратор Программист Платформа 1С v8.3 Бесплатно (free)

Во второй статье по докладу «Дамп – не приговор, а повод задуматься», с которым выступили на конференции INFOSTART TECH EVENT 2024, рассмотрим, какую информацию содержат файлы дампа, чем она полезна и как ее анализировать.

14.04.2025    1354    it-expertise    7    

16

Администрирование СУБД Программист Платформа 1С v8.3 Бесплатно (free)

Где лежат данные идентификаторов, как прочитать, как поменять...

10.04.2025    1180    atdonya    0    

6

HighLoad оптимизация Администрирование СУБД Системный администратор Программист Платформа 1С v8.3 Бесплатно (free)

Опубликовали первую статью по итогам доклада «Дамп – не приговор, а повод задуматься», с которым выступали на конференции INFOSTART TECH EVENT 2024.

25.03.2025    969    it-expertise    7    

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

Это неправда
4. artly2000 4 09.12.24 13:22 Сейчас в теме
2. ixijixi 2024 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());
Оставьте свое сообщение