RDT1C/DataProcessors/ирУправлениеCOMКлассами1С/Ext/ObjectModule.bsl
Администратор dcf1ca5dd0 Сравнение таблиц
*Исправлено в некоторых случаях потеря отрицательных чисел в колонках разницы числовых колонок
        *Исправлена ошибка сравнения при наличии колонок с пустым синонимом
        +Добавлен индикатор неуникальных строк для каждой таблицы
        *Оптимизирован алгоритм сравнения таблиц
    Консоль кода
        *Исправлена ошибка вычисления выражений с параметрами командой "Вычислить"
        *Исправлена генерация внешней обработки алгоритма при незаполненной настройке "Каталог объектов для отладки" для выполнения на клиенте в вариантах Расширение и Подсистема
    Табличный документ
        +Добавлена кнопка "Открыть в Excel" позволяющая быстро открыть табличный документ в EXCEL
        +Теперь при сохранении файла с расширением не mxl его сразу предлагается открыть в сопоставленном приложении
        +Добавлен флажок "Устанавливать "Содержит значение"" включенный по умолчанию для борьбы с проблемой обрезания лидирующих нулей при редактировании в EXCEL
    Таблица значений
        +Добавлена кнопка "Неуникальные" для обозначения неуникальных строк
        +Добавлена команда "Передать"/"в таблицу БД"
    Консоль запросов
        +Для табличного поля результата добавлена кнопка "Неуникальные" для обозначения неуникальных строк
        *Исправлена ошибка выполнения пакетного запроса с удалением временной таблицы в режиме дерева запроса
    Динамический список
        *Исправлено позиционирование на нужной строке независимого регистра сведений при открытии с параметрами
        +Добавлены команды "Сравнить" и "Вывести строки"
    Общее
        +Добавлен общий модуль ирИнтерфейсныйДляВстраивания для слабой интеграции с конфигурацией
        *Команда "Вывести в табличный документ" везде переименована в "Вывести строки"
        В команде "Вывести строки"
            +добавлена полная поддержка динамических списков
            *Исправлен вывод идентификаторов без типов
            *Исправлено долгое открытие в портативном варианте
            *Добавлен флажок "В таблицу значений"
        *Исправлена свежая невозможность ввода битых ссылок в полях ввода
    Консоль компоновки
        +В панели настроек компоновки добавлена закладка "Наборы данных" отображающая внешние наборы данных
    Редактор пользователей
        +В форме пользователя для списка ролей добавлена возможность множественного выделения и установки/снятия пометок
    Загрузка табличных данных
        +Добавлены флажки для отключения оперативного вывода ошибок
        +Добавлена команда "Удалить успешные строки из таблицы значений
        *Устранено требование заполненности всех полей ключа при поиске строки БД
        +Реализовано кэширование поисков ссылок при конвертации значений
        +Добавлен индикатор неуникальных строк таблицы значений на закладке "Сопоставление колонок"
        +Добавлены поля количества не успешно и успешно загруженных строк
        *Исправлена загрузка групп
        *Недоступные для изменения поля таблицы БД теперь нельзя помечать
    Адаптация расширения
        *Исправлена некорректное выполнение адаптации
    Редактор объекта БД
        *Исправлено обновление заголовков некоторых страниц основной панели
    Менеджер табличного поля
        +Добавлено много универсальных команд
    Анализ техножурнала
        *Исправлено некорректное чтение свойств lka, lkp, lkpid, lksrc
2017-08-06 17:52:46 +03:00

326 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");
СтрокаПриложения.Зарегистрирован = Истина;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура ОбновитьТаблицуКлассов(ЗаполнятьТолькоВнешниеСоединения = Ложь) Экспорт
Классы.Очистить();
МассивРазрядностей = Новый Массив();
МассивРазрядностей.Добавить(Ложь);
Если ирКэш.Это64битнаяОСЛкс(Компьютер) Тогда
МассивРазрядностей.Добавить(Истина);
//Если ЗаполнятьТолькоВнешниеСоединения Тогда
// Если КэшКонтекстаИис.Это64битныйПроцессИис() Тогда
// МассивРазрядностей.Удалить(0);
// Иначе
// МассивРазрядностей.Удалить(1);
// КонецЕсли;
//КонецЕсли;
КонецЕсли;
ИзданияПлатформы = Новый СписокЗначений;
Для Счетчик = 1 По 3 Цикл
ИзданияПлатформы.Добавить("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";
//ирПортативный #Если Клиент Тогда
//ирПортативный Контейнер = Новый Структура();
//ирПортативный Оповестить("ирПолучитьБазовуюФорму", Контейнер);
//ирПортативный Если Не Контейнер.Свойство("ирПортативный", ирПортативный) Тогда
//ирПортативный ПолноеИмяФайлаБазовогоМодуля = ВосстановитьЗначение("ирПолноеИмяФайлаОсновногоМодуля");
//ирПортативный ирПортативный = ВнешниеОбработки.ПолучитьФорму(ПолноеИмяФайлаБазовогоМодуля);
//ирПортативный КонецЕсли;
//ирПортативный #Иначе
//ирПортативный ирПортативный = ВнешниеОбработки.Создать(ПолноеИмяФайлаБазовогоМодуля, Ложь); // Это будет второй экземпляр объекта
//ирПортативный #КонецЕсли
//ирПортативный ирОбщий = ирПортативный.ПолучитьОбщийМодульЛкс("ирОбщий");
//ирПортативный ирКэш = ирПортативный.ПолучитьОбщийМодульЛкс("ирКэш");
//ирПортативный ирСервер = ирПортативный.ПолучитьОбщийМодульЛкс("ирСервер");
//ирПортативный ирПривилегированный = ирПортативный.ПолучитьОбщийМодульЛкс("ирПривилегированный");