askharlov
29.07.14
✎
00:56
Доброго времени суток всем!
Проблемка: не загружается внешняя компонента в УФ.
В обычных формах отрабатывает, в УФ не работает ни &НаКлиенте, ни &НаСервере. Вот код:
Попытка
ЗагрузитьВнешнююКомпоненту(«C:\Program Files (x86)\1cv82\8.2.18.61\bin\rs232.dll»);
Исключение
Сообщить(ОписаниеОшибки());
Возврат Ложь;
КонецПопытки;
На УФ выдает ошибку «{Форма.Форма.Форма(22)}: Ошибка при вызове метода контекста (ЗагрузитьВнешнююКомпоненту): Ошибка при загрузке внешней компоненты»
Книгу знаний http://kb.mista.ru/article.php?id=419 прочитал. Не помогло.
Компоненту успешно зарегистрировал (хоть на обычных формах это не требовалось), наличие веток в реестре проверил.
В чем еще может быть проблема?
Пока писал возникла мысль: а может сама компонента работать только с обычными формами и не работать с управляемыми? Эта компонента работает с COM-портом.
askharlov
29.07.14
✎
00:56
+(1) Загружал 1С под админом
jsmith
29.07.14
✎
01:18
я делаю так
Макет=ОбщийМодульМакет.ЗаписатьМакетНаДиск();
ИмяФайла=КаталогВременныхФайлов()+»Hook1c.dll»;
Макет.Записать(ИмяФайла);
Результат = ПодключитьВнешнююКомпоненту(ИмяФайла, «Hook», ТипВнешнейКомпоненты.Native);
jsmith
29.07.14
✎
01:21
ну и далее
&НаКлиенте
Процедура ПриОткрытии(Отказ)
КомпонентаKeyBoardHook = Новый(«AddIn.Hook.KeyboardHook»);
КонецПроцедуры
&НаКлиенте
Процедура ПриЗакрытии()
КомпонентаKeyBoardHook = Неопределено;
КонецПроцедуры
jsmith
29.07.14
✎
01:23
и это ещё
&НаСервере
Функция ЗаписатьМакетНаДиск() Экспорт
Макет = ПолучитьОбщийМакет(«Hook1c»);
Возврат Макет;
КонецФункции
jsmith
29.07.14
✎
01:24
мда, явно требуется рефакторинг
хорошо, что напомнили
askharlov
29.07.14
✎
15:00
(2) Спасибо. А какой код в процедуре Макет=ОбщийМодульМакет.ЗаписатьМакетНаДиск() ?
У меня самописка и этого модуля нет, в тех парочке конфигураций на УФ, которые мне доступны этого модуля тоже нет.
Скинь мне, пож-та, листинг кода.
askharlov
29.07.14
✎
15:08
+ (0) В продолжении темы:
Нашел в Интернете код:
Попытка
УстановитьВнешнююКомпоненту(«C:\Program Files (x86)\1cv82\8.2.18.61\bin\rs232.zip»);
//ПодключитьВнешнююКомпоненту(КаталогПрограммы() + «rs232.zip», «rs232», ТипВнешнейКомпоненты.Native);
Исключение
Сообщить(«Не удалось загрузить внешнюю компоненту!»);
Возврат Ложь;
КонецПопытки;
Исключения не возникает, но УстановитьВнешнююКомпоненту выдает ошибку: «Установка внешней компоненты не выполнена! В процессе установки произошла ошибка!»
Строку ПодключитьВнешнююКомпоненту пока закомментировал, так как ошибка возникает на предыдущей строчке.
askharlov
29.07.14
✎
15:23
+(0) Пробую подключить внешнюю компоненту на сервере без установки:
&НаСервере
Функция ОткрытьПорт()
Попытка
ПодключитьВнешнююКомпоненту(КаталогПрограммы() + «rs232.dll», «rs232», ТипВнешнейКомпоненты.Native);
Исключение
Сообщить(«Не удалось загрузить внешнюю компоненту!»);
Возврат Ложь;
КонецПопытки;
Попытка
КОМПорт = Новый(«Addin.rs232»);
КОМПорт.ОткрытьПорт(Порт.Наименование);
Возврат Истина;
Исключение
Сообщить(«Не удалось открыть порт » + Порт);
Возврат Ложь;
КонецПопытки;
КонецФункции
Получаю ошибку уже на строку Новый(«Addin.rs232»):
«Тип не определен (Addin.rs232)»
Добрый день. На текущий момент такая ошибка при использовании метода в 1с При попытке зарегистрировать компоненту с помощь. regsvr32 выходит ошибка, 3 года 4 месяца назад
#ссылка |
0 ответов
Добавить ответ
Для добавления сообщений на форуме вам необходимо зарегистрироваться и указать мобильный телефон в своем профиле (зачем?)
ЗАДАН
3 года 4 месяца назад
По каждому вопросу/ответу можно добавлять комментарии. Комментарии предназначены для уточнения вопроса/ответа.
Юрий Заглянувший Сообщений: 113 |
Альфа-Авто:Автосалон+Автосервис+Автозапчасти Проф, редакция 5 Имеется терминальный сервер S1 которому подключены с помощью удрабстола пользователи домена A и B. Пользователь домена A не испытывает никаких проблем при запуске Альфа-Авто. У пользователя домена B при запуске возникает ошибка «Ошибка при загрузке компоненты управления оборудованием: {Обработка.Защита.МодульОбъекта(24)}: Ошибка при вызове метода контекста (ЗагрузитьВнешнююКомпоненту): ошибка при загрузке внешней компоненты». Система защиты конфигурации Альфа-Авто установлена на этом же сервере S1. Права пользователей домена одинаковые (пользователь B создан копированием пользователя А в оснастке AD), доступ к папке C:\ProgramData\Protect\LocalProtect имеется для всех пользователей домена. Пользователь B не может зайти в Альфа-Авто ни под одним пользователем Альфа-Авто, в том числе под Администратором Альфа-Авто. Также не помогает временное предоставление пользователю домена B прав администратора домена. Прошу помочь в решении проблемы |
При первом запуске программы необходимо зарегистрировать компоненту RarusEquipment.dll. Можно зарегистрировать разными способами. Прикрепленные файлы |
|
Юрий Заглянувший Сообщений: 113 |
#3
07.03.2014 15:16:24
Это не первый запуск. Причины, видимо, глубоко уходят в область системного администрирования. Рецептов решения крайне мало и все они не помогают. Поэтому считаю важным предложить практически работающий способ. Прикрепляю 2 файла, содержимое которых также цитирую. Внести в реестр пользователя. —————— [HKEY_CURRENT_USER\Software\Classes\AddIn.RarusEquipment] [HKEY_CURRENT_USER\Software\Classes\AddIn.RarusEquipment\Clsid] —————— [HKEY_CURRENT_USER\Software\Classes\Wow6432Node\CLSID\{1E4BE968-CBCE-451F-876C-0A9E28CC795E}] [HKEY_CURRENT_USER\Software\Classes\Wow6432Node\CLSID\{1E4BE968-CBCE-451F-876C-0A9E28CC795E}\InprocServer32] [HKEY_CURRENT_USER\Software\Classes\Wow6432Node\CLSID\{1E4BE968-CBCE-451F-876C-0A9E28CC795E}\ProgID] Прикрепленные файлы
|
||
Добрый день!! Не помогает ни один из вариантов. У меня тоже самое, за исключением МодульОбъекта(25) и пользователи заходят, но без оборудования. Виндовс 8.1, платформа 8.3.5.1460, конфигурация Альфа-Авто: Автосалон+Автосервис+Автозапчасти ПРОФ, редакция 5.1 (5.1.01.05). При этом при попытке перерегистрации компоненты через regsvr32 конфигурация вообще отказывается работать, пишет конфигурация оборудования не найдена 1% и бесконечный поиск — после перерегистрации помогает только переустановка платформы. Пробовал на более свежей платформе, но там еще докучи и ошибка потока при заходе в базу нескольких пользователей. Обновлять конфигурацию пока побаиваюсь, понимаю, что дело тут совсем не в платформе и не в конфигурации, а в самом виндовсе, но никак проблему решить не могу. Причем есть в локальной сети один компьютер у которого все работает без ошибок с той-же самой операционной системой, но вот в чем разница непонятно. Изменено: Роман Конопелько — 08.06.2015 17:33:40 |
|
Добрый день, Роман, уточните, пожалуйста, из какого релиза Вы ставили систему управления оборудованием? |
|
Добрый день!! вот из этого 5.1.01.05. |
|
Уточните, пожалуйста, какую компоненту и как Вы регистрировали? |
|
Есть возможная причина всего этого. При установке виндовс в обязательном порядке была зарегестрирована учетная запись майкрософт под именем Техресурс. В дальнейшем учетную запись отключили (до установки 1С) и подключили локальную учетную запись USER. В итоге была проблема с доступом к базе по локальной сети, так как есть какая-то неразбериха с путями. Папка пользователя осталась называться как учетная запись майкрософт, то есть выглядит \users\Техресурс\Documents , а 1С искала базу по пути \users\user\documents\ — пришлось пути до базы прописывать на локальных компьютерах вручную. Возможно в этом вся проблема, но папку техресурс сейчас переименовать в user невозможно. Сам виндовс проверяли на целостность ситемы, все в норме. Изменено: Роман Конопелько — 09.06.2015 11:27:05 |
|
Регистрировали вот эту компоненту RarusEquipment.dll При всем при этом, на компьютере где все работает, дополнительную перерегистрацию компоненты делать не потребовалось, все установилось по умолчанию, но установка виндовс там была несколько другой, там виндовс встал без учетки майкрософт, сразу на локального пользователя (установка виндовс была не чистая, а было обновление с ХР до 8.0 и далее до 8.1) и соответственно на этом компьютере все пути так сказать прямые, пользователь user и все личные папки тоже под этим же именем. Изменено: Роман Конопелько — 09.06.2015 11:39:36 |
|
#10
09.06.2015 15:57:45 Роман, необходимо к Вам удаленно подключиться для решения ситуации на месте. Вышлите, пожалуйста, на alfa@rarus.ru контактные данные и удобное для Вас время подключения со ссылкой на данную ветку форума. |
|
Роман Конопелько Заглянувший Сообщений: 26 |
#11
09.06.2015 18:07:41
На данный момент решаю с майкрософт проблему переименования папки профиля пользователя, точнее уже решил (там администрирование+правка реестра). Сейчас выполню переустановку 1С проверю работоспособность, отпишусь. |
||
#12
09.06.2015 18:27:28 Переименование папки профиля не помогает, та же ошибка. А с alfa@rarus.ru мне не ответят, сейчас поддержка только на обновление. Один маленький вопрос, если я удалю сервер лицензирования (этого я ни разу не делал еще), то лицензия слетит ??? А то последний резервный пин уже использован. |
|
#13
09.06.2015 19:42:56 В итоге справился своими силами. Не знаю что уж там у меня было не так, но технология с плясками такая получилась : 1.Из папки C:\ProgramData\Protect\LocalProtect удаляем файл config.xml . Изменено: Роман Конопелько — 09.06.2015 19:45:28 |
|
#14
10.06.2015 10:27:19 Добрый день!! Что-то все рано не так работает. На компьютере 2 базы. В одну базу входит нормально, в другую с отключенным оборудованием из под администратора, если без администратора вообще не может найти сервер лицензирования. |
|
#15
10.06.2015 10:43:49 Роман, сервер лицензирования ищет в автоматическом поиске? Если да, поставьте указание сервера лицензирования вручную. |
|
Роман Конопелько Заглянувший Сообщений: 26 |
#16
10.06.2015 11:32:07
В том и дело, автоматически ищют локальные компьютеры, сейчас там все нормально. Лагает компьютер сервер. |
||
#17
10.06.2015 11:35:09 Попробую проделать все тоже самое что у же делал, но запущу все базы первый запуск от имени администратора и удалю ветки реестра с предложения выше от Юрия. |
|
#18
10.06.2015 11:41:31 Еще заметил, что все программы установщики от рарус попадают в касперский с ограничениями, абсолютно все, от фалов автозапуска до установки сервера лицензирования. |
|
Светлана Сулименко Посетитель Сообщений: 9055 |
#19
10.06.2015 11:50:28
Необходимо вносить их в исключения в антивирусе. |
||
#20
10.06.2015 16:20:54 Разобрался со второй базой, оказывается в самой 1С в оборудовании стоял путь старый от виндовс XP до папки LocalProtect . Поменял пути и все нормально |
|
Максим Козлов Заглянувший Сообщений: 7 |
#21
07.11.2016 18:00:19 Здравствуйте. Столкнулся с аналогичной ошибкой при запуске программы. Продукт приобрел и установил недавно. Компоненту регистрировал, как описывала Светлана Рожок в текстовом документе. Изменений никаких. Подскажите, что делать? |
#22
07.11.2016 18:18:38 Добрый день, Максим, уточните, пожалуйста, скрин ошибки, которая выдается. |
|
Максим Козлов Заглянувший Сообщений: 7 |
#23
07.11.2016 18:32:42 Да, конечно. Прикрепленные файлы |
#24
08.11.2016 09:09:58 Максим, уточните. пожалуйста, что конкретно Вы делали по установке компоненты оборудования? |
|
Максим Козлов Заглянувший Сообщений: 7 |
#25
08.11.2016 09:30:45
Выполнил установку драйверов с диска Альфы. После прочтения данной темы попытался зарегистрировать компоненту, как описано в текстовом файле выше. Больше ничего. |
||
Возникла тут идея поздравить нашего главного бухгалтера более-менее оригинально, например, с помощью ее любимой программы 1С? Но как?
После некоторых размышлений, пришла мысль использовать для поздравлений фоновое изображение в клиентской области обычных форм для конфигураций на 1С77–1С82 либо во внешнем окне для управляемых форм 1С82 и во всех случаях для 1С83. На нем вывести нужное сообщение и дать ссылки на поздравительное видео, как показано на рисунке.
Часть первая — результирующая
Очевидно, что данная идея не нова. Так, в 2011 году предлагалось похожее решение на базе FormEx.dll, Алексея Фёдорова aka АЛьФ. А вопросы как этого достичь задавались еще в далеком 2008 году.
В свое время, мы тоже использовали данную компоненту для загрузки фонового рисунка в 1С77. Но загрузка больших bmp-файлов (а другие нельзя было использовать) происходила медленно (из-за этого применялись маленькие картинки, уложенные черепицей), поэтому возникло желание написать собственную внешнюю компоненту (ВК), которая будет только загружать нужные изображения и ничего больше, разве что еще быть некоторым полигоном для экспериментов.
Такая компонента была написана (тоже, только для bmp-файлов, с использованием, при необходимости, укладки «черепицей»). Там применялась функция WinAPI LoadImage(). Эта dll-ка не конфликтовала с FormEx.dll, была простой, достаточно шустрой и служила долго.
Все это было замечательно, но настало время для расширения ее возможностей, а здесь нужен был уже другой подход.
В данной статье, мы не касаемся вопросов создания мультимедийных файлов. Это не наша специализация. Ограничимся только некоторыми нюансами программирования внешних компонент для 1С.
1C77
Поскольку версии платформы 1С могут быть разные, то и вариантов решений может быть несколько. В нашем случае это были конфигурации на 1С77 (рис. 1).
Рис. 1. Поздравительное изображение в тестовой конфигурации на 1С77.
Видео здесь хоть и собственное, но идея его создания почерпнута у Анны Шияновой, под ником «Особый случай». У этой девчонки есть талант, ей можно подражать, но полностью повторить стиль вряд ли получится. В данном случае просто хотелось хоть какого-то элемента творчества.
Если кому-то из коллег уже надоест смотреть на чужие поздравления, то они могут перегрузить картинку по «Alt+I» (рис. 2-3).
Рис. 2. Выбор другого фонового изображения в меню «Файл / Выбрать фон» либо по «Alt+I».
А заодно посмотреть информацию о используемом модуле по «Alt+L» (рис. 3).
Рис. 3. Перегруженное фоновое изображение вместе с информацией о программе («Помощь / О модуле LionExt32.dll» либо «Alt+L»).
1C82, обычные формы
Естественно, что большинство сейчас ориентированы на «восьмерку» (1С8х). Однако работать с фоновым изображением в 1С можно только на обычных формах в версии 8.2 и меньше и то, если не используются какие-либо обработки, запускаемые в режиме «рабочего стола», которые будут просто полностью перекрывать наш фон (рис. 4).
Рис. 4. Поздравительное изображение в тестовой конфигурации на обычных формах 1С82.
Заметим, что ссылки на рис. 4 указывают не на наше видео. Они показаны просто для теста.
В обычных формах 1С82 уже не получается стандартным способом получить доступ к меню, поскольку оно там не системное, как в «семерке», а «собственное» (хотя системное можно создать, но зачем нам два главных меню?). Однако горячие клавиши можно использовать. По тому же «Alt+I» мы в своей компоненте вызываем диалог, как на рис.2 и загружаем другой фон (рис. 5).
Рис. 5. Перегруженное фоновое изображение в «толстых» формах 1С82.
Аналогично можно получить информацию о модуле по клавише «Alt+L», как на рис. 3.
1C82, управляемые формы
Для управляемых форм в 1С82 еще можно отыскать на седьмом уровне вложенности нужное нам окно, типа «V8FormElement» и рисовать на нем, но как-то не интересно.
Для нас из этих рассуждений следует то, что проще создать внешнее окно с поздравительным сообщением (рис. 6), чем обрабатывать каждый отдельный случай. Само окно можно будет закрывать, точнее, сворачивать по «Esc», «Ctrl+F4», «Alt+F4» либо нажатием мышкой на «крестик».
Рис. 6. Поздравительное изображение в тестовой конфигурации на управляемых формах 1С82.
Причем свернутое окно (рис. 7), можно развернуть снова.
Рис. 7. Свернутое изображение внешнего окна на управляемых формах 1С82.
Размеры и относительное расположение внешнего окна можно менять, здесь все как обычно (см. увеличенные изображения внешних окон на рис. 6 и рис. 10). Отметим, что горячие клавиши действуют только, если внешнее окно активно.
1C83, обычные формы
В 1С83 дочерних окон уже нет вообще, что может служить критерием версии 1С в нашей dll. Причем, «толстые» формы являются фреймовым окном (рис. 8), а управляемые формы – безфреймовом (рис. 9). Т.е., всё, что не фрейм может быть перерисовано. Фрейм тоже может быть перерисован, но только как системный элемент.
Здесь мы с помощью динамической библиотеки создали тестовое окно и подчинили его главному окну 1С. Различие в поведении видно на рисунках.
1C83, управляемые формы
В случае 1С83, как и в управляемых формах 1С82 мы будем рисовать свои поздравления не на фоне, а в отдельном окне, прототип которого указан на рис. 8-9. В итоге нужная компонента (LionExt32.dll либо LionExt64.dll) даст следующий результат (рис. 10-12).
Рис. 10. Фоновое изображение во внешнем окне для обычных форм 1С83.
Рис. 11. Фоновое изображение во внешнем окне управляемых форм 1С83, релиз 14, 64-х разрядный вариант.
Рис. 12. Фоновое изображение во внешнем окне управляемых форм 1С83, релиз 15, 64-х разрядный вариант.
Предварительные выводы
Данная компонента была реально использована на практике (рис. 1), главный бухгалтер осталась довольна, все прошло чудесно. Попутно выяснилось, что пользователям нравиться выбирать собственные фоновые картинки, в данном случае, для работы на «семерке». Для «восьмерки» наша компонента адаптирована с заделом на будущее, пока ее стоит рассматривать как демо-вариант.
Интерес здесь состоял в том, что данная компонента совершенно не требовала соблюдения технологии создания внешних компонент от фирмы «1С». Может быть, возникнут дополнительные идеи по расширению ее возможностей. Например, для конфигураций, находящихся на полной поддержке, вносить изменения в код 1С без особой необходимости не хочется. В этом случае можно было бы предложить вариант внешней загрузки произвольной dll в адресное пространство 1С. Но это уже тема другой статьи.
Из технических новаций была использована блокировка по выгрузке нашей компоненты платформой 1С (поскольку она не соблюдает формат ВК). Кроме того, другой трюк позволил назначить дочернему окну локальное меню, так как операционная система Windows блокирует создание подобного меню у подчиненных окон. Поэтому вы нигде не увидите местных меню в том же MDI (Multi Document Interface). Заменой ему служат командные панели, тулбары и контекстное меню. Есть еще момент по обновлению окон. Иногда бывает, то ни UpdateWindow(), ни InvalidateRect() не срабатывают должным образом. А вот пара функций в этом случае оказывается успешной:
ShowWindow(hWnd, SW_HIDE);
ShowWindow(hWnd, SW_SHOW);
Еще нужно отметить, что наша компонента может конфликтовать с другими, например, с FormEx.dll для 1С77. В этом случае нужно, чтобы она загружалась последней.
Кстати, замечено, что если создавать конфигурацию в версии 1С-8.3.14 и выше, то компонента не загружается никаким штатным способом. Но если база создана в более ранней версии 1С, а открывается в последних версиях, то тогда проблем с загрузкой нашей ВК нет. Это еще раз намекает на необходимость создания внешнего загрузчика.
В данном проекте использована подсистема WinAPI GDI+. С ее помощью можно отображать картинки различных форматов: bmp, jpg, gif, png, tif и других. В этом же порядке компонента пытается загружать первый доступный файл Main.* из локального каталога Pics в текущей конфигурации. Если ни один из данных файлов не найден, то используется простой фоновый рисунок из ресурсов компоненты. На рис. 13 показан этот фоновый рисунок для обычных форм 64-х разрядной 1С83, релиз 15. Для разнообразия внешнее окно слега увеличено и на его фон добавлено еще одно изображение из файла Main1.png, уложенное «черепицей».
Рис. 13. Фоновый рисунок по умолчанию для обычных форм 64-х разрядной 1С83, релиз 15. Дополнительно добавлено еще одно изображение из файла Main1.png, уложенное «черепицей».
Разницы работы компоненты в режимах разной разрядности не наблюдается.
Также можно отметить, то наша компонента осуществляет сабклассинг главного окна 1С и его MDI-клиента, если он имеется. Именно это, по-видимому, служит источником конфликта с FormEx.dll, когда он загружен последним (в 1С77).
Часть вторая — техническая
Непосредственно с самим проектом можно ознакомиться по следующим ссылкам:
- Тестовая конфигурация на 1С77
- Тестовая конфигурация на 1С82
- Тестовая конфигурация на 1С83
- Проект на MS VS C++, v. 13
Проект на С++ может быть легко адаптирован под 10-ю версию, если в файлах конфигурации заменить строку «v120» на «v100» и «ToolsVersion=«12.0»» на «ToolsVersion=«4.0»».
Код для 32-х разрядной и 64-х разрядной версий 1С один и тот же и компилироваться могут одновременно.
Версия 1С77 определяется во внешней компоненте по ненулевому хэндлу фнукции GetMenu(), а версия 1С83, по отсутствию дочерних окон у главного окна, хэндл которого определяется функцией GetForegroundWindow().
О технологии создания внешних компонент для 1С
На дисках ИТС фирмы «1С», и в Интернете, можно без труда найти информацию о создании ВК и соответствующие шаблоны на разных языках программирования. Однако во времена 1С77 эти шаблоны удовлетворяли «не только лишь всех».
Если посмотреть на некоторые широко используемые компоненты, особенно для 1С77, то увидим, что их авторы нередко применяли особые методы программирования ради расширения возможностей своих разработок.
Возможно одной из первых такой внешней компонентой была «RAINBOW ADDIN 2000 для 1С: Предприятие 7.7». Пожалуй, самым важным здесь было более глубокое проникновение в недра «семерки», чем позволяла официальная технология ВК, хотя формат ВК она соблюдала. Это достигалось за счет полученных, вполне возможно нестандартными методами, хидеров (*.h-файлов) библиотечных файлов 1С77, используемых и в других широко известных проектах.
Действительно, если такие функции 1С как ЗагрузитьВнешнююКомпоненту() и ПодключитьВнешнююКомпоненту() позволяют внедрить в собственное адресное пространство внешние dll (прежде всего, удовлетворяющих формату технологии ВК), то почему бы пользовательским программам не поддаться искушению и не попытаться получить доступ к другим, скрытым от них, процедурам и прочим объектам целевой платформы? Вот этот подход как раз успешно продемонстрировал компонент Rainbow.dll.
Позже подобный механизм взяли на вооружение другие авторы компонент 1С версии 7.7. Особо следует выделить компоненту для «семерки» 1C++.dll и ее как бы частный случай FormEx.dll.
Но на этом нетривиальность подхода к проектированию внешних компонент для 1С77 не закончилась. По-видимому, кто-то должен был сказать: «Зачем нам кузнец? Кузнец нам не нужен!». Здесь под «кузнецом» мы понимаем технологию COM от MicroSoft, которой, в некотором смысле, следовала технология ВК для «семерки». Нет, ну, правда, зачем нам реестр, если мы загружаем нашу ВК непосредственно? Это может иметь смысл для веб-браузеров, работающих с Интернетом, но для локальной работы использование реестра явно избыточно. По крайней мере, это не должно быть обязательным условием. Тем более что для редактирования реестра нужны административные права.
Заметим, что фирма «1С» эту технологию очень любила (по крайней мере, до портирования 1С на Линукс). Мы же относимся к ней достаточно прохладно. COM удобна для использования ActiveX компонент и это естественно, поскольку последние разрабатывались изначально для Интернета.
Однако в последних версиях фирма «1С» добавила возможность применения технологии Native API, которая позволяет обходиться без использования реестра. В принципе, это то, что нам нужно, за исключением того, что эта технология не применима в «семерке», а она, для некоторых, все еще актуальна.
Но иногда возникают относительно простые задачи, когда не хочется использовать кучу шаблонного кода ВК и желательно работать с 1С со стороны внешней компоненты только. Как, скажем, в нашем случае демонстрации поздравительного изображения в клиентской области или, при необходимости, в отдельном окне, конфигурации 1С.
Другими словами, если мы не собираемся непосредственно обмениваться данными между 1С и ВК, то нас вполне устроит более простой и универсальный вариант внешней компоненты для 1С. Простота здесь будет достигаться за счет отсутствия шаблонного кода.
Альтернативные технология создания ВК для 1С
Поскольку ВК для 1С это частный случай COM-сервера (до появления технологии Native API), то, нашлись разработчики ВК, которые сказали: «COM’у – нет!». Особенно заметна деятельность в этом направлении Александра Орефкова. Его компоненты «1sqlite.dll», «TurboMD.dll» и возможно другие, не используют COM от слова «совсем». Также по этому пути развивается компонента Йоксель («SpreadSheet.dll»).
Но как же тогда загрузчик ВК от 1С77 загружает эти компоненты? Ведь они даже не пытаются имитировать какой-то там COM. И действительно, если мы попытаемся тупо подсунуть в функцию ЗагрузитьВнешнююКомпоненту() какую-нибудь стандартную dll, сгенерированную скажем мастером MS VC++, то нас ждет облом.
В «семерке» мы получим сообщение, типа:
Ошибка при создании объекта из компоненты <ПолныйПутьИмяКомпоненты>.dll (отсутствует CLSID)
В «толстом» 32-х разрядном клиенте «восьмерки» сообщение будет аналогичное. Та же dll-ка вызовет похожую ругань (рис. 15):
Ошибка при вызове метода контекста (ЗагрузитьВнешнююКомпоненту): Ошибка при загрузке внешней компоненты
Так все-таки, как упомянутые библиотеки решают эту проблему? Изучая тексты программ Орефкова и Йокселя мы, в конечном счете, приходим к выводу, что «виноваты» следующие «волшебные строчки» в файле ресурсов (*.rc либо *.rc2):
STRINGTABLE DISCARDABLE
BEGIN
100 "sd" // 1sqlite.dll
100 "tmd" // TurboMD.dll
100 "f" // SpreadSheet.dll
END
Т.е. в обязательном порядке в ресурсах программы присутствует строка с идентификатором 100 и некоторым строковым значением, первый символ которого нулевой. Вы можете экспериментировать с вариантами подобных строк, а меня вполне устраивает строка «L«. Таким образом, создаем файл ресурсов и пишем туда строчки вида:
STRINGTABLE DISCARDABLE
BEGIN
100 "L" // Без подобной строки 1С не загрузит нормально внешнюю компоненту!
END
Подключаем этот файл к нашему простейшему dll-проекту, сгенерированному мастером MS C++, добавляем код:
BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved) {
switch(dwReason) {
case DLL_PROCESS_ATTACH:
MessageBox(NULL, "Привет, из DllMain()!", "Информация", MB_OK);
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
} // switch(dwReason)
return TRUE;
} // DllMain()
и наблюдаем (рис. 14).
Рис. 14. Использование простейшей «ВК» в 1С82.
Без «волшебных строчек» в файле ресурсов, наша dll, после показа MessageBox’a, сразу же выгрузиться с руганью, со стороны 1С (рис. 15).
Рис. 15. Ошибка загрузки обычной dll в 1С82.
Т.е., эти строки действительно оказывают магическое воздействие на загрузчик внешних компонент 1С.
Первым, похоже, «волшебные строки» описал в своей старой статье Алексей Фёдоров (АЛьФ), но ссылка на нее уже недоступна, а автор не видит смысла в ее переопубликации. Причем, наиболее интенсивно их использовал Александр Орефков, и судя по всему, с его подачи, автор Йокселя. Поэтому мы будем говорить о «волшебных» строках Фёдорова-Орефкова. Смысл их в том, чтобы заблокировать выгрузку нестандартных (с точки зрения 1С) dll-файлов функцией ЗагрузитьВнешнююКомпоненту(). Причем, как мы видим, этот прием работает не только в 1С77, но и в «толстых» формах 1С82.
Однако в управляемых формах 1С82 и во всех версиях 1С83 эта возможность уже полностью перерыта (также появился и другой загрузчик – ПодключитьВнешнююКомпоненту()).
Таким образом, в современных версиях 1С нужно искать уже другие простые альтернативы «волшебным» строкам Фёдорова-Орефкова.
И такую альтернативу легко предложить. Суть проста. Загрузчик 1С выгружает «неправильную» компоненту, если она вызывает исключение при попытке обратиться к ней по заданному протоколу, например, при запросе версии компоненты. У нас, естественно, ничего такого нет, что и служит основанием для выгрузки нестандартной dll. Но требование 1С к операционной системе выгрузить данную динамическую библиотеку может быть проигнорирована системой, если эта ВК все еще где-то используется. Вместо собственно удаления, система просто уменьшает счетчик использования искомого модуля. И удалит физически не ранее, чем этот счетчик обнулится. Поэтому наша задача искусственно увеличить этот счетчик.
Для этого можно в секции DLL_THREAD_ATTACH еще раз вызвать нашу dll функцией WinAPI LoadLibrary()
BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved) {
switch(dwReason) {
case DLL_PROCESS_ATTACH: {
WCHAR szDllName[_MAX_PATH] = {0};
// Получаем полный путь нашей dll
GetModuleFileName(hModule, szDllName, _MAX_PATH);
//MessageBox(NULL, szDllName, L"Info", MB_OK);
// Повторная загрузка текущей dll (чтобы блокировать ее выгрузку из 1С83),
// но без повторного выполнения секции DLL_PROCESS_ATTACH
HMODULE hDll = LoadLibrary(szDllName);
break;
} // case DLL_PROCESS_ATTACH
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
} // switch(dwReason)
return TRUE;
} // DllMain()
Всё! Проблема решена. Повторный вызов той же самой динамической библиотеки увеличит счетчик ее использования на единицу, а выгрузка (с предварительным заходом в секцию DLL_THREAD_DETACH) уменьшит на единицу. Итого имеем 2 – 1 = 1 > 0, следовательно, операционная система выгружать нашу dll не будет. Причем, что важно, повторной инициализации секции DLL_PROCESS_ATTACH происходить не будет.
Отсюда, кстати, видно, как фирма «1С» может бороться с подобным трюком в своих последних версиях (и, по-видимому, уже делает это, в конфигурациях, созданных в 1С-8.3.14 и выше). Она может использовать функцию LoadLibraryEx() с параметром, блокирующим выполнение секции инициализации DLL_PROCESS_ATTACH, после чего, сразу вызовет нужные экспортируемые функции. И, действительно, если посмотреть код примера ВК для Native API, то видно, что вызывать код инициализации нет никакой необходимости, так как по формату ВК он должен быть пустым.
Относительно примеров использования технологии COM, очевидно, что исполнение секции инициализации DLL_PROCESS_ATTACH, там необходимо, поэтому в не слишком новых версиях 1С, точнее, в конфигурациях, которые сделаны в 1С-8.3.13 и ниже, нам подойдет загрузчик 1С:
ПодключитьВнешнююКомпоненту(АдресКомпоненты, НаимКомпоненты, ТипВнешнейКомпоненты.COM);
Здесь последний параметр можно убрать, поскольку он подразумевается по умолчанию. При этом открываться они могут нормально в любой более высокой версии. В версиях 1С83 прежний загрузчик ЗагрузитьВнешнююКомпоненту(АдресКомпоненты) нам уже не подходит (соответственно и «волшебные строки» Фёдорова-Орефкова там не работают).
В общем случае, как уже упоминалось, проблему можно решить путем использования внешнего загрузчика. Либо, что вполне естественно, соблюдать в той или иной мере технологию внешних компонент фирмы «1С».
Следует также отметить, что эксперименты мы проводили в файловых версиях 1С разной разрядности. Чтобы загрузить нашу компоненту может потребоваться установить в конфигурации свойство «Режим использования синхронных вызовов» в значение «Использовать».
Также следует понимать, что применение подобной техники вы осуществляете на собственный страх и риск, экспериментируйте предварительно на тестовых конфигурациях либо копиях рабочих, чтобы избежать потенциальных проблем в основных программах.
Обновление от 11.09.2019
Выяснилось, что я зря переживал, что: «в версиях 1С-8.3.14 и выше, секция инициализация во внешней компоненте не выполняется уже от слова «совсем»».
Оказывается выполняется, только возвратное сообщение в функции ПодключитьВнешнююКомпоненту() не нужно обрабатывать. Причем независимо от того, какой тип компоненты мы укажем: COM или Native API.
Таким образом, создавать конфигурацию можно во всех доступных ныне версиях 1С, наша компонента должна работать везде нормально, а создание внешнего загрузчика будет актуально, разве, что только для случая, когда не хочется менять конфигурацию, находящейся на полной поддержке.
В связи с этим слегка изменен код в тестовых конфигурациях для 1С82 и 1С83, хотя различия между ними становятся уже не принципиальными.
При этом очевидно остается в силе наше замечание, что фирма «1С» может легко заблокировать выполнение кода инициализации в любой ВК, по крайней мере, для внешних компонент типа Native API, поскольку, судя по их шаблону, в этом нет никакой необходимости. Для ВК типа COM такая необходимость пока есть, но что мешает от нее избавиться? Заодно и посмотрим, примут ли «там» в расчет эту информацию?
Добрый день!
Проверьте в реестре, что никакие компоненты больше не зарегистрированы, при необходимости, разрегистрируйте их.
- Зайти в реестр (<Win+R> — «regedit»).
- Запустить поиск (Ctrl+F) по строке «AddIn.DiadocInvoiceApi» (Поиск пойдет от выделенной ветки. Таким образом Вы можете, например, пропустить поиск по ветке HKEY_CLASSES_ROOT).
- Ищете записи о компоненте в ветках реестра:
HKEY_CLASSES_ROOT\ — повторите поиск, нажав F3.
HKEY_LOCAL_MACHINE\ — это значит, что компонента была зарегистрирована под всех пользователей и скорее всего для регистрации потребуется запуск консоли от имени администратора.
HKEY_CURRENT_USER\ — это значит, что компонента зарегистрирована под текущего пользователя.
HKEY_USERS<SID>\ — это значит, что компонента зарегистрирована под пользователя с указанным SID. SID-ы других пользователей может смотреть только администратор. При работе от пользователя увидите только ветку с SID текущего пользователя. - Рядом с найденной веткой найдите ветку «AddIn.DiadocInvoiceApi.1\CLSID». Зайдите в неё и скопируйте значение из параметра по умолчанию.
- Запустите поиск по этому значению.
- В найденной ветке будет подветка «InprocServer32». В параметре «InprocServer32» по умолчанию будет указан путь до компоненты (именно по этому пути Windows ищет компоненту).
- Если автоматическая регистрация компоненты не срабатывает, тогда:
Если в реестре вы нашли другие зарегистрированные компоненты Диадок, то их необходимо разрегистрировать. В случаях, когда указанного в реестре каталога или файла не существует, их необходимо создать.
После того, как все компоненты будут разрегистрированы, удалите компоненты с диска ( Shift + Del ). После успешной разрегистрации компоненты веток с именем «AddIn.DiadocInvoiceApi» оставаться не должно.
После этого:
1 Закройте 1С
2. Запустите консоль от имени администратора и введите следующие команды:
2.1 C:\Windows\System32\regsvr32.exe /u «полный путь до компоненты»
2.2 C:\Windows\System32\regsvr32.exe /i «полный путь до компоненты»
2.3 C:\Windows\System32\regsvr32.exe /i:user «полный путь до компоненты»
2.4 C:\Windows\System32\regsvr32.exe /u «полный путь до компоненты»
2.5 C:\Windows\System32\regsvr32.exe /i:user «полный путь до компоненты»
3. Все действия в консоли обязательно проделать до конца.
4. После выполнения действий проверьте работу модуля.
Определения:
«полный путь до компоненты» — пример «C:\Users\permikin\AppData\Local\Temp\AddInDiadocAPI_5_28_6_502_x86_64.dll»
При разрегистрации может возникнуть ошибка с кодом «0x80070005» или «0х80004005» это значит, что консоль запущена без прав администратора, либо что по указанному пути нет компоненты.
Если возникнут трудности при проверке или регистрации компоненты, напишите об этом.