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

13.10.15

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

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

Скачать файлы

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

В последнее время 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С УТ 11, КА 2, ERP2, Розница 2/3, УНФ 16/3, БП 3, ЗУП 3 и подобных (УФ, Платформа 8.3.14+)

Инструменты администратора БД Роли и права 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, пытаясь понять какими правами они обладают? Вы все время смотрите права в конфигураторе или отчетах чтоб создать нормальные профили доступа? Вы хотите наглядно видеть какие права дает профиль и редактировать все в простом виде? А может хотите просто указать подсистему и дать права на просмотр и добавление на объекты и не лезть в дебри прав и чтоб обработка сама подобрала нужные роли? Все это теперь стало возможно! Обновление от 15.12.2023, версия 1.1.

12000 руб.

06.12.2023    2988    15    1    

34

SALE! 20%

Infostart УДиФ: Управление данными и формами

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

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

10000 8000 руб.

10.11.2023    3563    11    1    

34

SALE! 30%

PowerTools

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

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

3600 2520 руб.

14.01.2013    177769    1074    0    

849

Ускоренное проведение документов (x4), устранение ошибок 60/62 счетов и зачет авансов (Бухгалтерия 3.0)

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

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

14400 руб.

29.04.2020    27388    79    146    

59

Система хранения присоединенных файлов в томах на диске

Инструменты администратора БД Платформа 1С v8.3 1С:Комплексная автоматизация 1.х 1С:Управление производственным предприятием Платные (руб)

Конфигурация Комплексная автоматизация 1.1 (и УПП 1.3 тоже) хранит файлы и изображения в справочнике Хранилище дополнительной информации в реквизите Хранилище типа ХранилищеЗначений. Та же история с ВложениямиЭлектроннойПочты. Но при этом присоединенные файлы в Электронном документообороте хранит в томах на диске. Эта доработка позволяет использовать стандартный механизм хранения файлов, изображений и вложений электронных писем в томах на диске. При этом можно разделить тома хранения по объектам конфигурации.

4200 руб.

10.11.2015    61320    88    59    

73

"Менеджер потоков 2.1": УПП: "Восстановление партий"

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

Как оптимизировать то, что, считалось, не поддается оптимизации? Как повысить доступность базы данных? Как проводить самую «времяемкую» операцию не по паре раз в неделю, а по несколько раз в день*? Ответ есть!

20000 руб.

12.09.2019    11748    5    9    

7

Брандмауэр для сервера 1С Предприятие 8 - внешнее управление сеансами

Инструменты администратора БД Платформа 1С v8.3 Конфигурации 1cv8 Платные (руб)

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

3600 руб.

06.02.2017    31113    31    18    

47

Хранилище файлов на SQL

Инструменты администратора БД Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Управленческий учет Платные (руб)

Привязка файлов / сканов к объектам 1С с сохранением их на SQL-сервере

12000 руб.

09.10.2019    10987    5    8    

9
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. Yashazz 4709 31.08.15 22:19 Сейчас в теме
Ну естессно, теперь, после шикарной статьи от tormozit'а, легко клепать такие публикации, ага-ага.
3. Zhilyakovdr 142 31.08.15 23:04 Сейчас в теме
(1) Yashazz, Вы про эту статью Статья ???
2. Zhilyakovdr 142 31.08.15 23:00 Сейчас в теме
Хм... после какой статьи??? Этот код был написан пол года назад, руки не доходили статью набросать. Весь код написан с нуля!
4. tormozit 7138 01.09.15 08:35 Сейчас в теме
Объект MSScriptControl.ScriptControl к сожалению не доступен в 64-битном процессе. Поэтому приведенный код в случае отсутствия COM+ приложения без ошибок выполнится только
- на толстом клиенте
- на 32-битном сервере
- в файловой базе в любом контексте
5. Zhilyakovdr 142 01.09.15 09:10 Сейчас в теме
(4) tormozit, Хм.... почему же у меня работает на 64-битном сервере и на тонком клиенте??? Да и клиентские системы 64-битные....
Этот код выполняется клиентами на клиентских машинах (32 и 64), он для этого и писался чтобы не бегать по клиентам и не ставить вручную.
Только что специально смоделировал (Тонкий клиент 64 система сервер 64) все работает.
Если у вас падает с ошибкой то ошибку в студию попробуем разобраться.
6. tormozit 7138 01.09.15 09:23 Сейчас в теме
(5) Попробуйте выполнить код
Новый COMОбъект("MSScriptControl.ScriptControl")
на 64-битном сервере.
7. Zhilyakovdr 142 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 142 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 Сейчас в теме
И еще просьба уточнить: если один пользователь подключился к базе на одной платформе, а другому пользователю потребовалось подключился к другой базе на другой платформе, то его подключение невозможно не прервав подключение подключения первого пользователя?
Оставьте свое сообщение