//Пример вызова (в отладчике, табло или своем коде) // ВнешниеОбработки.Создать("T:\Информатор_82.epf").Изучить(Новый ТаблицаЗначений) // для исследования глобального контекста следующий вызов // ВнешниеОбработки.Создать("T:\Информатор_82.epf").Изучить(Неопределено) // // Экспортные методы // булево = Изучить(Объект) - показ формы обработки с данными объекта // таблицаЗначений = ПолучитьТаблицуМетодов(Объект) // таблицаЗначений = ПолучитьТаблицуСвойств(Объект) // булево = МетодСуществует(Объект, наименованиеМетода) // булево = СвойствоСуществует(Объект, наименованиеСвойства) Перем СТРОКА_ОПИСАНИЕ_МЕТОДА_БЕЗ_ПАРАМЕТРОВ Экспорт; Перем СТРОКА_МЕТОДЫ Экспорт; Перем СТРОКА_СВОЙСТВА Экспорт; Перем СТРОКА_ГЛОБАЛЬНЫЙ_КОНТЕКСТ; // Экспорт; Перем ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_СВОЙСТВ_И_МЕТОДОВ; // Экспорт; Перем ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_СВОЙСТВ; Перем ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_МЕТОДОВ; Перем ФЛАГ_ЗАПОЛНЕНИЯ_ЗАПОЛНИТЬ_СВОЙСТВА; Перем ФЛАГ_ЗАПОЛНЕНИЯ_ЗАПОЛНИТЬ_МЕТОДЫ; Перем ИМЯ_КЛАССА_DynamicWrapperX; Перем ScrptCtrl; Перем Wrap; Перем ТЗ; Перем buf; Перем ppv; Перем WshShell; // Экспорт; Перем ФайлРегистратораКомпонент; // Экспорт; Перем ИсполнительСкрытыхКомандСистемы; Перем ПапкаВнешнихКомпонент; // Экспорт; Перем Флаг; Функция Версия() Экспорт Возврат "1.12"; КонецФункции #Если Клиент Тогда // основной метод для внешнего использования, например, в отладчике // если Объект = неопределено, то исследуется глобальный контекст Функция Изучить(Объект, Модально = Ложь) Экспорт форма = ЭтотОбъект.ПолучитьФорму(,, Новый УникальныйИдентификатор); ИсследоватьОбъект(Объект); форма.УстановитьЗаголовокПоОбъекту(Объект); //форма.СпрятатьКолонкиВЗависимостиОтОбъекта(Объект); Если Модально Тогда форма.ОткрытьМодально(); Иначе форма.Открыть(); КонецЕсли; Возврат Истина; КонецФункции Функция ПолучитьТаблицуСвойств(Объект) Экспорт Если НЕ ТипДоступенДляИсследования(Объект) Тогда ВызватьИсключение "Объект недоступен для изучения"; КонецЕсли; ИсследоватьОбъект(Объект, ФЛАГ_ЗАПОЛНЕНИЯ_ЗАПОЛНИТЬ_СВОЙСТВА); резТаблица = Новый ТаблицаЗначений; резТаблица.Колонки.Добавить("Наименование"); резТаблица.Колонки.Добавить("Тип"); резТаблица.Колонки.Добавить("Значение"); резТаблица.Колонки.Добавить("Индекс"); резТаблица.Колонки.Добавить("ИндексКонтекста"); новСтрока = ДЗ.Строки[0]; Для каждого строка Из новСтрока.Строки Цикл НоваяСтрока = резТаблица.Добавить(); ЗаполнитьЗначенияСвойств(НоваяСтрока, строка); НоваяСтрока.Значение = строка.Объект; //НоваяСтрока.Наименование = строка.Наименование; //НоваяСтрока.Индекс = строка.Индекс; КонецЦикла; Возврат резТаблица; КонецФункции Функция ПолучитьТаблицуМетодов(Объект) Экспорт Если НЕ ТипДоступенДляИсследования(Объект) Тогда ВызватьИсключение "Объект недоступен для изучения"; КонецЕсли; ИсследоватьОбъект(Объект, ФЛАГ_ЗАПОЛНЕНИЯ_ЗАПОЛНИТЬ_МЕТОДЫ); резТаблица = Новый ТаблицаЗначений; резТаблица.Колонки.Добавить("Наименование"); резТаблица.Колонки.Добавить("КоличествоПараметров"); резТаблица.Колонки.Добавить("ЕстьВозвращаемоеЗначение"); //резТаблица.Колонки.Добавить("Тип"); //резТаблица.Колонки.Добавить("Значение"); резТаблица.Колонки.Добавить("Индекс"); резТаблица.Колонки.Добавить("ИндексКонтекста"); новСтрока = ДЗ.Строки[0]; Для каждого строка Из новСтрока.Строки Цикл НоваяСтрока = резТаблица.Добавить(); ЗаполнитьЗначенияСвойств(НоваяСтрока, строка); //НоваяСтрока.Наименование = строка.Наименование; //НоваяСтрока.Значение = строка.Объект; //НоваяСтрока.КоличествоПараметров = строка.КоличествоПараметров; //НоваяСтрока.ЕстьВозвращаемоеЗначение = строка.ЕстьВозвращаемоеЗначение = Истина; //НоваяСтрока.Индекс = строка.ИндексМетодаСвойства; КонецЦикла; Возврат резТаблица; КонецФункции Функция СвойствоСуществует(Объект, наименованиеСвойства) Экспорт таблица = ПолучитьТаблицуСвойств(Объект); строка = таблица.Найти(наименованиеСвойства, "Наименование"); Возврат строка <> Неопределено; КонецФункции Функция МетодСуществует(Объект, наименованиеМетода) Экспорт таблица = ПолучитьТаблицуМетодов(Объект); строка = таблица.Найти(наименованиеМетода, "Наименование"); Возврат строка <> Неопределено; КонецФункции // вызывается из формы обработки Процедура ИсследоватьОбъект(Объект, парамФлагЗаполнения = Неопределено ) Экспорт Если Объект = Неопределено Тогда // глобальный контекст //Если ЭтоПлатформа_81() Тогда // ВызватьИсключение "Изучение глобального контекста для платформы 8.1 пока не реализовано!"; //КонецЕсли; Объект = СТРОКА_ГЛОБАЛЬНЫЙ_КОНТЕКСТ; //ElsIf Объект = ЭтотОбъект.ПолучитьФорму() Then // Возврат; КонецЕсли; Перехват(); Очистить(ДЗ.Строки); ДЗ.Строки.Очистить(); новСтрока = ДЗ.Строки.Добавить(); новСтрока.Наименование = "Значение"; новСтрока.Тип = ТипЗнч(Объект); новСтрока.Значение = Объект; новСтрока.Объект = Объект; Если парамФлагЗаполнения = Неопределено Тогда парамФлагЗаполнения = ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_СВОЙСТВ_И_МЕТОДОВ; КонецЕсли; ЗаполнитьСубДерево(Объект, новСтрока, парамФлагЗаполнения); //0 КонецПроцедуры Функция Инит() //Экспорт ПапкаВнешнихКомпонент = Новый Файл(КаталогВременныхФайлов()); WshShell = Новый COMОбъект("WScript.Shell"); Wrap = "НеИнициализирован"; Wrap = ПолучитьWinAPI(); ДЗ.Колонки.Добавить("Наименование"); ДЗ.Колонки.Добавить("Тип"); ДЗ.Колонки.Добавить("Значение"); ДЗ.Колонки.Добавить("Объект"); ДЗ.Колонки.Добавить("УжеЗаполняли"); ДЗ.Колонки.Добавить("ЕстьВозвращаемоеЗначение"); ДЗ.Колонки.Добавить("КоличествоПараметров"); ДЗ.Колонки.Добавить("ИндексКонтекста"); ДЗ.Колонки.Добавить("Индекс"); //ИндексМетодаСвойства"); КонецФункции Процедура Перехват() //Экспорт If ТипЗнч(ScrptCtrl) <> Тип("Неопределено") Then Возврат; EndIf; ТекстМодуля = Public_Consts(); ТекстМодуля = ТекстМодуля + Public_Vars(); ТекстМодуля = ТекстМодуля + Class_Service(); ТекстМодуля = ТекстМодуля + Funcs(); ScrptCtrl = Новый COMОбъект("MSScriptControl.ScriptControl"); ScrptCtrl.Language = "vbscript"; Попытка ScrptCtrl.AddCode(ТекстМодуля); Исключение Сообщить(ScrptCtrl.Error.Description); Сообщить(ScrptCtrl.Error.Source); Сообщить(ScrptCtrl.Error.Text); Сообщить(ScrptCtrl.Error.Line); КонецПопытки; buf = ScrptCtrl.Eval("oServ.buf"); ppv = ScrptCtrl.Eval("oServ.ppv"); Wrap.RegisterAddr(buf, "ImplBase_call", "i=pllp", "r=l"); //ID 20 КонецПроцедуры Функция ЭтоПлатформа_81() Перем локальная; этоПлатформа_81 = Истина; Попытка Выполнить("локальная = Метаданные.РежимСовместимости"); этоПлатформа_81 = Ложь; Исключение КонецПопытки; Возврат этоПлатформа_81; КонецФункции Функция Public_Consts() ТекстМодуля = " |Public Const S_OK = &h0 |Public Const E_NOINTERFACE = &h80004002 //|Public Const E_UNEXPECTED = &h8000FFFF |Public Const CP_ACP = &h0 | |Public Const HEAP_ZERO_MEMORY = &h00000008 |Public Const PAGE_EXECUTE_READWRITE = &h40 | |Public Const VT_BSTR = &h8 |Public Const VT_DISPATCH = &h9 | |'IID Интерфейсов |Public Const IID_IContextExtImpBase = ""{FD7B6CC2-DC8E-11D2-B8D0-008048DA0335}"" |Public Const IID_IValueImplBase = ""{FD7B6CC3-DC8E-11D2-B8D0-008048DA0335}"" |Public Const IID_GC = ""{F7399BD5-100E-4D0A-A5CE-F97810ACFEE9}"" | |Public Const bsl_off_13 = &h119E7AF0 |Public Const bsl_off_14 = &h11A299F0 | |Public Const platform_offset = &h18 |"; Возврат ТекстМодуля; КонецФункции Функция Public_Vars() ТекстМодуля = " |Public oServ | |Public Wrap |Public curVers 'Версия 8.2 | |Set Wrap = CreateObject("""+ИМЯ_КЛАССА_DynamicWrapperX+""") |"; //|Set Wrap = CreateObject(""DynamicWrapperX"") Возврат ТекстМодуля; КонецФункции Функция Class_Service() ТекстМодуля = " //{ |Class Service |Class Service //{ |Vars | Private hHeap | Public buf 'Буфер для вызова функций | Private buf_thiscall 'Буфер для вызова функций | | Private res 'Память для результата VirtualProtect | Private pGC 'Глоб.объект | Public ppv | Private pIID | Private swIID | Private handle | | Public numGK 'Кол-во ГК контекстов | Public pArray 'Массив ГК | | 'Для передачи параметров | Public paramArr2 'Для печати | Public paramArr9 'Для вызова функций | | Private pMes 'Контекст, с методом /Сообщить/ | Private numMes 'Номер метода /Сообщить/ | | Private adrValue_str 'адрес ф-и __thiscall core::Value::Value(wchar_t const *) | Private adrValue_void 'адрес ф-и __thiscall core::Value::Value(void) //} | //{ |Release | Private Function Release(pObj) | vfunc pObj, (3 - 1) * 4 | res = Wrap.IUnknown_Release(pObj) | End Function //} | //{ |FindCG_Message | Private Function FindCG_Message() | FindCG_Message = -1 | | 'Найдем контекст, в котором есть метод ""Сообщить"" | j = 0 | PutString(""Сообщить"") | Do While j < numGK + 1 | pIContext = Wrap.NumGet(pArray, j * 4) | | vfunc pIContext, 4 * (16 - 1) | numMes = Wrap.ImplBase_findMethod(pIContext, ppv) | If numMes =>0 Then | FindCG_Message = pIContext | Exit Do | End If | j = j + 1 | Loop | '======================================================= | End Function //} | //{ |GetArrayGC | Private Function GetArrayGC() | IIDFromString IID_GC | | 'ГО (1) | vfunc pGC, (15 - 1) * 4 | pObj1 = Wrap.GetObjectFromIID(pGC, pIID) | | 'ГО (2) | vfunc pObj1, (13 - 1) * 4 | res = Wrap.GetObj(pObj1, ppv) | pObj2 = Wrap.NumGet(ppv) | | Select Case curVers | Case 13 | numfunc = 68 | Case 14 | numfunc = 69 | Case 15 | numfunc = 70 | Case Else | numfunc = 70 | End Select | | 'ГО (3) | vfunc pObj2, (numfunc - 1) * 4 | res1 = Wrap.GetObj(pObj2, ppv) | pObj3 = Wrap.NumGet(ppv) | | 'Массив | GetArrayGC = Wrap.NumGet(pObj3, &h10) | | 'Количество | numGK = (Wrap.NumGet(pObj3, &h14) - GetArrayGC) / 4 | numGK = numGK - 1 | | Release pObj3 | Release pObj2 | Release pObj1 | Release pGC | End Function //} | //{ |Class_Initialize | Private Sub Class_Initialize | Wrap.Register ""Kernel32"", ""HeapAlloc"", ""i=lll"", ""r=l"" | Wrap.Register ""Kernel32"", ""GetProcessHeap"", ""r=l"" | Wrap.Register ""Kernel32"", ""HeapFree"", ""i=lll"",""r=l"" | Wrap.Register ""Kernel32"", ""VirtualProtect"" , ""i=lllp"", ""r=l"" | Wrap.Register ""Kernel32"", ""LoadLibrary"" , ""i=s"", ""r=h"" | Wrap.Register ""Kernel32"", ""GetProcAddress"" , ""i=hs"", ""r=u"" | Wrap.Register ""Kernel32"", ""MultiByteToWideChar"", ""i=llslpl"", ""r=l"" | Wrap.Register ""Ole32"" , ""IIDFromString"", ""i=pp"", ""r=l"" | Wrap.Register ""Version"", ""GetFileVersionInfoSize"", ""i=sl"", ""r=l"" | Wrap.Register ""Version"", ""GetFileVersionInfo"", ""i=sllp"", ""r=l"" | Wrap.Register ""Version"", ""VerQueryValue"", ""i=pspp"", ""r=l"" | | hHeap = Wrap.GetProcessHeap() | curVers = GetVersion() | | numGK = 0 | code_len = 10 | | buf_thiscall= Wrap.HeapAlloc(hHeap, HEAP_ZERO_MEMORY, code_len) | ppv = Wrap.HeapAlloc(hHeap, HEAP_ZERO_MEMORY, &h20) 'Под внутр. нужды и строки | pIID = Wrap.HeapAlloc(hHeap, HEAP_ZERO_MEMORY, 32) | swIID = Wrap.HeapAlloc(hHeap, HEAP_ZERO_MEMORY, 100) | | paramArr2 = Wrap.HeapAlloc(hHeap, HEAP_ZERO_MEMORY, 16 * 2 + 4 * (2 + 1) + 4 * 3) 'На 2 параметра | paramArr9 = Wrap.HeapAlloc(hHeap, HEAP_ZERO_MEMORY, 16 * 9 + 4 * (9 + 1) + 4 * 3) 'На 9 параметров | '======================================================= | 'Буфер для вызова функций интерфейса | Wrap.VirtualProtect buf_thiscall, code_len, PAGE_EXECUTE_READWRITE, ppv | | Wrap.NumPut &hB9, buf_thiscall, 0, ""b"" 'mov ecx, .... pObj | | buf = buf_thiscall + 5 | Wrap.NumPut &hE9, buf, 0, ""b"" 'jmp ...Addr | '======================================================= | 'IUnknown | Wrap.RegisterAddr buf, ""IUnknown_QueryInterface"", ""i=ppp"", ""r=l"" 'ID 1 | Wrap.RegisterAddr buf, ""IUnknown_AddRef"", ""i=p"", ""r=l"" 'ID 2 | Wrap.RegisterAddr buf, ""IUnknown_Release"", ""i=p"", ""r=l"" 'ID 3 | | 'IContextExtImplBase | Wrap.RegisterAddr buf , ""ImplBase_getName"", ""i=pll"", ""r=l"" 'ID getPropName - 5, getMethodName - 10 | Wrap.RegisterAddr buf , ""ImplBase_getN"", ""i=p"", ""r=l"" 'ID getNProps - 4, getNMethods - 9 | Wrap.RegisterAddr buf , ""ImplBase_getNParams"", ""i=pl"", ""r=l"" 'ID 11 | Wrap.RegisterAddr buf , ""ImplBase_hasRetVal"", ""i=pl"", ""r=l"" 'ID 15 | Wrap.RegisterAddr buf , ""ImplBase_findMethod"", ""i=pp"", ""r=l"" 'ID 16 | Wrap.RegisterAddr buf , ""ImplBase_getParamDefValue"", ""i=pllp"", ""r=l"" 'ID 14 | Wrap.RegisterAddr buf , ""ImplBase_call"", ""i=pllp"", ""r=l"" 'ID 20 | Wrap.RegisterAddr buf_thiscall, ""ImplBase_call_thiscall"", ""i=pllp"", ""r=l"" 'ID 20 | | 'IValue | Wrap.RegisterAddr buf_thiscall, ""setIValue"", ""i=p"", ""r=l"" 'ID 1 | Wrap.RegisterAddr buf_thiscall, ""getIValue"", ""i=p"", ""r=l"" 'ID 2 | Wrap.RegisterAddr buf_thiscall, ""type0"", ""i=p"", ""r=l"" 'ID 7 | | 'ObjectTypeCore | Wrap.RegisterAddr buf, ""getTypeCode"", ""i=p"", ""r=l"" 'ID 4 | '======================================================= | handle = Wrap.LoadLibrary(""core82"") | 'Функция возвращает ГК | Addr1 = Wrap.GetProcAddress(handle, ""?current_process@core@@YAPAVSCOM_Process@1@XZ"") | | Wrap.RegisterAddr Addr1, ""current_process"", ""r=l"" 'core::current_process(void) | | 'Вот это Глобальный Контекст | pGC = Wrap.current_process() | '======================================================= | 'CurProc | 'Функция из ВТ объекта pGC | 'возвращает какой-то глобальный объект (1) | 'в ВТ (1) есть ф-я, возвращающая другой ГО (2) | 'в ВТ (2) есть ф-я, возвращающая другой ГО (3) | '(3) - содержит массив ГК IContextExtImplBase | | Wrap.RegisterAddr buf, ""GetObjectFromIID"", ""i=pp"", ""r=l"" 'ID 15 | | 'Функция, получения объектов | Wrap.RegisterAddr buf, ""GetObj"", ""i=pp"", ""r=p"" | | 'Получим указатель на глоб. массив ГК | pArray = GetArrayGC() | | 'Для вывода сообщений | pMes = FindCG_Message() | '======================================================= | | adrValue_str = Wrap.GetProcAddress(handle, ""??0Value@core@@QAE@PB_W@Z"") '__thiscall core::Value::Value(wchar_t const *) | Wrap.RegisterAddr buf_thiscall, ""Value_str"", ""i=p"", ""r=l"" | | adrValue_void = Wrap.GetProcAddress(handle, ""??0Value@core@@QAE@XZ"") '__thiscall core::Value::Value(void) | Wrap.RegisterAddr buf_thiscall, ""Value_void"", ""r=l"" | | 'Обертка 1C-х объектов в IDispatch | Addr1 = Wrap.GetProcAddress(handle, ""?value_to_dispatch@core@@YA?AV?$InterfacePtr@UIDispatch@@@1@PAVIValue@1@PAVSCOM_ProcessData@1@@Z"") | Wrap.RegisterAddr Addr1, ""value_to_dispatch"", ""i=ppl"", ""r=l"" | | PrepareParams paramArr2, 2 | PrepareParams paramArr9, 9 | End Sub //} | //{ |Class_Terminate | Private Sub Class_Terminate | Wrap.HeapFree hHeap, 0, buf_thiscall | Wrap.HeapFree hHeap, 0, ppv | Wrap.HeapFree hHeap, 0, pIID | Wrap.HeapFree hHeap, 0, swIID | | Wrap.HeapFree hHeap, 0, paramArr2 | Wrap.HeapFree hHeap, 0, paramArr9 | | Set Wrap = Nothing //| MsgBox ""Class_Terminate2"" | End Sub //} | //{ |GetString | Private Function GetString(offset) | ppv1 = ppv + offset | ln = Wrap.NumGet(ppv1) | If ln > 15 Then | GetString = Wrap.StrGet(Wrap.NumGet(ppv1, 4) + 8) | Else | GetString = Wrap.StrGet(ppv1 + 4) | End If | End Function //} | //{ |PutString | Private Function PutString(txt) | 'Формируем структуру строки | ln = Len(txt) | If ln > 15 Then | Wrap.NumPut 16, ppv, 0 'Флаг, что строка длиннее 15 символов | Wrap.NumPut (ppv + 16), ppv, 4 'Указатель на начало строки | Wrap.NumPut (ppv + 24) + ln * 2, ppv, 8 'Указатель на 0, за концом строки | Wrap.NumPut 1, ppv, 12 'Не знаю, что это | | Wrap.NumPut 1, ppv, 16 'Это счетчик ссылок на строку | Wrap.NumPut 1, ppv, 20 'Не знаю, что это | res = Wrap.MultiByteToWideChar(CP_ACP, 0, txt, -1, ppv + 24, ln) | Wrap.NumPut 0, ppv, 24 + ln * 2 | Else | Wrap.NumPut ln, ppv, 0 | res = Wrap.MultiByteToWideChar(CP_ACP, 0, txt, -1, ppv + 4, ln) | End If | End Function //} | //{ |GetVersion | Private Function GetVersion() | sz = Wrap.GetFileVersionInfoSize(""core82"", 0) | | pbuf = Wrap.HeapAlloc(hHeap, 0, sz) | lplpBuffer = Wrap.HeapAlloc(hHeap, 0, 4) | puLen = Wrap.HeapAlloc(hHeap, 0, 4) | | res1 = Wrap.GetFileVersionInfo(""core82"",0, sz, pbuf) | res1 = Wrap.VerQueryValue(pbuf, ""\"", lplpBuffer, puLen) | | VS_FIXEDFILEINFO = Wrap.NumGet(lplpBuffer) | 'Младшая часть версии | lpart = Wrap.NumGet(VS_FIXEDFILEINFO, &h0C, ""t"") | 'Старшая часть версии | hpart = Wrap.NumGet(VS_FIXEDFILEINFO, &h0E, ""t"") | //| GetVersion = CSTR(hpart) & ""."" & CSTR(lpart) | GetVersion = hpart | | Wrap.HeapFree hHeap, 0, pbuf | Wrap.HeapFree hHeap, 0, lplpBuffer | Wrap.HeapFree hHeap, 0, puLen | End Function //} | //{ |IIDFromString | Private Function IIDFromString(sIDD) | IIDFromString = Wrap.MultiByteToWideChar(CP_ACP, 0, sIDD, -1, swIID, 100) | IIDFromString = Wrap.IIDFromString(swIID, pIID) | End Function //} | //{ |QueryInterface | Private Function QueryInterface(pObj, sIDD) | QueryInterface = E_NOINTERFACE | If IIDFromString(sIDD) = S_OK Then | vfunc pObj, &h0 | QueryInterface = Wrap.IUnknown_QueryInterface(pObj, pIID, ppv) | End If | End Function //} | //{ |GetInterface | Public Function GetInterface(pObj, sIID) | GetInterface = QueryInterface(pObj, sIID) | If GetInterface = S_OK Then | GetInterface = Wrap.NumGet(ppv) | End If | End Function //} | //{ |vfunc | Public Sub vfunc(pObj, offset) | Addr = Wrap.NumGet(Wrap.NumGet(pObj), offset) | Wrap.NumPut Addr - (buf + 1 + 4), buf, 1 | End Sub //} | //{ |this_call | Public Sub this_call(ECX, Addr) | Wrap.NumPut ECX, buf_thiscall,1 | Wrap.NumPut Addr - (buf + 1 + 4),buf, 1 | End Sub //} | //{ |SetParamsCount | Private Function SetParamsCount(pParams, num, cnt) | 'Указатели на начало и конец массива указателей на параметры | | 'Указатель на начало массива указателей на параметры | Wrap.NumPut (pParams + num * 16), pParams, num * 16 + (num + 1) * 4 | | 'Указатель на конец массива указателей на параметры | Wrap.NumPut (pParams + num * 16 + cnt * 4), pParams, num * 16 + (num + 1) * 4 + 4 | Wrap.NumPut (pParams + num * 16 + cnt * 4), pParams, num * 16 + (num + 1) * 4 + 8 | End Function //} | //{ |PrepareParams | Private Function PrepareParams(pParams, num) | 'Подготовим параметры, 16 байт на параметр | bsl_off = bsl_off_13 | If Left(curVers, 2) > ""13"" Then | bsl_off = bsl_off_14 | End If | | For j = 0 To num - 1 | Wrap.NumPut bsl_off, pParams, j * 16 | Next | | 'Указатели на параметры | For j = 0 To num - 1 | Wrap.NumPut (pParams + j * 16), pParams, num * 16 + j * 4 | Next | | 'Установим по-умолчанию 2 параметра | SetParamsCount pParams, num, 2 | End Function //} | //{ |SetParam | Private Function SetParam(pParams, num, paramType, paramValue, paramValueType) | Wrap.NumPut paramType, pParams, (num - 1) * 16 + 4 | Wrap.NumPut paramValue, pParams, (num - 1) * 16 + 8 | Wrap.NumPut paramValueType, pParams, (num - 1) * 16 + 12 | End Function //} | //{ |GetParam | Private Function GetParam(pParams, num) | GetParam = Wrap.NumGet(pParams, 8 + num * 16) | End Function //} | //{ |getParamList | Public Function getParamList(pParams, num) | getParamList = pParams + num * 16 + (num + 1) * 4 | End Function //} | //{ |getType | Public Function getType(pIValue) | Addr = Wrap.NumGet(Wrap.NumGet(pIValue), (7 - 1) * 4) | this_call pIValue, Addr | res = Wrap.type0(ppv + 8) | | pObjTypeCore = Wrap.NumGet(ppv + 8) | vfunc pObjTypeCore, (4 - 1) * 4 | getType = Wrap.getTypeCode(pObjTypeCore) //| MsgBox getType | End Function //} | //{ |getIValue | Private Function getIValue(pValue) | Addr = Wrap.NumGet(Wrap.NumGet(pValue), (2 - 1) * 4) | | this_call pValue, Addr | res = Wrap.getIValue(ppv + 8) | getIValue = Wrap.NumGet(ppv + 8) | End Function //} | //{ |setIValue | Private Function setIValue(pIValue, pValue) | Addr = Wrap.NumGet(Wrap.NumGet(pIValue), (1 - 1) * 4) | | this_call pIValue, Addr | setIValue = Wrap.setIValue(pValue) | End Function //} | //{ |Message | Public Function Message(txt) | '1-й параметр, строка | '======================================================= | this_call ppv, adrValue_str | res = Wrap.Value_str(txt) | IValue = getIValue(ppv) | res = SetParam (paramArr2, 1, 0, IValue, 4) | | '2-й параметр, перечисление | '======================================================= | this_call ppv, adrValue_void | res = Wrap.Value_void() | | vfunc pMes, 4 * (14 - 1) | res = Wrap.ImplBase_getParamDefValue(pMes, numMes, 1, ppv) | IValue = getIValue(ppv) | res = SetParam(paramArr2, 2, 0, IValue, 0) | | SetParamsCount paramArr2, 2, 2 | '======================================================= | vtable = Wrap.NumGet(pMes) | Addr = Wrap.NumGet(vtable, 4 * (20 - 1)) | | this_call numMes, Addr | Wrap.ImplBase_call_thiscall pMes, numMes, 0, getParamList(paramArr2, 2) | End Function //} | //{ |PrepereDefParams |Public Function PrepareDefParams(pIContext, numFunc) | PrepareDefParams = -1 | | vfunc pIContext, 4 * (11 - 1) | NParams = Wrap.ImplBase_getNParams(pIContext, numFunc) | | If (NParams = 0) OR (NParams > 9) Then | Exit Function | End If | | j = 0 | Do While j < NParams | this_call ppv, adrValue_void | res = Wrap.Value_void() | | vfunc pIContext, 4 * (14 - 1) | res = Wrap.ImplBase_getParamDefValue(pIContext, numFunc, j, ppv) | If res <> S_OK Then | PrepareDefParams = -1 | Exit Do | End If | IValue = getIValue(ppv) | typeCode = getType(ppv) | res = SetParam(paramArr9, j + 1, 0, IValue, typeCode) | j = j + 1 | Loop | If PrepareDefParams = -1 Then | Exit Function | End If | | SetParamsCount paramArr9, 9, NParams | | this_call ppv, adrValue_void | res = Wrap.Value_void() | | vfunc pIContext, 4 * (20 - 1) | PrepareDefParams = getParamList(paramArr9, 9) | End Function //} | //{ |RetValueImplBase | Public Function RetValueImplBase() | pCont = getIValue(ppv) | pValueImplBase = GetInterface(pCont, IID_IValueImplBase) | | res = Wrap.value_to_dispatch(ppv, pValueImplBase, 0) | pDisp = Wrap.NumGet(ppv) | | 'Уменьшим счетчик ссылок (незаконно - не через Release), иначе повиснет ссылка и 1С не закроется | res = Wrap.NumGet(pDisp, 8) | res = Wrap.NumPut(res - 1, pDisp, 8) | | Set RetValueImplBase = Wrap.GetObject(pDisp) | End Function //} | |End Class //} | |Set oServ = New Service |"; Возврат ТекстМодуля; КонецФункции Функция Funcs() ТекстМодуля = " //{ |getN |Public Function getN(pIContext, nfunc) | getN = 0 | If pIContext <> 0 Then | oServ.vfunc pIContext, 4 * (nfunc - 1) | getN = Wrap.ImplBase_getN(pIContext) | End If |End Function //} | //{ |ImplBase_getN |Public Function ImplBase_getN(Obj, nfunc) | ImplBase_getN = 0 | If VarType(Obj) = VT_BSTR Then | For j = 0 To oServ.numGK | pIContext = Wrap.NumGet(oServ.pArray, j * 4) | ImplBase_getN = ImplBase_getN + getN(pIContext, nfunc) | Next | Else | pObj = Wrap.GetIDispatch(Obj) | pIContext = Wrap.NumGet(pObj, platform_offset) | //| If pIContext <> 0 Then //| oServ.Message Hex(pIContext) //| oServ.Message Hex(Wrap.NumGet(pIContext)) //| End If | | ImplBase_getN = getN(pIContext, nfunc) | End if |End Function //} | //{ |ImplBase_getName |Public Function ImplBase_getName(pIContext, num, nfunc) | ImplBase_getName = 0 | If pIContext <> 0 Then | j = 1 | Do While j > -1 | oServ.vfunc pIContext, 4 * (nfunc - 1) | pbstrName = Wrap.ImplBase_getName(pIContext, num, j) | | If (pbstrName <> 0) Then | If Wrap.StrGet(pbstrName) <> """" Then | ImplBase_getName = pbstrName | Exit Do | End If | End If | j = j - 1 | Loop | End If |End Function //} | //{ |valFill |Public Function valFill(pIContext, num, valTable, nfunc, ContID) | For j = 0 To num - 1 | pStr = ImplBase_getName(pIContext, j, nfunc) | If (pStr <> 0) Then | Set nRow = valTable.Add() | nRow.Name = Wrap.StrGet(pStr) | | oServ.vfunc pIContext, 4 * (15 - 1) | nRow.Val = Wrap.ImplBase_hasRetVal(pIContext, j) | | oServ.vfunc pIContext, 4 * (11 - 1) | nRow.NParams = Wrap.ImplBase_getNParams(pIContext, j) | nRow.ID = j | nRow.ContID = ContID | End If | Next |End Function //} | //{ |Fill |Public Function Fill(Obj, valTable, nfunc) | Fill = 0 | | If VarType(Obj) = VT_BSTR Then | For j = 0 To oServ.numGK | pIContext = Wrap.NumGet(oServ.pArray, j * 4) | num = getN(pIContext, nfunc - 1) | Fill = Fill + num | valFill pIContext, num, valTable, nfunc, j | Next | Else | pObj = Wrap.GetIDispatch(Obj) | pIContext = Wrap.NumGet(pObj, platform_offset) | | Fill = getN(pIContext, nfunc - 1) | valFill pIContext, Fill, valTable, nfunc, 0 | End if |End Function //} | //{ |GetContext |Public Function GetContext(Obj, numCont) | If VarType(Obj) = VT_BSTR Then | GetContext = Wrap.NumGet(oServ.pArray, numCont * 4) | Else | pObj = Wrap.GetIDispatch(Obj) | GetContext = Wrap.NumGet(pObj, platform_offset) | End If |End Function //} | //{ |PrepareDefParams |Public Function PrepareDefParams(Obj, numFunc, numCont) | pIContext = GetContext(Obj, numCont) | PrepareDefParams = oServ.PrepareDefParams(pIContext, numFunc) |End Function //} | //{ |RetValueImplBase |Public Function RetValueImplBase() | Set RetValueImplBase = oServ.RetValueImplBase() |End Function //} | |"; Возврат ТекстМодуля; КонецФункции Функция ТипДоступенДляИсследования(Объект, Уровень = 0) Если (Объект = Неопределено) И (Уровень = 0) Тогда // глобальный контекст Объект = СТРОКА_ГЛОБАЛЬНЫЙ_КОНТЕКСТ; КонецЕсли; типОбъект = ТипЗнч(Объект); Если (Объект <> СТРОКА_ГЛОБАЛЬНЫЙ_КОНТЕКСТ) Тогда If (типОбъект = Тип("Число"))ИЛИ (типОбъект = Тип("Строка")) ИЛИ (типОбъект = Тип("Дата")) ИЛИ (типОбъект = Тип("Булево")) ИЛИ (типОбъект = Тип("Неопределено")) ИЛИ (типОбъект = Тип("ComОбъект")) Then Возврат Ложь; EndIf; КонецЕсли; Возврат Истина; КонецФункции Функция ЭтоГлобальныйКонтекст(Объект) Экспорт Возврат Объект = СТРОКА_ГЛОБАЛЬНЫЙ_КОНТЕКСТ ИЛИ Объект = Неопределено; КонецФункции Функция ПолучитьОписание(Объект, ТЗ, Флаг, Уровень) Рез = ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_СВОЙСТВ_И_МЕТОДОВ; //0 Если НЕ ТипДоступенДляИсследования(Объект, Уровень) Тогда Возврат Рез; КонецЕсли; //типОбъект = ТипЗнч(Объект); //Если (Объект <> СТРОКА_ГЛОБАЛЬНЫЙ_КОНТЕКСТ) Тогда // If (типОбъект = Тип("Число"))ИЛИ // (типОбъект = Тип("Строка")) ИЛИ // (типОбъект = Тип("Дата")) ИЛИ // (типОбъект = Тип("Булево")) ИЛИ // (типОбъект = Тип("Неопределено")) ИЛИ // (типОбъект = Тип("ComОбъект")) Then // // Возврат Рез; // EndIf; //КонецЕсли; If Флаг = ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_СВОЙСТВ_И_МЕТОДОВ Then //0 Рез = ScrptCtrl.Run("ImplBase_getN",Объект, 4); Рез = Рез + ScrptCtrl.Run("ImplBase_getN", Объект, 9); //Адр = ScrptCtrl.CodeObject.ImplBase_pIContext(Объект); //If (Адр <> "0") И (Адр <> "") Then // Сообщить(""+ Объект + " :" + Адр); //EndIf; ElsIf Флаг = ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_СВОЙСТВ Then //1 Рез = ScrptCtrl.Run("ImplBase_getN",Объект, 4); ElsIf Флаг = ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_МЕТОДОВ Then //2 Рез = ScrptCtrl.Run("ImplBase_getN", Объект, 9); Else ТЗ = Новый ТаблицаЗначений; ТЗ.Колонки.Добавить("Name"); ТЗ.Колонки.Добавить("Type"); ТЗ.Колонки.Добавить("Val"); ТЗ.Колонки.Добавить("NParams"); ТЗ.Колонки.Добавить("ID"); ТЗ.Колонки.Добавить("ContID"); If Флаг = ФЛАГ_ЗАПОЛНЕНИЯ_ЗАПОЛНИТЬ_СВОЙСТВА Then //3 ScrptCtrl.Run("Fill", Объект, ТЗ, 5); Else ScrptCtrl.Run("Fill", Объект, ТЗ, 10); EndIf; //Если (Объект <> СТРОКА_ГЛОБАЛЬНЫЙ_КОНТЕКСТ) Тогда ТЗ.Сортировать("Name"); //EndIf; EndIf; Возврат Рез; КонецФункции Процедура ДобавитьВДерево(текСтрока, ТЗ, ТипТЗ, Объект) Для каждого текСтр Из ТЗ Цикл новСвойство = текСтрока.Строки.Добавить(); новСвойство.Наименование = текСтр.Name; //новСвойство.Наименование = текСтр.Name + " (" + ?(Объект <> СТРОКА_ГЛОБАЛЬНЫЙ_КОНТЕКСТ,"", "" + текСтр.ContID + ",") + текСтр.ID + ")"; //контИД это порядковый номер контекста из массива Глобальных контекстов, // ИД номер свойства/метода //контИД = 0 для не ГлК новСвойство.ИндексКонтекста = ?(Объект <> СТРОКА_ГЛОБАЛЬНЫЙ_КОНТЕКСТ, "", "" + текСтр.ContID); новСвойство.Индекс = текСтр.ID; текОбъект = ""; If ТипТЗ = СТРОКА_СВОЙСТВА Then Если Объект <> СТРОКА_ГЛОБАЛЬНЫЙ_КОНТЕКСТ Тогда Попытка текОбъект = Вычислить("Объект."+текСтр.Name);//Объект[текСтр.Name]; Исключение КонецПопытки; Иначе текОбъект = Вычислить(текСтр.Name); КонецЕсли; //текОбъект = Вычислить("Объект."+текСтр.Name);//Объект[текСтр.Name]; Значение = Строка(текОбъект); новСвойство.Тип = ТипЗнч(текОбъект); Else If текСтр.Val = 0 Then //Процедура Значение = ""; новСвойство.КоличествоПараметров = 0; новСвойство.ЕстьВозвращаемоеЗначение = Ложь; ElsIf текСтр.NParams > 0 Then Значение = СТРОКА_ОПИСАНИЕ_МЕТОДА_БЕЗ_ПАРАМЕТРОВ;//"<Функция требует " + Строка(текСтр.NParams) + " парам.>"; новСвойство.КоличествоПараметров = текСтр.NParams; новСвойство.ЕстьВозвращаемоеЗначение = Истина; //1; Else Значение = СТРОКА_ОПИСАНИЕ_МЕТОДА_БЕЗ_ПАРАМЕТРОВ; новСвойство.КоличествоПараметров = 0; новСвойство.ЕстьВозвращаемоеЗначение = Истина; //1; EndIf; EndIf; новСвойство.Значение = Значение; новСвойство.Объект = текОбъект; ЗаполнитьСубДерево(текОбъект, новСвойство, ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_СВОЙСТВ_И_МЕТОДОВ); //0); КонецЦикла; КонецПроцедуры Процедура ЗаполнитьСубДерево(Объект, текСтрока, Флаг) Экспорт Перем ТЗ; Рез = ПолучитьОписание(Объект, ТЗ, Флаг, текСтрока.Уровень()); If Флаг < ФЛАГ_ЗАПОЛНЕНИЯ_ЗАПОЛНИТЬ_СВОЙСТВА Then //3 If Рез > 0 Then новСтрока = текСтрока.Строки.Добавить(); If (Флаг > ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_СВОЙСТВ_И_МЕТОДОВ) Then //0 новСтрока.Наименование = ?(Флаг = ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_СВОЙСТВ, СТРОКА_СВОЙСТВА, СТРОКА_МЕТОДЫ); //1 новСтрока.Объект = новСтрока.Наименование; новСтрока.Строки.Добавить(); EndIf; EndIf; ElsIf Флаг = ФЛАГ_ЗАПОЛНЕНИЯ_ЗАПОЛНИТЬ_СВОЙСТВА Then //3 ДобавитьВДерево(текСтрока, ТЗ, СТРОКА_СВОЙСТВА, Объект); Else ДобавитьВДерево(текСтрока, ТЗ, СТРОКА_МЕТОДЫ, Объект); EndIf; КонецПроцедуры Процедура Очистить(НаборСтрок) Экспорт Для каждого текСтр Из НаборСтрок Цикл текСтр.Объект = 0; текСтр.Значение = 0; Очистить(текСтр.Строки); КонецЦикла; КонецПроцедуры Процедура ОбработатьСобытие_ДЗ_ПередРазворачиванием(Элемент, Строка, Отказ) Экспорт //Уже заполняли If Строка.УжеЗаполняли = Истина Then Возврат; EndIf; //1 Объект = Строка.Объект; Строка.Строки.Очистить(); If (Объект = СТРОКА_СВОЙСТВА) Then ЗаполнитьСубДерево(Строка.Родитель.Объект, Строка, ФЛАГ_ЗАПОЛНЕНИЯ_ЗАПОЛНИТЬ_СВОЙСТВА); //3 ElsIf (Объект = СТРОКА_МЕТОДЫ) Then ЗаполнитьСубДерево(Строка.Родитель.Объект, Строка, ФЛАГ_ЗАПОЛНЕНИЯ_ЗАПОЛНИТЬ_МЕТОДЫ); //4 Else ЗаполнитьСубДерево(Объект, Строка, ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_СВОЙСТВ); //1 ЗаполнитьСубДерево(Объект, Строка, ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_МЕТОДОВ); //2 EndIf; Строка.УжеЗаполняли = Истина; //1; КонецПроцедуры Процедура ОбработатьСобытие_ДЗ_Выбор(Элемент, ВыбраннаяСтрока, Колонка, СтандартнаяОбработка) Экспорт //If Колонка.Имя = "Значение" Then If (ВыбраннаяСтрока.ЕстьВозвращаемоеЗначение = Истина) И (ВыбраннаяСтрока.Значение = СТРОКА_ОПИСАНИЕ_МЕТОДА_БЕЗ_ПАРАМЕТРОВ) Then //1 ВычислитьФункциюВСтроке(ВыбраннаяСтрока); EndIf; //EndIf; КонецПроцедуры Процедура вспВычислитьФункциюВСтроке(ВыбраннаяСтрока, текОбъект) ВыбраннаяСтрока.Тип = ТипЗнч(текОбъект); ВыбраннаяСтрока.Значение = Строка(текОбъект); ВыбраннаяСтрока.Объект = текОбъект; ЗаполнитьСубДерево(текОбъект, ВыбраннаяСтрока, ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_СВОЙСТВ_И_МЕТОДОВ); //0 КонецПроцедуры Процедура ВычислитьФункциюВСтроке(ВыбраннаяСтрока) Экспорт текОбъект = ВыбраннаяСтрока.Родитель.Родитель.Объект; param = ScrptCtrl.Run("PrepareDefParams", текОбъект, ВыбраннаяСтрока.Индекс, ВыбраннаяСтрока.индексКонтекста); If param = -1 Then Попытка Если текОбъект <> СТРОКА_ГЛОБАЛЬНЫЙ_КОНТЕКСТ Тогда текОбъект = Вычислить("текОбъект." + ВыбраннаяСтрока.Наименование + "()"); Иначе текОбъект = Вычислить(ВыбраннаяСтрока.Наименование + "()"); КонецЕсли; //текОбъект = Вычислить("текОбъект." + ВыбраннаяСтрока.Наименование + "()"); вспВычислитьФункциюВСтроке(ВыбраннаяСтрока, текОбъект); Исключение Ошибка = ОписаниеОшибки(); Поз = Найти(Ошибка, "Недостаточно фактических параметров"); ВыбраннаяСтрока.Значение = ?(Поз >0, Сред(Ошибка, Поз), Ошибка); КонецПопытки; Else Попытка pIContext = ScrptCtrl.Run("GetContext", текОбъект, ВыбраннаяСтрока.индексКонтекста); res = Wrap.ImplBase_call(pIContext, ВыбраннаяСтрока.Индекс, ppv, param); текОбъект = ScrptCtrl.Run("RetValueImplBase"); вспВычислитьФункциюВСтроке(ВыбраннаяСтрока, текОбъект); Исключение Ошибка = ОписаниеОшибки(); Стр = "Произошла исключительная ситуация:"; Поз = ?(Найти(Ошибка, Стр) >0, Найти(Ошибка, Стр) + СтрДлина(Стр), 1); ВыбраннаяСтрока.Значение = Сред(Ошибка, Поз); КонецПопытки; EndIf; КонецПроцедуры #КонецЕсли // ================================== ================================== ================================== // // блок кода из "Инструменты разработчика" // // ================================== ================================== ================================== #Если Клиент Тогда // Получает новый экземпляр ком-объекта парсера. // // Параметры: // Нет. // // Возвращаемое значение: // Com-объект, Неопределено. // Функция ПолучитьWinAPI() //Экспорт Если Wrap = "НеИнициализирован" Тогда Wrap = ПолучитьCOMОбъектИзМакета(ИМЯ_КЛАССА_DynamicWrapperX, ИМЯ_КЛАССА_DynamicWrapperX); Если Wrap <> Неопределено Тогда Wrap.Register( "KERNEL32.DLL","Sleep","i=h","f=s"); //Wrap.Register( "KERNEL32.DLL","GetTickCount64","r=l","f=s"); // обычный DynamicWrapper на x86 подключает, а этот - нет Wrap.Register( "KERNEL32.DLL","GetTickCount","r=l","f=s"); Wrap.Register( "KERNEL32.DLL","GetProcessId","i=l","r=l","f=s"); Wrap.Register( "KERNEL32.DLL","GetCurrentProcessId","r=l","f=s"); Wrap.Register( "WINMM.DLL", "timeGetTime", "r=l", "f=s"); Wrap.Register( "WINMM.DLL", "timeBeginPeriod", "i=l", "r=l", "f=s"); Wrap.Register( "WINMM.DLL", "timeEndPeriod", "i=l", "r=l", "f=s"); Иначе // Под пользователем ОС без админских прав сразу после установки через regsvr32 /i компонента не создается почему то. // Нужно перезапускать приложение. Предупреждение("Установлена новая компонента. Сеанс будет перезапущен", 5); ПрекратитьРаботуСистемы(Истина); КонецЕсли; КонецЕсли; Возврат Wrap; КонецФункции // ПолучитьWinAPI() #КонецЕсли Функция ЗарегистрироватьПолучитьCOMОбъект(КлассКомпоненты, ПолноеИмяDll) //Экспорт // Сначала пробуем зарегистрировать для HKLM КоманднаяСтрока = "regsvr32 /s """ + ПолноеИмяDll + """"; //КомандаСистемы(КоманднаяСтрока); ЗапуститьСкрытоеПриложениеИДождатьсяЗавершения(КоманднаяСтрока, , Истина); Попытка Компонента = Новый COMОбъект(КлассКомпоненты); Исключение КонецПопытки; Если Компонента <> Неопределено Тогда Сообщить("Зарегистрирована COM-компонента " + КлассКомпоненты, СтатусСообщения.Информация); Возврат Компонента; КонецЕсли; // Теперь пробуем зарегистрировать для HKCU КоманднаяСтрока = "regsvr32 /s /i""" + ПолноеИмяDll + """"; //КомандаСистемы(КоманднаяСтрока); ЗапуститьСкрытоеПриложениеИДождатьсяЗавершения(КоманднаяСтрока, , Истина); Попытка Компонента = Новый COMОбъект(КлассКомпоненты); Исключение КонецПопытки; Если Компонента <> Неопределено Тогда Сообщить("Зарегистрирована COM-компонента " + КлассКомпоненты, СтатусСообщения.Информация); Возврат Компонента; КонецЕсли; Если ФайлРегистратораКомпонент = Неопределено Тогда ФайлРегистратораКомпонент = Новый Файл(ПолучитьИмяВременногоФайла("exe")); ПолучитьМакет("regsvrex").Записать(ФайлРегистратораКомпонент.ПолноеИмя); КонецЕсли; // Теперь пробуем зарегистрировать для HKCU через сторонний регистратор КоманднаяСтрока = """" + ФайлРегистратораКомпонент.ПолноеИмя + """ /c /s """ + ПолноеИмяDll + """"; //КомандаСистемы(КоманднаяСтрока); ЗапуститьСкрытоеПриложениеИДождатьсяЗавершения(КоманднаяСтрока, , Истина); Попытка Компонента = Новый COMОбъект(КлассКомпоненты); Исключение КонецПопытки; Если Компонента <> Неопределено Тогда Сообщить("Зарегистрирована COM-компонента " + КлассКомпоненты, СтатусСообщения.Информация); Возврат Компонента; КонецЕсли; // Теперь пробуем зарегистрировать для HKCU через сторонний регистратор КоманднаяСтрока = """" + ФайлРегистратораКомпонент.ПолноеИмя + """ /c /s /i """ + ПолноеИмяDll + """"; //КомандаСистемы(КоманднаяСтрока); ЗапуститьСкрытоеПриложениеИДождатьсяЗавершения(КоманднаяСтрока, , Истина); Попытка Компонента = Новый COMОбъект(КлассКомпоненты); Исключение КонецПопытки; Если Компонента <> Неопределено Тогда Сообщить("Зарегистрирована COM-компонента " + КлассКомпоненты, СтатусСообщения.Информация); Возврат Компонента; КонецЕсли; Сообщить("Не удалось зарегистривать COM-компоненту " + КлассКомпоненты + ". Возможно требуются права администратора ОС", СтатусСообщения.Внимание); Возврат Неопределено; КонецФункции // ЗарегистрироватьПолучитьCOMОбъект // Возвращает нужный com-объект. Если компонента не зарегистрирована, то пытается ее сохранить из макета и зарегистрировать. // // Параметры: // Нет. // // Возвращаемое значение: // COM-объект, Неопределено. // Функция ПолучитьCOMОбъектИзМакета(ИмяКомпоненты, КлассКомпоненты, КаталогУстановки = "авто") //Экспорт Попытка Компонента = Новый COMОбъект(КлассКомпоненты); // -- Артур -- 14.09.2011 - вставка в код ИР Если КлассКомпоненты = ИМЯ_КЛАССА_DynamicWrapperX Тогда Попытка л = Компонента.GetIDispatch(Компонента); Возврат Компонента; Исключение //ВызватьИсключение "Зарегистрирована старая версия COM-объекта DynamicWrapperX"; КонецПопытки; КонецЕсли; //Возврат Компонента; // --завершение Исключение КонецПопытки; #Если Клиент Тогда Если КаталогУстановки = "" Тогда Ответ = Вопрос("Для работы данной функции необходимо зарегистрировать //|(необходимы права локального администратора) | COM-компоненту """ + ИмяКомпоненты + """. Выполнить регистрацию?", РежимДиалогаВопрос.ОКОтмена, 30, КодВозвратаДиалога.Отмена); Если Ответ = КодВозвратаДиалога.Отмена Тогда Возврат Неопределено; КонецЕсли; ВыборФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.ВыборКаталога); ВыборФайла.Заголовок = "Укажите папку, куда установить компоненту."; Если Не ВыборФайла.Выбрать() Тогда Возврат Неопределено; КонецЕсли; КаталогУстановки = ВыборФайла.Каталог; ИначеЕсли Нрег(КаталогУстановки) = Нрег("авто") Тогда КаталогУстановки = ПапкаВнешнихКомпонент.ПолноеИмя; КонецЕсли; ФайлКомпоненты = Новый Файл(КаталогУстановки + "\" + ИмяКомпоненты + ".dll"); Если Не ФайлКомпоненты.Существует() Тогда ПолучитьМакет(ИмяКомпоненты).Записать(ФайлКомпоненты.ПолноеИмя); КонецЕсли; Результат = ЗарегистрироватьПолучитьCOMОбъект(КлассКомпоненты, ФайлКомпоненты.ПолноеИмя); #Иначе Результат = Неопределено; #КонецЕсли Возврат Результат; КонецФункции // ПолучитьCOMОбъектИзМакета() // <Описание процедуры> // // Параметры: // <Параметр1> – <Тип.Вид> – <описание параметра> // <продолжение описания параметра>; // ИмяФайлаРезультата – Краткое имя файла, в который будет выведен выходной поток, только в текущем каталоге. // Процедура ЗапуститьСкрытоеПриложениеИДождатьсяЗавершения(Знач СтрокаЗапуска, ТекущийКаталог = "\.", ИспользоватьWSH = Ложь, КраткоеИмяФайлаРезультата = "") //Экспорт #Если Клиент Тогда // Баг платформы здесь будет работать. Во время работы данной строки окно продолжает принимать команды! // WSH не использовать при генерации внешних обработок Если ИспользоватьWSH Тогда #КонецЕсли WshShell.CurrentDirectory = ТекущийКаталог; СтрокаЗапуска = "cmd.exe /c """ + СтрокаЗапуска + """"; Если КраткоеИмяФайлаРезультата <> "" Тогда СтрокаЗапуска = СтрокаЗапуска + " > " + КраткоеИмяФайлаРезультата; СтрокаЗапуска = СтрокаЗапуска + " 2>&1"; //stderr КонецЕсли; Попытка WshShell.Run(СтрокаЗапуска, 0, Истина); Исключение // Для x64 ОС СтрокаЗапуска = "%windir%\Sysnative\" + СтрокаЗапуска; WshShell.Run(СтрокаЗапуска, 0, Истина); КонецПопытки; #Если Клиент Тогда Иначе ПолучитьИсполнительСкрытыхКомандСистемы(); КонечнаяСтрока = ИсполнительСкрытыхКомандСистемы + " /nowindow /wait /silent /D=""" + ТекущийКаталог + """ " + СтрокаЗапуска; ЗапуститьПриложение(КонечнаяСтрока, , Истина); КонецЕсли; #КонецЕсли КонецПроцедуры // ЗапуститьСкрытоеПриложениеИДождатьсяЗавершения() Функция ПолучитьИсполнительСкрытыхКомандСистемы() //Экспорт Если ИсполнительСкрытыхКомандСистемы = Неопределено Тогда ДвоичныеДанные = ПолучитьОбщийМакет("hstart"); ИсполнительСкрытыхКомандСистемы = ПолучитьИмяВременногоФайла("exe"); ДвоичныеДанные.Записать(ИсполнительСкрытыхКомандСистемы); ИсполнительСкрытыхКомандСистемы = """" + ИсполнительСкрытыхКомандСистемы + """"; КонецЕсли; Возврат ИсполнительСкрытыхКомандСистемы; КонецФункции // ================================== ================================== ================================== // // окончание блока кода из "Инструменты разработчика" // // ================================== ================================== ================================== #Если Клиент1 Тогда // основная процедура для юнит-тестирования SnowTest Функция ПолучитьСписокТестов() Экспорт Результат = Я_Тест.Новый_НаборТестов(); Я_Тест.НаборТестов_Добавить(Результат, "Тесты_ПолучитьТаблицуСвойств"); Я_Тест.НаборТестов_Добавить(Результат, "Тесты_ПолучитьТаблицуМетодов"); Я_Тест.НаборТестов_Добавить(Результат, "Тесты_ПолучитьТаблицуСвойств_Глобальный"); Я_Тест.НаборТестов_Добавить(Результат, "Тесты_ПолучитьТаблицуМетодов_Глобальный"); Я_Тест.НаборТестов_Добавить(Результат, "Тесты_СвойствоСуществует"); Я_Тест.НаборТестов_Добавить(Результат, "Тесты_МетодСуществует"); Я_Тест.НаборТестов_Добавить(Результат, "Тесты_СвойствоСуществует_Глобальный"); Я_Тест.НаборТестов_Добавить(Результат, "Тесты_МетодСуществует_Глобальный"); Возврат Результат; КонецФункции // ======================= ======================= ======================= ======================= // // БЛОК ЮНИТ-ТЕСТОВ - сами тесты // // ======================= ======================= ======================= ======================= Процедура Тесты_ПолучитьТаблицуСвойств() Экспорт тестТЗ = Новый ТаблицаЗначений; тестТЗ.Колонки.Добавить("Колонка1"); НоваяСтрока = тестТЗ.Добавить(); таблицаСвойств = ЭтотОбъект.ПолучитьТаблицуСвойств(тестТЗ); артТесты.ПроверитьБольшеИлиРавно(таблицаСвойств.Колонки.Количество(), 5, "таблицаСвойств.Колонки.Количество()"); артТесты.ПроверитьРавенство(таблицаСвойств.Количество(), 2, "таблицаСвойств.Количество()"); артТесты.ПроверитьРавенство(таблицаСвойств[0].Наименование, "Индексы", "таблицаСвойств[0].Наименование"); артТесты.ПроверитьРавенство(таблицаСвойств[1].Наименование, "Колонки", "таблицаСвойств[0].Наименование"); КонецПроцедуры Процедура Тесты_ПолучитьТаблицуМетодов() Экспорт тестТЗ = Новый ТаблицаЗначений; тестТЗ.Колонки.Добавить("Колонка1"); НоваяСтрока = тестТЗ.Добавить(); таблица = ЭтотОбъект.ПолучитьТаблицуМетодов(тестТЗ); артТесты.ПроверитьБольшеИлиРавно(таблица.Колонки.Количество(), 5, "таблица.Колонки.Количество()"); артТесты.ПроверитьРавенство(таблица.Количество(), 19, "таблица.Количество()"); артТесты.ПроверитьРавенство(таблица[0].Наименование, "Вставить", "таблица[0].Наименование"); артТесты.ПроверитьИстину(таблица[0].ЕстьВозвращаемоеЗначение, "таблица[0].ЕстьВозвращаемоеЗначение"); артТесты.ПроверитьРавенство(таблица[0].КоличествоПараметров, 1, "таблица[0].КоличествоПараметров"); артТесты.ПроверитьРавенство(таблица[18].Наименование, "Удалить", "таблица[Последняя].Наименование"); Если Ложь Тогда таблица = Новый ТаблицаЗначений; КонецЕсли; строка = таблица.Найти("Количество", "Наименование"); артТесты.ПроверитьНеравенство(строка, Неопределено, "таблица.НайтиСтроки(Количество, Наименование)"); артТесты.ПроверитьИстину(строка.ЕстьВозвращаемоеЗначение, "строка.ЕстьВозвращаемоеЗначение"); артТесты.ПроверитьРавенство(строка.КоличествоПараметров, 0, "таблица[0].КоличествоПараметров"); КонецПроцедуры Процедура Тесты_ПолучитьТаблицуСвойств_Глобальный() Экспорт таблица = ЭтотОбъект.ПолучитьТаблицуСвойств(Неопределено); артТесты.ПроверитьБольшеИлиРавно(таблица.Колонки.Количество(), 5, "таблица.Колонки.Количество()"); артТесты.ПроверитьБольшеИлиРавно(таблица.Количество(), 10, "таблица.Количество()"); строка = таблица.Найти("SelectRecordType", "Наименование"); артТесты.ПроверитьНеравенство(строка, Неопределено, "таблица.НайтиСтроки(Количество, Наименование)"); //артТесты.ПроверитьРавенство(таблицаСвойств[0].Наименование, "Индексы", "таблицаСвойств[0].Наименование"); //артТесты.ПроверитьРавенство(таблицаСвойств[1].Наименование, "Колонки", "таблицаСвойств[0].Наименование"); КонецПроцедуры Процедура Тесты_ПолучитьТаблицуМетодов_Глобальный() Экспорт таблица = ЭтотОбъект.ПолучитьТаблицуМетодов(Неопределено); артТесты.ПроверитьБольшеИлиРавно(таблица.Колонки.Количество(), 5, "таблица.Колонки.Количество()"); артТесты.ПроверитьБольшеИлиРавно(таблица.Количество(), 30, "таблица.Количество()"); //артТесты.ПроверитьРавенство(таблица[0].Наименование, "Вставить", "таблица[0].Наименование"); //артТесты.ПроверитьИстину(таблица[0].ЕстьВозвращаемоеЗначение, "таблица[0].ЕстьВозвращаемоеЗначение"); //артТесты.ПроверитьРавенство(таблица[0].КоличествоПараметров, 1, "таблица[0].КоличествоПараметров"); //артТесты.ПроверитьРавенство(таблица[18].Наименование, "Удалить", "таблица[Последняя].Наименование"); Если Ложь Тогда таблица = Новый ТаблицаЗначений; КонецЕсли; строка = таблица.Найти("XMLЗначение", "Наименование"); артТесты.ПроверитьНеравенство(строка, Неопределено, "таблица.НайтиСтроки(Количество, Наименование)"); артТесты.ПроверитьИстину(строка.ЕстьВозвращаемоеЗначение, "строка.ЕстьВозвращаемоеЗначение"); артТесты.ПроверитьРавенство(строка.КоличествоПараметров, 2, "таблица[0].КоличествоПараметров"); КонецПроцедуры Процедура Тесты_СвойствоСуществует() Экспорт тестТЗ = Новый ТаблицаЗначений; тестТЗ.Колонки.Добавить("Колонка1"); НоваяСтрока = тестТЗ.Добавить(); существует = ЭтотОбъект.СвойствоСуществует(тестТЗ, "Колонки"); артТесты.ПроверитьИстину(существует, "существует Колонки"); существует = ЭтотОбъект.СвойствоСуществует(тестТЗ, "Колонки1564"); артТесты.ПроверитьЛожь(существует, "существует Колонки1564"); КонецПроцедуры Процедура Тесты_МетодСуществует() Экспорт тестТЗ = Новый ТаблицаЗначений; тестТЗ.Колонки.Добавить("Колонка1"); НоваяСтрока = тестТЗ.Добавить(); существует = ЭтотОбъект.МетодСуществует(тестТЗ, "Количество"); артТесты.ПроверитьИстину(существует, "существует Количество"); существует = ЭтотОбъект.МетодСуществует(тестТЗ, "Количество1564"); артТесты.ПроверитьЛожь(существует, "существует Количество1564"); КонецПроцедуры Процедура Тесты_СвойствоСуществует_Глобальный() Экспорт существует = ЭтотОбъект.СвойствоСуществует(Неопределено, "SelectRecordType"); артТесты.ПроверитьИстину(существует, "существует SelectRecordType"); существует = ЭтотОбъект.СвойствоСуществует(Неопределено, "SelectRecordType1564"); артТесты.ПроверитьЛожь(существует, "существует SelectRecordType1564"); КонецПроцедуры Процедура Тесты_МетодСуществует_Глобальный() Экспорт существует = ЭтотОбъект.МетодСуществует(Неопределено, "XMLЗначение"); артТесты.ПроверитьИстину(существует, "существует XMLЗначение"); существует = ЭтотОбъект.МетодСуществует(Неопределено, "XMLЗначение1564"); артТесты.ПроверитьЛожь(существует, "существует XMLЗначение1564"); КонецПроцедуры // ======================= ======================= ======================= ======================= // // КОНЕЦ БЛОКА ЮНИТ-ТЕСТОВ // // ======================= ======================= ======================= ======================= #КонецЕсли //================================== ИМЯ_КЛАССА_DynamicWrapperX = "DynamicWrapperX"; СТРОКА_ОПИСАНИЕ_МЕТОДА_БЕЗ_ПАРАМЕТРОВ = "<Двойной клик по ячейке>"; СТРОКА_МЕТОДЫ = "Методы"; СТРОКА_СВОЙСТВА = "Свойства"; СТРОКА_ГЛОБАЛЬНЫЙ_КОНТЕКСТ = "ГлобальныйКонтекст"; ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_СВОЙСТВ_И_МЕТОДОВ = 0; ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_СВОЙСТВ = 1; ФЛАГ_ЗАПОЛНЕНИЯ_ПРОВЕРИТЬ_СУЩЕСТВОВАНИЕ_МЕТОДОВ = 2; ФЛАГ_ЗАПОЛНЕНИЯ_ЗАПОЛНИТЬ_СВОЙСТВА = 3; ФЛАГ_ЗАПОЛНЕНИЯ_ЗАПОЛНИТЬ_МЕТОДЫ = 4; #Если Клиент Тогда Инит(); #КонецЕсли