Решаем проблему с разными версиями платформ при COM соединении

13.10.15

База данных - Инструменты администратора БД

Код позволяет перед подключением установить нужную версии comcntr.dll

Файлы

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование Скачано Купить файл
Пример работы кода
.epf 8,42Kb
13 1 850 руб. Купить
Пример работы кода (добавлен код для выполнения на сервере без com объекта)
.epf 8,67Kb
26 1 850 руб. Купить

Подписка PRO — скачивайте любые файлы со скидкой до 85% из Базы знаний

Оформите подписку на компанию для решения рабочих задач

Оформить подписку и скачать решение со скидкой

В последнее время 1С стала очень часто выпускать новые релизы платформы, к новым функциям которой привязывают типовые конфигурации, например БП 3.0.

Большинство крупных организаций ведут учет своей деятельности в нескольких системах и чаще всего некоторые из этих систем просто невозможно запустить без серьезных доработак и рефакторинга.

В связи с этим на серверах начинают соседствовать по несколько различных релизов платформ. Это затрудняет поддержку систем и их взаимодействия.

Данный код призван упростить жизнь программистам, работающим в таких условиях.

&НаКлиенте
Процедура Команда1(Команда)
	Путь	= ПутьКDLL;
	ЗавершатьПринудительно	= ЗавершатьПриложениеЕслиОноАктивно;
	рез	= ЗарегистрироватьНужнуюКомпоненту(Путь,ЗавершатьПринудительно);
КонецПроцедуры

&НаКлиенте
Процедура Команда2(Команда)	
	ВызовССервера(ПутьКDLL,ЗавершатьПриложениеЕслиОноАктивно);
КонецПроцедуры

&НаСервере
Процедура ВызовССервера(ПутьКDLL,ЗавершатьПриложениеЕслиОноАктивно)

	Путь					= ПутьКDLL;
	ЗавершатьПринудительно	= ЗавершатьПриложениеЕслиОноАктивно;
	рез	= ЗарегистрироватьНужнуюКомпоненту(Путь,ЗавершатьПринудительно);	
	
КонецПроцедуры


#Область Механизм_регистрации_COM_компоненты

//Возвращаем текущий путь, может пригодиться для восстановления после работы
&НаКлиентеНаСервереБезКонтекста
Функция ЗарегистрироватьНужнуюКомпоненту(Путь,МожноОтключатьПриложение = истина)
	
	//Проверяем досутпность dll
	файл	= новый Файл(Путь);
	Если не файл.Существует() тогда возврат новый структура("Путь,Результат",Путь,ложь); КонецЕсли;

	ПутьВозврат	= Путь;
	
	//Инициализируем системный объект
	Каталог	= новый Comобъект ("COMAdmin.COMAdminCatalog");
	//Делаем выборку всех приложений
	Приложения	= Каталог.GetCollection("Applications");//TopCollection  Applications AppObject.Key
	Приложения.Populate();
	
	//Ищем по имени наше приложение
	ключ	= неопределено;
	for each Приложение in Приложения цикл
		Если врег(Приложение.Name) = ВРег("V83_COMConnector") тогда
			ключ	= Приложение;
			прервать;
		КонецЕсли;
	КонецЦикла; 
	
	//Если не нашли то создаем приложение и импортируем в него компоненту
	Если ключ	= неопределено Тогда
		СоздатьПриложение(Путь);
		возврат новый структура("Путь,Результат",ПутьВозврат,истина);
	КонецЕсли;
	
	//Если приложение найдено, то получаем все компоненты в нем
	компоненты = Приложения.GetCollection("Components", Приложение.Key);// PropertyInfo  App.Value[prop.Name]
	компоненты.Populate();
	
	//Ищем нашу компоненту по имени
	ключ	= неопределено;
	ид	= 0;
	Для каждого Компонент Из компоненты Цикл	
		Если Компонент.Name = "V83.COMConnector.1" Тогда
			ключ	= Компонент;
			прервать; 
		КонецЕсли; 
		ид	= ид + 1;
	КонецЦикла; 
	
	//проверка можем ли мы отключать приложение, это нужно чтобы никого не рубануть случайно, если пофиг то рубим
	если не МожноОтключатьПриложение тогда
		//если нельзя то проверяем запущено ли приложение
		свва	= Приложения.GetCollection("PropertyInfo", Приложение.Key);
		свва.Populate();
		
		CLSID = Неопределено;
		Для каждого св Из свва Цикл
			Если св.Name = "ID" тогда
				CLSID	= Приложение.Value(св.Name);
			КонецЕсли;
		КонецЦикла;
		
		Locator = новый Comобъект("WbemScripting.SWbemLocator");
		
		ServicesSet	= Locator.ConnectServer(".", "root\cimv2");
		ServicesSet.Security_.Privileges.AddAsString("SeDebugPrivilege",True);
		выборка	= ServicesSet.ExecQuery("SELECT * FROM Win32_Process Where Name = ""dllhost.exe""
		| and CommandLine Like ""%/Processid:" + CLSID + "%"" ");      
		
		для каждого стр из выборка цикл
			возврат новый структура("Путь,Результат",ПутьВозврат,ложь);
		конеццикла;
	конецЕсли;
	
	//Если не нашли то создаем компоненту
	Если ключ	= неопределено Тогда
		//для начала остановим приложение
		Каталог.ShutdownApplication(Приложение.Name);
		ИмпортироватьКомпоненту(путь,Каталог); 
		возврат новый структура("Путь,Результат",ПутьВозврат,истина);
	КонецЕсли;
	
	//Если нашли то получаем все ее свойства
	свва	= Компоненты.GetCollection("PropertyInfo", Компонент.Key);
	свва.Populate();
	
	//Ищем путь к компоненте для сравнения
	dll = Неопределено;
	Для каждого св Из свва Цикл
		Если св.Name = "DLL" тогда
			dll	= Компонент.Value(св.Name);
			Прервать;
		КонецЕсли;				
	КонецЦикла;
	
	//Если пути разные то удаляем текущую и импортируем новую компоненту
	Если не врег(dll) = врег(Путь) Тогда
		ПутьВозврат	= dll;
		Каталог.ShutdownApplication(Приложение.Name);
		
		Компоненты.remove(ид);
		компоненты.SaveChanges();
		компоненты.Populate();
		
		ИмпортироватьКомпоненту(путь,Каталог); 
		возврат новый структура("Путь,Результат",ПутьВозврат,истина);
	КонецЕсли;		
	
	возврат новый структура("Путь,Результат",ПутьВозврат,ложь);
	
КонецФункции

#Область Служебные_процедуры
	
&НаКлиентеНаСервереБезКонтекста
Процедура ИмпортироватьКомпоненту(знач Путь, Каталог)
	попытка
		Имя	= "V83_COMConnector";
		Каталог.InstallComponent(Имя,путь,"","");
	исключение
		//сообщить(ОписаниеОшибки());
	конецпопытки;
КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Процедура СоздатьПриложение(путь)
	попытка
		СкриптМенеджер = Новый COMОбъект("MSScriptControl.ScriptControl");
		Скрипт = " Function SetFuncValue(Path)
		|Dim objCatalog 'As COMAdminCatalog
		|Set objCatalog = CreateObject(""COMAdmin.COMAdminCatalog"")
		|Dim objApplicationsColl 'As COMAdminCatalogCollection
		|Set objApplicationsColl = objCatalog.GetCollection(""Applications"")
		|Dim objApp 'As COMAdminCatalogObject
		|Set objApp = objApplicationsColl.Add
		|objApp.Value(""Name"") = ""V83_COMConnector""
		|objApp.Value(""Description"") = ""Компонента 1С""
		|objApp.Value(""ApplicationAccessChecksEnabled"") = false
		|objApplicationsColl.SaveChanges
		|objApplicationsColl.Populate
		|Set roles = objApplicationsColl.GetCollection(""Roles"", objApp.key)
		|Set newRole = roles.Add
		|newRole.Value(""Name"") = ""CreatorOwner""
		|roles.SaveChanges
		|objCatalog.InstallComponent objApp.key,Path,"""",""""
		|End Function";
		СкриптМенеджер.Language = "vbscript";
		СкриптМенеджер.AddCode(Скрипт);
		СкриптМенеджер.Run("SetFuncValue", путь);
	Исключение
		сообщить(ОписаниеОшибки());
	КонецПопытки;
КонецПроцедуры

#КонецОбласти 

#КонецОбласти

Для корректной работы данного кода у пользователя, от имени которого запущена 1С, должны быть соответствующие права. Своих пользователей мы добавили в группу DCOM в AD, этого было достаточно.

Код имеет достаточно комментариев, поэтому расписывать его работу нет необходимости.

UPD:

Небольшая функция для получения пути к целевой dll:

Функция ПолучитьПутьКDll(Версия_ = "") Экспорт
Locator = новый Comобъект("WbemScripting.SWbemLocator");
ТекстЗапроса = "select * from WIN32_Product where Name like ""%1C:Предприятие 8%"" and Version = """ + Версия_+"""";
ServicesSet = Locator.ConnectServer(".", "root\cimv2");
ServicesSet.Security_.Privileges.AddAsString("SeDebugPrivilege",True);
выборка = ServicesSet.ExecQuery(ТекстЗапроса);
х64 = Неопределено;
х86 = Неопределено;
Этох64 = ложь;
Для каждого прога Из выборка Цикл
Путь = прога.Properties_("InstallLocation").Value+"bin\comcntr.dll";
Этох64 = не СтрНайти(прога.Properties_("Name").Value,"(x86-64)") = 0;
Если Этох64 Тогда
х64 = путь;
иначе 
х86 = путь;
КонецЕсли; 
КонецЦикла;

Возврат ?(х64 = Неопределено,х86,х64);

КонецФункции // ПолучитьПутьКDll()

Получаем пути установки 1С и подбираем нужный. Функция работает медленно.

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

COMОбъект COMAdmin COMConnector MSScriptControl Обмен comcntr.dll Regsvr32

См. также

Инструментарий разработчика Чистка данных Свертка базы Инструменты администратора БД Системный администратор Программист Руководитель проекта 1С v8.3 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 Россия Платные (руб)

Инструмент представляет собой обработку для проведения свёртки или обрезки баз данных. Работает на ЛЮБЫХ конфигурациях (УТ, БП, ERP, УНФ, КА и т.д.). Поддерживаются серверные и файловые базы, управляемые и обычные формы. Может выполнять свертку одновременно в несколько потоков. А так же автоматически, без непосредственного участия пользователя. Решение в Реестре отечественного ПО

14400 руб.

20.08.2024    42725    233    120    

217

Инструменты администратора БД Инструментарий разработчика Роли и права Программист 1С v8.3 1C:Бухгалтерия Россия Платные (руб)

Расширение позволяет без изменения кода конфигурации выполнять проверки при вводе данных, скрывать от пользователя недоступные ему данные, выполнять код в обработчиках. Не изменяет данные конфигурации, легко устанавливается практически на любую конфигурацию на управляемых формах.

16000 руб.

10.11.2023    19414    76    39    

92

Инструменты администратора БД Роли и права Системный администратор Программист Пользователь 8.3.14 1С:Розница 2 1С:Управление нашей фирмой 1.6 1С:Документооборот 1С:Зарплата и кадры государственного учреждения 3 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Платные (руб)

Роли… Вы тратите много времени и сил на подбор ролей среди около 2400 в ERP или 1500 в Рознице 2, пытаясь понять какими правами они обладают? Вы все время смотрите права в конфигураторе или отчетах чтоб создать нормальные профили доступа? Вы хотите наглядно видеть какие права дает профиль и редактировать все в простом виде? А может хотите просто указать подсистему и дать права на просмотр и добавление на объекты и не лезть в дебри прав и чтоб обработка сама подобрала нужные роли? Все это теперь стало возможно! Обновление от 17.06.2025, версия 1.3

20400 руб.

06.12.2023    17520    66    10    

100

Инструменты администратора БД Системный администратор Программист 1С v8.3 1C:Бухгалтерия Платные (руб)

Брандмауэр для сервера 1С включает в себя управление возможностью начала и возобновления сеансов пользователей по различным условиям, ограничение общего числа возможных сеансов для работы с информационной базой, резервирование возможности работы с информационной базой определенных польззователей, запрет запуска нескольких сеансов для пользователя, журнализация событий начала (возобновления) и завершения (гибернации) сеансов, ведение списка активных сеансов для информационных баз кластера серверов

3600 руб.

06.02.2017    33811    146    18    

51

Закрытие периода Инструменты администратора БД Корректировка данных Бухгалтер Пользователь Бухгалтерский учет 1С:Бухгалтерия 3.0 Россия Бухгалтерский учет Платные (руб)

Расширение «Оперативное проведение» в 4 раза уменьшает время проведения документов и закрытия месяца. Является комплексным решением проблем 62 и 60 счетов. Оптимизирует проведение при включенной функциональной опции «Раздельный учет НДС». Используется в более 10 организациях уже 2 года. Совместимо с конфигурацией Бухгалтерия 3.0 (+КОРП).

14400 руб.

29.04.2020    39448    116    152    

82

Инструменты администратора БД Системный администратор Программист 1С v8.3 1C:Бухгалтерия Платные (руб)

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

140000 руб.

10.08.2012    124843    9    122    

195

Администрирование Инструменты администратора БД Удаленное управление Системный администратор 1С v8.3 1С:Зарплата и Управление Персоналом 3.x Платные (руб)

Расширение разработано для автоматизации интеграции «1С:Зарплата и управление персоналом (редакция 3.1)» с сервисом Яндекс 360 через платформу «n8n». Расширение позволяет автоматически создавать учетные записи Яндекс для новых сотрудников, обновлять данные существующих сотрудников и блокировать учетные записи уволенных сотрудников. Обмен данными осуществляется через API Яндекс 360 с использованием промежуточного сервера платформы n8n, что обеспечивает гибкость, масштабируемость и упрощение интеграционных процессов.

5000 руб.

03.04.2025    1957    3    0    

4
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. Yashazz 4876 31.08.15 22:19 Сейчас в теме
Ну естессно, теперь, после шикарной статьи от tormozit'а, легко клепать такие публикации, ага-ага.
3. Zhilyakovdr 148 31.08.15 23:04 Сейчас в теме
(1) Yashazz, Вы про эту статью Статья ???
2. Zhilyakovdr 148 31.08.15 23:00 Сейчас в теме
Хм... после какой статьи??? Этот код был написан пол года назад, руки не доходили статью набросать. Весь код написан с нуля!
4. tormozit 7311 01.09.15 08:35 Сейчас в теме
Объект MSScriptControl.ScriptControl к сожалению не доступен в 64-битном процессе. Поэтому приведенный код в случае отсутствия COM+ приложения без ошибок выполнится только
- на толстом клиенте
- на 32-битном сервере
- в файловой базе в любом контексте
5. Zhilyakovdr 148 01.09.15 09:10 Сейчас в теме
(4) tormozit, Хм.... почему же у меня работает на 64-битном сервере и на тонком клиенте??? Да и клиентские системы 64-битные....
Этот код выполняется клиентами на клиентских машинах (32 и 64), он для этого и писался чтобы не бегать по клиентам и не ставить вручную.
Только что специально смоделировал (Тонкий клиент 64 система сервер 64) все работает.
Если у вас падает с ошибкой то ошибку в студию попробуем разобраться.
6. tormozit 7311 01.09.15 09:23 Сейчас в теме
(5) Попробуйте выполнить код
Новый COMОбъект("MSScriptControl.ScriptControl")
на 64-битном сервере.
7. Zhilyakovdr 148 01.09.15 11:44 Сейчас в теме
(6) tormozit, вы правы, действительно падает с ошибкой, код которым можно заменить вызов com объекта:
Скрипт = "Dim objCatalog 'As COMAdminCatalog
        |Set objCatalog = CreateObject(""COMAdmin.COMAdminCatalog"")
        |Dim objApplicationsColl 'As COMAdminCatalogCollection
        |Set objApplicationsColl = objCatalog.GetCollection(""Applications"")
        |Dim objApp 'As COMAdminCatalogObject
        |Set objApp = objApplicationsColl.Add
        |objApp.Value(""Name"") = ""V83_COMConnector""
        |objApp.Value(""Description"") = ""Компонента 1С""
        |objApp.Value(""ApplicationAccessChecksEnabled"") = false
        |objApplicationsColl.SaveChanges
        |objApplicationsColl.Populate
        |Set roles = objApplicationsColl.GetCollection(""Roles"", objApp.key)
        |Set newRole = roles.Add
        |newRole.Value(""Name"") = ""CreatorOwner""
        |roles.SaveChanges
        |objCatalog.InstallComponent objApp.key,"""+путь+""","""",""""
        |";
        ВрСкрипт	= ПолучитьИмяВременногоФайла("vbs");
     	
     	ЗТ = Новый ЗаписьТекста(ВрСкрипт, КодировкаТекста.ANSI); 
		ЗТ.Закрыть(); 
		ЗТ = Новый ЗаписьТекста(ВрСкрипт,,, Истина, Символы.ПС); 
		ЗТ.Записать(Скрипт); 
		ЗТ.Закрыть();

     	СтрокаВыполненияСкрипта	= "wscript.exe "+ВрСкрипт+""""; 
       	СтрокаКВыполнению		= "cmd /C """+СтрокаВыполненияСкрипта;
        ЗапуститьПриложение(СтрокаКВыполнению);
Показать


Как руки дойдут допишу статью.
8. TerveRus 27.10.17 16:55 Сейчас в теме
(7) спасибо, помогло на Windows Server 2012 R2 x64!
9. M_Volkov 5 19.07.19 08:00 Сейчас в теме
(7) Процедура СоздатьПриложение(путь) создает OLE соединение V83.Application, или COM соединение V83.COMConnector (с ограниченными возможностями, запускается небольшая серверная часть)?
10. Zhilyakovdr 148 20.07.19 21:27 Сейчас в теме
11. M_Volkov 5 21.07.19 06:53 Сейчас в теме
(10)
V83.COMConnector
Создать OLE соединение V83.Application в консоли Службы компонентов в принципе создать невозможно ни программно, ни вручную?
12. M_Volkov 5 21.07.19 08:55 Сейчас в теме
И еще просьба уточнить: если один пользователь подключился к базе на одной платформе, а другому пользователю потребовалось подключился к другой базе на другой платформе, то его подключение невозможно не прервав подключение подключения первого пользователя?
Для отправки сообщения требуется регистрация/авторизация