RDT1C/DataProcessors/ирУправлениеCOMКлассами1С/Ext/ObjectModule.bsl
Администратор 6a2d8d07e4 4.09
Интерфейсная панель
        +Для ветки "Избранное" добавлена команда выгрузки ссылок в список значений
        +Для ссылок в ветке "Избранное" в представление добавлен их тип в скобках
        +Добавлена поддержка копирования ссылок из ветки "Избранное"
    Консоль запросов
        *Вставка ссылки на объект БД теперь вставляет имя параметра в текст запроса только если он имеет фокус ввода
        *Исправлена ошибка возможности установки параметру  строкового значения, не соответствующего квалификатору
    Консоль кода
        *Вставка ссылки на объект БД теперь вставляет имя параметра в скрипт только если он имеет фокус ввода
    Поиск дублей и замена ссылок
        +При добавления нового правила замены теперь устанавливается тип ссылки по выбранной в настройках поиска дублей таблице
    Подбор и обработка объектов
        +Обработка "Объединить ссылки на объекты" переименована в "Заменить ссылки на объекты" в связи с расширением функциональности
        +Обработка "Объединить ссылки" теперь предоставляет на выбор создание одной группы дублей для всех объектов или своего правила замены для каждого объекта
    Редактор пользователей
        +В форме запуска сеанса под пользователем добавлен флажок "отключить защиту от опасных действий на время запуска"
    Портативный вариант
        *При обновлении с сайта архив теперь помещается в каталог базового модуля
    Анализ техножурнала
        *Во встроенном варианте исправлена проблема сброса чужой схемы БД каждые 20 минут
        *Исправлен ряд ошибок в форме управляемой блокировки
    Редактор списка значений
        +Добавлена команда передачи в таблицу значений
    Управление COM классами
        +Реализована поддержка 64-разрядных классов Application и CApplication
4.10
    Конструктор запроса
        +Добавлен флажок "Иерархическая логика" (включен по умолчанию) обеспечивающий иерархический стиль сборки условий отбора и соединений
        +При выборе таблицы-параметра теперь автоматически вставляется запрос на создание временной таблицы и выбирается временная таблица вместо параметра
        *Исправлена ошибка загрузки запроса с выражением ЗНАЧЕНИЕ(XXX.YYY)
    Консоль запросов
        *Исправлена свежая проблема не вставки имени параметра в активное поле обработчика результата при вставке ссылки
    Общее
        +Для встроенного варианта реализована настройка "Каталог объектов для отладки" в общих настройках инструментов
        *Вывод табличного поля в табличный документ теперь корректно выводит колонку с данными флажка
        *Исправлен некорректный запуск команд системы на некоторых 64-разрядных ОС
    Портативный
        +При загрузке новой версии теперь сохраняется ее архив по аналогии со старой версией
    Табличный документ
        +Добавлена поддержка форматов "xls,xls,ods" при загрузке/выгрузке в файл
    Структура хранения БД
        +Добавлена кнопка вывода в табличный документ ИР
        *Исправлена ошибка нажатия на кнопку "Сравнить"
        *Исправлена ошибка активизации закладки "Общая таблица индексов"
    Исследователь объектов
        +Хранилище значений и двоичные данные теперь открываются в сопоставленных редакторах по двойному клику в ячейке Значение
    Подбор и обработка объектов
        *Флажок "Без автоупорядочивания" теперь устанавливается при изменении области поиска
    Редактор констант
        +Добавлены флажки "Отключить контроль записи" и "Запись на сервере"
2017-05-28 22:19:29 +03:00

330 lines
22 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//ирПортативный Перем ирПортативный Экспорт;
//ирПортативный Перем ирОбщий Экспорт;
//ирПортативный Перем ирСервер Экспорт;
//ирПортативный Перем ирКэш Экспорт;
//ирПортативный Перем ирПривилегированный Экспорт;
Функция ВыполнитьРегистрацию() Экспорт
//http://msdn.microsoft.com/en-us/library/windows/desktop/ms687653%28v=vs.85%29.aspx
// http://icodeguru.com/VC%26MFC/APracticalGuideUsingVisualCandATL/133.htm
// Коды ошибок http://msdn.microsoft.com/en-us/library/windows/desktop/dd542647%28v=vs.85%29.aspx
КаталогПриложений = Новый COMОбъект("COMAdmin.COMAdminCatalog");
КаталогПриложений.Connect(Компьютер);
Приложения = КаталогПриложений.GetCollection("Applications");
Приложения.Populate();
Для Каждого СтрокаТаблицы Из Классы Цикл
НовыйСборкаПлатформы = СтрокаТаблицы.НовыйСборкаПлатформы;
Если ЗначениеЗаполнено(НовыйСборкаПлатформы) Тогда
Если Не ирОбщий.ЭтоЛокальныйКомпьютерЛкс(Компьютер) Тогда
Сообщить("Изменение COM классов нелокальной машины не поддерживается");
Прервать;
Иначе
ЗарегистрироватьCOMКлассСборкиПлатформы(ТипыComКлассов.Найти(СтрокаТаблицы.ТипКласса, "Имя"), СтрокаТаблицы.x64, НовыйСборкаПлатформы);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Результат = Истина;
Возврат Результат;
КонецФункции
Процедура ЗарегистрироватьCOMКлассСборкиПлатформы(Знач ТипКласса, Знач x64 = Неопределено, Знач СборкаПлатформы = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
ТипКласса = ТипыComКлассов.Найти();
#КонецЕсли
Если x64 = Неопределено Тогда
x64 = ирКэш.Это64битныйПроцессЛкс();
КонецЕсли;
ОтборСтрок = Новый Структура("СборкаПлатформы", СборкаПлатформы);
ОтборСтрок.Вставить("x64", x64);
СтрокиТаблицы = СборкиПлатформы.НайтиСтроки(ОтборСтрок);
Если СтрокиТаблицы.Количество() > 0 Тогда
СтрокаТаблицыНовогоРелиза = СтрокиТаблицы[0];
ЗарегистрироватьCOMКлассИзКаталогаФайлов(ТипКласса, x64, СтрокаТаблицыНовогоРелиза.Каталог + "bin", СборкаПлатформы);
Иначе
ВызватьИсключение "Файл регистрации класса " + ТипКласса.Имя + " для сборки платформы " + СборкаПлатформы + " не найден";
КонецЕсли;
КонецПроцедуры
Функция ЗарегистрироватьCOMКлассИзКаталогаФайлов(ТипКласса, x64 = Неопределено, пКаталогФайла = Неопределено, СборкаПлатформы = Неопределено) Экспорт
Если Не ЗначениеЗаполнено(пКаталогФайла) Тогда
КаталогФайла = КаталогПрограммы();
СборкаПлатформы = ТекущаяСборкаПлатформы;
Иначе
КаталогФайла = пКаталогФайла;
КонецЕсли;
Если ТипКласса.Внутрипроцессный Тогда
Если x64 <> Неопределено И ирКэш.Это64битнаяОСЛкс() Тогда
Если x64 Тогда
Команда = "%systemroot%\System32\regsvr32.exe";
Иначе
Команда = "%systemroot%\SysWoW64\regsvr32.exe";
КонецЕсли;
Иначе
Команда = "regsvr32.exe";
КонецЕсли;
Если ТипКласса.Имя = "ComConnector" Тогда
ПолноеИмяФайла = КаталогФайла + "\" + ТипКласса.КлючевойФайл;
Команда = Команда + " """ + ПолноеИмяФайла + """ /s";
ИначеЕсли ТипКласса.Имя = "ServerAdminScope" Тогда
ПолноеИмяФайла = КаталогФайла + "\" + ТипКласса.КлючевойФайл;
Команда = Команда + " """ + ПолноеИмяФайла + """ /s /n /i:user";
Иначе
РезультатКоманды = "Неизвестный тип COM класса """ + ТипКласса.Имя + """ платформы 1С";
КонецЕсли;
Иначе
#Если Не Клиент Тогда
Если Не ЗначениеЗаполнено(пКаталогФайла) Тогда
ВызватьИсключение "Регистрация COM класса типа """ + ТипКласса.Имя + """ отменена, т.к. определение пути к исполняемому файлу клиентского приложения на сервере не реализовано.";
КонецЕсли;
#КонецЕсли
Если Не ЗначениеЗаполнено(РезультатКоманды) Тогда
ПолноеИмяФайла = КаталогФайла + "\" + ТипКласса.КлючевойФайл;
Команда = """" + ПолноеИмяФайла + """ /regserver";
КонецЕсли;
КонецЕсли;
Если ЗначениеЗаполнено(Команда) Тогда
Файл = Новый Файл(ПолноеИмяФайла);
Если Не Файл.Существует() Тогда
ВызватьИсключение "При регистрации COM класса типа """ + ТипКласса.Имя + """ не найден файл """ + Файл.ПолноеИмя + """
|Переустановите платформу с необходимой компонентой";
Иначе
РезультатКоманды = ирОбщий.ПолучитьТекстРезультатаКомандыОСЛкс(Команда,,, Истина); // Тут всегда пустой результат
КонецЕсли;
КонецЕсли;
#Если Сервер И Не Клиент Тогда
Текст = "серверном контексте";
#Иначе
Текст = "клиентском контексте";
#КонецЕсли
ПроцессОС = ирОбщий.ПолучитьПроцессОСЛкс("текущий");
//#Если Клиент Тогда
// Текст = Текст + " из процесса " + ПроцессОС.Name + "(" + XMLСтрока(ПроцессОС.ProcessID) + ")";
//#КонецЕсли
ТекстСообщения = "Выполнена локальная регистрация COM класса """ + ТипКласса.Имя + """ " + СборкаПлатформы + " в " + Текст;
Сообщить(ТекстСообщения);
//#Если Клиент Тогда
// Сообщить("! После регистрации для возможности использовать класс может потребоваться перезапуск процесса 1С !", СтатусСообщения.Внимание);
//#КонецЕсли
Возврат РезультатКоманды;
КонецФункции
Процедура ПроверитьСозданиеCOMОбъекта(СтрокаКласса)
//#Если _ Тогда
// СтрокаКласса = ЭтотОбъект.Классы.Добавить();
//#КонецЕсли
//Попытка
// РезультатСоздания = ирОбщий.СоздатьCOMОбъектИис(СтрокаКласса.ИмяКласса, Компьютер, Не СтрокаКласса.Внутрипроцессный);
//Исключение
// РезультатСоздания = Неопределено;
//КонецПопытки;
//Если РезультатСоздания <> Неопределено Тогда
// СтрокаКласса.Зарегистрирован = Истина;
// СтрокаКласса.ПроверкаСоздания = Истина;
//КонецЕсли;
КонецПроцедуры
Процедура ЗаполнитьКлассыИзКоллекции(Компоненты, x64)
Компоненты.Populate();
Для Каждого Компонента Из Компоненты Цикл
ИмяКласса = Компонента.Name;
Если Найти(НРег(ИмяКласса), "v8") = 1 Тогда
Для Каждого СтрокаТипаКласса Из ТипыComКлассов Цикл
Если Найти(НРег(ИмяКласса), НРег(СтрокаТипаКласса.ИмяКлассаПослеV8)) = 4 Тогда
ИдентификаторКомпоненты = Компонента.Value("CLSID");
НомерИзданияПлатформы = Число(Сред(ИмяКласса, 3, 1));
Если СтрокаТипаКласса.Внутрипроцессный Тогда
ПолноеИмяФайла = Компонента.Value("InprocServer32");
Иначе
ПолноеИмяФайла = Компонента.Value("LocalServer32");
КонецЕсли;
ИмяКласса = "V8" + НомерИзданияПлатформы + СтрокаТипаКласса.ИмяКлассаПослеV8;
СтрокиКлассов = Классы.НайтиСтроки(Новый Структура("ИмяКласса, x64", ИмяКласса, x64));
Если СтрокиКлассов.Количество() > 0 Тогда
СтрокаПриложения = СтрокиКлассов[0];
СтрокаПриложения.ИмяФайла = ПолноеИмяФайла;
СтрокаПриложения.ИдентификаторКласса = Компонента.Value("CLSID");
СтрокаПриложения.Зарегистрирован = Истина;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура ОбновитьТаблицуКлассов(ЗаполнятьТолькоВнешниеСоединения = Ложь) Экспорт
СистемнаяИнформация = Новый СистемнаяИнформация;
ЭтотОбъект.ТекущаяСборкаПлатформы = СистемнаяИнформация.ВерсияПриложения;
ЭтотОбъект.ПользовательОС = ирКэш.ТекущийПользовательОСЛкс();
ЭтотОбъект.x64Текущая = ирКэш.Это64битныйПроцессЛкс();
Классы.Очистить();
МассивРазрядностей = Новый Массив();
МассивРазрядностей.Добавить(Ложь);
Если ирКэш.Это64битнаяОСЛкс(Компьютер) Тогда
МассивРазрядностей.Добавить(Истина);
//Если ЗаполнятьТолькоВнешниеСоединения Тогда
// Если КэшКонтекстаИис.Это64битныйПроцессИис() Тогда
// МассивРазрядностей.Удалить(0);
// Иначе
// МассивРазрядностей.Удалить(1);
// КонецЕсли;
//КонецЕсли;
КонецЕсли;
ИзданияПлатформы = Новый СписокЗначений;
Для Счетчик = 1 По 4 Цикл
ИзданияПлатформы.Добавить("8" + Счетчик, "8." + Счетчик);
КонецЦикла;
Для Каждого ИзданиеПлатформы Из ИзданияПлатформы Цикл
Для Каждого ТипКласса Из ТипыComКлассов Цикл
Если Истина
И ЗаполнятьТолькоВнешниеСоединения
И ТипКласса.Имя <> "ComConnector"
Тогда
Продолжить;
КонецЕсли;
Для Каждого x64 Из МассивРазрядностей Цикл
Если Не ТипКласса.Внутрипроцессный И x64 И ИзданиеПлатформы.Значение < "83" Тогда
Продолжить;
КонецЕсли;
ИмяКласса = "V" + ИзданиеПлатформы.Значение + ТипКласса.ИмяКлассаПослеV8;
СтрокаКласса = Классы.Добавить();
СтрокаКласса.ИзданиеПлатформы = ИзданиеПлатформы.Представление;
СтрокаКласса.ИмяКласса = ИмяКласса;
СтрокаКласса.ВнутриПроцессный = ТипКласса.Внутрипроцессный;
СтрокаКласса.ТипКласса = ТипКласса.Имя;
СтрокаКласса.x64 = x64;
КонецЦикла;
КонецЦикла;
КонецЦикла;
КаталогПриложений = Новый COMОбъект("COMAdmin.COMAdminCatalog");
КаталогПриложений.Connect(Компьютер);
Если ирКэш.Это64битнаяОСЛкс(Компьютер) Тогда
Компоненты = КаталогПриложений.GetCollection("InprocServers");
ЗаполнитьКлассыИзКоллекции(Компоненты, Истина);
Компоненты = КаталогПриложений.GetCollection("WOWLegacyServers");
ЗаполнитьКлассыИзКоллекции(Компоненты, Ложь);
КонецЕсли;
Компоненты = КаталогПриложений.GetCollection("LegacyServers");
ЗаполнитьКлассыИзКоллекции(Компоненты, ирКэш.Это64битнаяОСЛкс(Компьютер));
Приложения = КаталогПриложений.GetCollection("Applications");
Приложения.Populate();
Для Каждого Приложение Из Приложения Цикл
Если Ложь
Или Приложение.Key = "{9EB3B62C-79A2-11D2-9891-00C04F79AF51}"
Или Приложение.Key = "{7B4E1F3C-A702-11D2-A336-00C04F7978E0}"
Или Приложение.Key = "{01885945-612C-4A53-A479-E97507453926}"
Или Приложение.Key = "{02D4B3F1-FD88-11D1-960D-00805FC79235}"
Тогда
Продолжить;
КонецЕсли;
СтрокаДоступногоПриложения = Неопределено;
Компоненты = Приложения.GetCollection("Components", Приложение.Key);
Попытка
Компоненты.Populate();
Исключение
Компоненты = Неопределено;
Сообщить("Ошибка получения компонент приложения """ + Приложение.Value("Name") + """: " + ОписаниеОшибки(), СтатусСообщения.Внимание);
Продолжить;
КонецПопытки;
Если Компоненты <> Неопределено Тогда
Для Каждого Компонента Из Компоненты Цикл
ИмяКласса = Компонента.Value("ProgID");
Если Истина
И Найти(НРег(ИмяКласса), "v8") = 1
И Найти(НРег(ИмяКласса), ".comconnector") = 4
Тогда
НомерИзданияПлатформы = Число(Сред(ИмяКласса, 3, 1));
ИмяКласса = "V8" + НомерИзданияПлатформы + ".ComConnector";
ПолноеИмяФайла = Компонента.Value("DLL");
Это64битнаяКомпонента = Найти(НРег(ПолноеИмяФайла), "(x86)") = 0 И ирКэш.Это64битнаяОСЛкс(Компьютер); // Ненадежно
СтрокиКлассов = Классы.НайтиСтроки(Новый Структура("ИмяКласса, x64", ИмяКласса, Это64битнаяКомпонента));
Если СтрокиКлассов.Количество() > 0 Тогда
СтрокаКласса = СтрокиКлассов[0];
СтрокаКласса.ИмяФайла = ПолноеИмяФайла;
СтрокаКласса.ИдентификаторКласса = Компонента.Value("CLSID");
СтрокаКласса.Зарегистрирован = Истина;
КонецЕсли;
КонецЕсли;
Прервать;
КонецЦикла;
КонецЕсли;
Если ирКэш.Это64битнаяОСЛкс(Компьютер) Тогда
Компоненты = Приложения.GetCollection("LegacyComponents", Приложение.Key);
Компоненты.Populate();
Для Каждого Компонента Из Компоненты Цикл
ИмяКласса = Компонента.Value("ProgID");
Если Истина
И Найти(НРег(ИмяКласса), "v8") = 1
И Найти(НРег(ИмяКласса), ".comconnector") = 4
Тогда
НомерИзданияПлатформы = Число(Сред(ИмяКласса, 3, 1));
ИмяКласса = "V8" + НомерИзданияПлатформы + ".ComConnector";
СтрокиКлассов = Классы.НайтиСтроки(Новый Структура("ИмяКласса, x64", ИмяКласса, Ложь));
Если СтрокиКлассов.Количество() > 0 Тогда
СтрокаКласса = СтрокиКлассов[0];
ПолноеИмяФайла = Компонента.Value("InprocServer32");
СтрокаКласса.ИдентификаторКласса = Компонента.Value("CLSID");
СтрокаКласса.ИмяФайла = ПолноеИмяФайла;
СтрокаКласса.Зарегистрирован = Истина;
КонецЕсли;
КонецЕсли;
Прервать;
КонецЦикла;
КонецЕсли;
КонецЦикла;
Для Каждого СтрокаТаблицы Из Классы Цикл
Если ЗначениеЗаполнено(СтрокаТаблицы.ИмяФайла) Тогда
ФайлWMI = ирОбщий.ПолучитьФайлWMIЛкс(СтрокаТаблицы.ИмяФайла);
СтрокаСборки = "";
Если ФайлWMI <> Неопределено Тогда
СтрокаТаблицы.ФайлСуществует = Истина;
СтрокаСборки = ФайлWMI.Version;
КонецЕсли;
Если ЗначениеЗаполнено(СтрокаСборки) Тогда
СтрокаТаблицы.СборкаПлатформы = СтрокаСборки;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Классы.Сортировать("ИзданиеПлатформы Убыв, ТипКласса");
КонецПроцедуры
Функция ЗаполнитьТипыCOMКлассов() Экспорт
ТабличныйДокумент = ПолучитьМакет("ТипыCOMКлассов");
Результат = ирОбщий.ПолучитьТаблицуИзТабличногоДокументаЛкс(ТабличныйДокумент);
ТипыComКлассов.Загрузить(Результат);
Возврат Результат;
КонецФункции
//ирПортативный лФайл = Новый Файл(ИспользуемоеИмяФайла);
//ирПортативный ПолноеИмяФайлаБазовогоМодуля = Лев(лФайл.Путь, СтрДлина(лФайл.Путь) - СтрДлина("Модули")) + "ирПортативный.epf";
//ирПортативный #Если Клиент Тогда
//ирПортативный Контейнер = Новый Структура();
//ирПортативный Оповестить("ирПолучитьБазовуюФорму", Контейнер);
//ирПортативный Если Не Контейнер.Свойство("ирПортативный", ирПортативный) Тогда
//ирПортативный ПолноеИмяФайлаБазовогоМодуля = ВосстановитьЗначение("ирПолноеИмяФайлаОсновногоМодуля");
//ирПортативный ирПортативный = ВнешниеОбработки.ПолучитьФорму(ПолноеИмяФайлаБазовогоМодуля);
//ирПортативный КонецЕсли;
//ирПортативный #Иначе
//ирПортативный ирПортативный = ВнешниеОбработки.Создать(ПолноеИмяФайлаБазовогоМодуля, Ложь); // Это будет второй экземпляр объекта
//ирПортативный #КонецЕсли
//ирПортативный ирОбщий = ирПортативный.ПолучитьОбщийМодульЛкс("ирОбщий");
//ирПортативный ирКэш = ирПортативный.ПолучитьОбщийМодульЛкс("ирКэш");
//ирПортативный ирСервер = ирПортативный.ПолучитьОбщийМодульЛкс("ирСервер");
//ирПортативный ирПривилегированный = ирПортативный.ПолучитьОбщийМодульЛкс("ирПривилегированный");