RDT1C/DataProcessors/ирУправлениеCOMКлассами1С/Ext/ObjectModule.bsl
Администратор e09a0dbe6c Анализ техножурнала
+В форме события добавлена команда "Сравнить"
    Консоль запросов
        +При открытии конструктора запроса ИР теперь передаются параметры из консоли и при закрытии параметры добавляются в консоль
        *Исправлено выполнение лишних запросов командой "Выполнить все подзапросы"
    Конструктор запроса
        *Исправлено некорректное вычисление типов полей временной таблицы, созданной запросом пакета с объединением разнотипных полей
        +При двойном клике в колонках "Тип значения" теперь открывается форма просмотра описания типов
        *Исправлена потеря условия и типа связи при перестановке таблиц в связи таблиц
        *Исправлена недоступность для изменения агрегатной функции у выбранного поля в некоторых случаях
        *Устранена замена имен параметров из нескольких слов без пробела на имена с пробелами при входе в режим редактирования строки для значений отбора
        *Исправлено некорректное копирование запроса создания временной таблицы
    Удаление объектов с контролем ссылок
        *Исправлена ошибка обращения к полю Предопределенный на 8.3.9+ при выборе в качестве кандидатов только объектов без этого свойства
    Консоль кода
        +Добавлена поддержка отладки через внешнюю обработку на сервере в непортативных вариантах
    Портативный
        *В базовой форме устранена возможность открытия одноименных форм конфигурации вместо внешних инструментов
    Управление службами 1С
        +Улучшены диагностические сообщения
        +Добавлен индикатор запуска от имени администратора
        +Добавлена кнопка запуска от имени администратора
    Управление COM классами 1С
        +Добавлен индикатор запуска от имени администратора
        +Добавлена кнопка запуска нового сеанса от имени администратора
    Административная регистрация COM компонент
        +Добавлен индикатор запуска от имени администратора
    Общее
        +В окне "О подсистеме" в информацию для технической поддержке добавлен элемент "От имени администратора Windows"
2017-06-18 13:29:57 +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 По 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";
//ирПортативный #Если Клиент Тогда
//ирПортативный Контейнер = Новый Структура();
//ирПортативный Оповестить("ирПолучитьБазовуюФорму", Контейнер);
//ирПортативный Если Не Контейнер.Свойство("ирПортативный", ирПортативный) Тогда
//ирПортативный ПолноеИмяФайлаБазовогоМодуля = ВосстановитьЗначение("ирПолноеИмяФайлаОсновногоМодуля");
//ирПортативный ирПортативный = ВнешниеОбработки.ПолучитьФорму(ПолноеИмяФайлаБазовогоМодуля);
//ирПортативный КонецЕсли;
//ирПортативный #Иначе
//ирПортативный ирПортативный = ВнешниеОбработки.Создать(ПолноеИмяФайлаБазовогоМодуля, Ложь); // Это будет второй экземпляр объекта
//ирПортативный #КонецЕсли
//ирПортативный ирОбщий = ирПортативный.ПолучитьОбщийМодульЛкс("ирОбщий");
//ирПортативный ирКэш = ирПортативный.ПолучитьОбщийМодульЛкс("ирКэш");
//ирПортативный ирСервер = ирПортативный.ПолучитьОбщийМодульЛкс("ирСервер");
//ирПортативный ирПривилегированный = ирПортативный.ПолучитьОбщийМодульЛкс("ирПривилегированный");