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

13.10.15

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

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

Скачать файл

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

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

В последнее время 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 Конфигурации 1cv8 Россия Платные (руб)

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

10000 руб.

10.11.2023    7406    27    4    

51

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

14400 руб.

06.12.2023    5722    24    1    

55

SALE! %

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

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

3600 2880 руб.

14.01.2013    182215    1105    0    

876

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

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

14400 руб.

29.04.2020    30152    88    151    

63

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

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

3600 руб.

06.02.2017    31581    32    18    

48

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

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

6000 руб.

06.11.2012    71370    623    45    

83

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

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

1500 руб.

01.12.2020    15207    38    0    

55

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

Обработка для простого и удобного анализа настроек, нагрузки и проблем с SQL сервером с упором на использование оного для 1С. Анализ текущих запросов на sql, ожиданий, конвертация запроса в 1С и рекомендации, где может тормозить.

2 стартмани

15.02.2024    10325    208    ZAOSTG    74    

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