Решаем проблему с разными версиями платформ при 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С:Предприятие 8 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 Россия Платные (руб)

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

24900 руб.

20.08.2024    52251    292    145    

264

SALE! %

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

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

17000 16000 руб.

10.11.2023    21511    84    42    

96

Инструменты администратора БД Роли и права Системный администратор Программист Пользователь 1С 8.3 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    19186    70    10    

103

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

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

14400 руб.

29.04.2020    41075    123    152    

84

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

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

12000 руб.

06.02.2017    34573    148    18    

53

Архивирование (backup) Инструменты администратора БД 1С:Предприятие 8 1C:Бухгалтерия 1С:Розница 2 1С:Управление нашей фирмой 1.6 1С:Управление торговлей 11 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Платные (руб)

Данная разработка позволит решить вопрос с резервным копированием Ваших баз в автоматическом режиме, расположенных на сервере 1С. Система умеет ставить блокировки на вход, блокировать фоновые задания, принудительно отключать сеансы пользователей. И все это система делает в автоматически при создании бэкапа (или через команду). Выгрузка происходит в родной формат 1С - .dt. Так же система умеет архивировать данные выгрузки с установкой пароля. Умеет менять расширение файла zip или dt на любое указанное вами, что позволит сохранить выгрузки от шифровальщика. Может удалять старые копии выгрузок, оставляя указанное количество резервных копий, начиная с самой поздней. Только для WINDOWS!

6000 руб.

06.11.2012    77220    633    45    

92
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. Yashazz 4890 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 7327 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 7327 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 Сейчас в теме
И еще просьба уточнить: если один пользователь подключился к базе на одной платформе, а другому пользователю потребовалось подключился к другой базе на другой платформе, то его подключение невозможно не прервав подключение подключения первого пользователя?
Для отправки сообщения требуется регистрация/авторизация