| 
    
        
     
     | 
    
  | 
v8: Использование сборок .NET в 1С 7.x и 8.x | ☑ | ||
|---|---|---|---|---|
| 
    0
    
        Serginio1    
     28.11.13 
            ✎
    16:13 
 | 
         
        Это продолжение темы 
 
        v8: Объекты Net в IDispatch v8: Вопрос по NetObjectToIDispatch v8: soap:Header выложил статью и файлы http://infostart.ru/public/238584/ Суть статьи использование сборок на примере доступа к вэб сервису  | 
|||
| 
    71
    
        Serginio1    
     03.12.13 
            ✎
    18:33 
 | 
         
        Но я загружаю не через 1С. Завтра попробую через 1С     
         | 
|||
| 
    72
    
        Serginio1    
     03.12.13 
            ✎
    18:34 
 | 
         
        (69) Это для ВК     
         | 
|||
| 
    73
    
        H A D G E H O G s    
     03.12.13 
            ✎
    18:35 
 | 
         
        (69) У меня идея - перехват DllregisterServer.
 
        В нем - включение перехвата работы с реестром, и возврат годного CLSID по ProgID. Но там такая каша с zw(nt) работы с реестром, пока не разобрался.  | 
|||
| 
    74
    
        H A D G E H O G s    
     03.12.13 
            ✎
    18:37 
 | 
         
        (71) Естественно. Comcntlr требует для себя core82.dll
 
        А оно уже загружено при загрузке 1cv8.exe Он получает его handle по имени и видит кривую версию. Фэйл.  | 
|||
| 
    75
    
        Serginio1    
     03.12.13 
            ✎
    18:39 
 | 
         
        (73) Зачем? Посмотри внимательно 62. 
 
        (74) При использовании Win32NativeMethods.LoadLibraryEx(ИмяФайла, IntPtr.Zero, 8); будет грузить библиотеку из директории таком порядке 1.Каталог, заданный в napaмeтре pszDLLPathName. А уже потом из 2.Текущий каталог процесса. 3.Системный каталог Windows. 4.Основной каталог Windows. 5.Каталоги, перечисленные в переменной окружения PATH  | 
|||
| 
    76
    
        Serginio1    
     03.12.13 
            ✎
    18:39 
 | 
         
        Давай сейчас и проверю.     
         | 
|||
| 
    77
    
        H A D G E H O G s    
     03.12.13 
            ✎
    18:40 
 | 
         
        Сколько я мучения провел с этим перехватом dllregisterserver
 
        2 дня убил на то, что обваливался процесс в мертвую при установке перехвата реестра. Оказалось, что 1С выгружала dll, так как в dllregisterserver не всенено записей в реестр и дальше не вызывался dllgetclassobject и не было ссылок на эту dll.  | 
|||
| 
    78
    
        H A D G E H O G s    
     03.12.13 
            ✎
    18:42 
 | 
         
        (75) Зачем? Посмотри внимательно 62.
 
        У меня нет библиотеки типов.  | 
|||
| 
    79
    
        Serginio1    
     03.12.13 
            ✎
    19:03 
 | 
         
        (78) Я про библиотеку типов
 
        Кстати проверил на 1С все грузится Процедура ЗагрузкаComОбъектаБезРегистрацииНажатие(Элемент) // Вставить содержимое обработчика. врап=новый COMОбъект("NetObjectToIDispatch45"); // ФайлСборки=ИмяФайлаСборки;//"d:\MyPrograms\Test\ОбменПоTCPIP\ОбменПоTCPIP\bin\Debug\ОбменПоTCPIP.dll"; ФайлСборки="d:\MyPrograms\Test\ЗагрузкаCOMОбъектаБезРегистрации\ЗагрузкаCOMОбъектаБезРегистрации\bin\Debug\ЗагрузкаCOMОбъектаБезРегистрации.dll"; Сборка=врап.загрузитьСборку(ФайлСборки); ЗагрузкаComОбъекта=Сборка.GetType("ЗагрузкаCOMОбъектаБезРегистрации.ЗагрузкаComОбъекта"); res = ЗагрузкаComОбъекта.ЗагрузитьОбъектПоИнформацииОТипе("c:\Program Files (x86)\1cv8\8.3.3.715\bin\comcntr.dll", "COMConnector"); Сообщить(res.HighBoundDefault); КонецПроцедуры  | 
|||
| 
    80
    
        Serginio1    
     03.12.13 
            ✎
    19:05 
 | 
         
        (78) Но она и без 
 
        public class Win32NativeMethods { [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] public static extern IntPtr LoadLibrary( [MarshalAs(UnmanagedType.LPWStr)] string lpFileName); [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] internal static extern IntPtr LoadLibraryEx(string libFilename, IntPtr reserved, int flags); [DllImport("kernel32.dll", CharSet = CharSet.Ansi)] public static extern IntPtr GetProcAddress( IntPtr hModule, [MarshalAs(UnmanagedType.LPStr)] string lpProcName); public delegate uint DllGetClassObjectDelegate( [MarshalAs(UnmanagedType.LPStruct)] Guid rclsid, [MarshalAs(UnmanagedType.LPStruct)] Guid riid, [MarshalAs(UnmanagedType.IUnknown, IidParameterIndex = 1)] out object pUnknown); [DllImport("oleaut32", CharSet = CharSet.Unicode)] public extern static void LoadTypeLib(string dllFilePath, out UCOMITypeLib typeLibrary); } public class ЗагрузкаComОбъекта { public static object ЗагрузитьОбъект(string ИмяФайла, string clsid) { return ЗагрузитьОбъект(ИмяФайла, new Guid(clsid)); } public static object ЗагрузитьОбъект(string ИмяФайла, Guid clsid) { var module = Win32NativeMethods.LoadLibraryEx(ИмяФайла, IntPtr.Zero, 8); var proc = Win32NativeMethods.GetProcAddress(module, "DllGetClassObject"); var gco = Marshal.GetDelegateForFunctionPointer(proc, typeof(Win32NativeMethods.DllGetClassObjectDelegate)) as Win32NativeMethods.DllGetClassObjectDelegate; object unknown; gco(clsid, typeof(IClassFactory).GUID, out unknown); var factory = unknown as IClassFactory; //var iid = typeof(IFilter).GUID; //var filter = factory.CreateInstance(null, ref iid) as IFilter; var iid = typeof(IDispatch).GUID; return factory.CreateInstance(null, iid); }  | 
|||
| 
    81
    
        Serginio1    
     03.12.13 
            ✎
    19:06 
 | 
         
        (78) А в какой библиотеке у тебя нет информации о типе. Это надо на чистом С++ писать.     
         | 
|||
| 
    82
    
        Serginio1    
     04.12.13 
            ✎
    17:55 
 | 
         
        И добавлен приер загрузки объекта из DLL без регистрации на примере загрузки
 
        Из comcntr.dll класс COMConnector. Для примера когда нужно подключиться к Базе с версией отличной от текущей К сожалению иногда не все методы выполняются. Например ToArray() для List<T> Или методы с параметром типа GUID (сам метод выполняется, но при передаче результата в 1С выдается ошибка «типы не совпадают» ) Для этого добавлен метод public object ВыполнитьМетод(object obj, string ИмяМетода, params object[] args) И вызов из 1С //Ком=ЗагрузкаComОбъекта.ЗагрузитьОбъект(ИмяФайла,стр.Гуид); ошибка типа Ком=Врап.ВыполнитьМетод(ЗагрузкаComОбъекта,"ЗагрузитьОбъект",ИмяФайла,стр.Гуид); // Выполняется без ошибок  | 
|||
| 
    83
    
        Serginio1    
     05.12.13 
            ✎
    12:52 
 | 
         
        Решил поэкспериментировать с ExpandoObject
 
        Понятно, что с типом там работать не получится, а переделывать AutoWrap пока лениво. public static object ПолучитьExpandoObject() { dynamic res = new ExpandoObject(); res.Имя = "Тест ExpandoObject"; res.Число = 456; res.ВСтроку = (Func<string>) (() => res.Имя ); return res; }  | 
|||
| 
    84
    
        Serginio1    
     05.12.13 
            ✎
    12:53 
 | 
         
        И соответственно вызов из 1С 
 
        Процедура ТестExpandoObjectНажатие(Элемент) // Вставить содержимое обработчика. врап=новый COMОбъект("NetObjectToIDispatch45"); //ФайлСборки="d:\MyPrograms\Test\ЗагрузкаCOMОбъектаБезРегистрации\ЗагрузкаCOMОбъектаБезРегистрации\bin\Debug\ЗагрузкаCOMОбъектаБезРегистрации.dll"; ФайлСборки=ИмяФайлаСборки; Сборка=врап.загрузитьСборку(ФайлСборки); ЗагрузкаComОбъекта=Сборка.GetType("ЗагрузкаCOMОбъектаБезРегистрации.ЗагрузкаComОбъекта"); // врап.GetInfoFromObject(ЗагрузкаComОбъекта); Объект=ЗагрузкаComОбъекта.ПолучитьExpandoObject(); // Сообщить(объект.Имя); Для каждого стр Из Объект Цикл Сообщить(""+стр.Key+"="+Стр.Value); КонецЦикла; Для каждого стр Из Врап.ТипКакОбъект(Объект.GetType()).GetInterfaces() Цикл Сообщить(Врап.ТипКакОбъект(Стр).Name); КонецЦикла; Объект=Врап.ПолучитьИнтерфейс(Объект,"IDictionary`2"); Объект.set_Item("Число",5); Сообщить(Объект.get_Item("Имя")); Сообщить(Объект.get_Item("Число")); Объект.set_Item("Имя","Вызов Метода"); Сообщить(Объект.get_Item("ВСтроку").DynamicInvoke()); КонецПроцедуры  | 
|||
| 
    85
    
        Serginio1    
     05.12.13 
            ✎
    12:57 
 | 
         
        Но обнаружилась неприятная для меня новость
 
        При вызове свойства или при Установке свойства Объект.get_Item("Имя")); в InvokeMember( invokeAttr вызывается как GetProperty а вот в параметрах ничего нет. Как такое можно побороть?  | 
|||
| 
    86
    
        Serginio1    
     05.12.13 
            ✎
    12:58 
 | 
         
        Вернее при вызове свойства Объект.Item["Имя"];     
         | 
|||
| 
    87
    
        H A D G E H O G s    
     05.12.13 
            ✎
    13:01 
 | 
         
        (85) Я вот неплохо понимаю в кухне COM, но вот ваши шаманические напевы на C++ вынесли мне мозг. Пишите на Дельфи, пожалуйста :-)     
         | 
|||
| 
    88
    
        Serginio1    
     05.12.13 
            ✎
    13:37 
 | 
         
        (87) Это C#. На манагед Delphi будет тоже самое.
 
        Суть в том что например при вызове такой конструкции Объект.Item[5]=5; Должен вызываться Метод IDispath Invoke c параметрами DISPID_PROPERTYPUT и 2 параметра. А на самом деле вызывается с DISPATCH_PROPERTYGET и вообще без параметров. Если просто вызвать Объект.Item["Имя"]; то параметры (Имя) не передается  | 
|||
| 
    89
    
        Serginio1    
     05.12.13 
            ✎
    13:39 
 | 
         
        (87) Зря ты C# игнорируешь. Подучи. Там после Delphi не так сильно переучиваться, а знание библиотек и устройство Net пригодится.     
         | 
|||
| 
    90
    
        Serginio1    
     05.12.13 
            ✎
    16:51 
 | 
         
        Сделал Исправления связанные с параметрами и событиями
 
        public void ПроверитьНаДоступКПолям(ref System.Reflection.BindingFlags invokeAttr,int КоличествоПараметров) { if (( ( (invokeAttr & BindingFlags.PutDispProperty) == BindingFlags.PutDispProperty) || (invokeAttr.HasFlag(System.Reflection.BindingFlags.PutRefDispProperty)) ) && (КоличествоПараметров == 1)) { invokeAttr = invokeAttr | BindingFlags.SetField; } И после вызова метода нужно снва обернуть параметры // Так как параметры могут изменяться (OUT) и передаются по ссылке // нужно обратно обернуть параметры if (args.Length > 0) { if (args != null && args.Length > 0) { for (int x = 0; x < args.Length; x++) { args[x]=ОбернутьОбъект(args[x]); } } }  | 
|||
| 
    91
    
        H A D G E H O G s    
     08.12.13 
            ✎
    22:02 
 | 
         
        Ищется Serginio1     
         | 
|||
| 
    92
    
        Serginio1    
     09.12.13 
            ✎
    10:11 
 | 
         
        (91) Я Здесь     
         | 
|||
| 
    93
    
        Serginio1    
     09.12.13 
            ✎
    11:05 
 | 
         
        Нашел как использовать конфигурационнын файлы в WCF клиентах в DLL
 
        public object СоздатьКлиентаWCFConfigFile(string ИмяФайла, object TChannel, string endpointConfigurationName, object endpointAddress) { ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap(); fileMap.ExeConfigFilename = ИмяФайла; Configuration newConfiguration = ConfigurationManager.OpenMappedExeConfiguration( fileMap, ConfigurationUserLevel.None); Type ТипКанала=ТипДляСоздатьОбъект(TChannel); Type type= typeof(ConfigurationChannelFactory<>); Type constructed = type.MakeGenericType(ТипКанала); dynamic factory1 = System.Activator.CreateInstance(constructed, endpointConfigurationName, newConfiguration, AutoWrap.ПолучитьРеальныйОбъект(endpointAddress) ); // new ConfigurationChannelFactory<ICalculatorChannel>( // "endpoint1", // newConfiguration, // new EndpointAddress("http://localhost:8000/servicemodelsamples/service")); return AutoWrap.ОбернутьОбъект(factory1.CreateChannel()); }  | 
|||
| 
    94
    
        Serginio1    
     09.12.13 
            ✎
    11:06 
 | 
         
        И вызов из 1С
 
        Процедура ВызовСервисаИспользуяConfigFileНажатие(Элемент) // Вставить содержимое обработчика. врап=новый COMОбъект("NetObjectToIDispatch45"); //Сборка=врап.загрузитьСборку("d:\MyPrograms\Test\NestNet45\NestNet45\bin\Debug\NestNet45.dll"); Сборка=врап.загрузитьСборку(ИмяФайлаСборки); // Можно получить тип и используя сборку, что будет правильным //Сборка GetType("NestNet45.ServiceReference1.MorpherSoapClient"); //Но в данном примере используется поиск в загруженных сборках TChannel=Сборка.GetType("NestNet45.ServiceReference1.MorpherSoap"); ConfigFile=ИмяФайлаСборки+".config"; endpointConfigurationName="MorpherSoap"; endpointAddress=Неопределено; Клиент=врап.СоздатьКлиентаWCFConfigFile(ConfigFile,TChannel,endpointConfigurationName,endpointAddress); // Вызываю метод и вывожу результат рез = Клиент.GetForms("Ваяся Пупкин"); Для каждого стр Из рез Цикл сообщить(стр) КонецЦикла; КонецПроцедуры  | 
|||
| 
    95
    
        H A D G E H O G s    
     09.12.13 
            ✎
    11:33 
 | 
         
        (92) Я готов оплатить ваше время, если вы через team(ammy) покажите, как загружаете comcntrl.dll в 1С. Желательно с включенным отладчиком и списком загруженных в процесс, библиотек. (если такого нет в c# - подойдет и vmmap).     
         | 
|||
| 
    96
    
        Serginio1    
     09.12.13 
            ✎
    11:42 
 | 
         
        (95) А у тебя на Delphi не получается?
 
        Наприаер 62. Там через натив достаточно просто.  | 
|||
| 
    97
    
        Serginio1    
     09.12.13 
            ✎
    11:48 
 | 
         
        Или скачай пример. Там сможешь и сам посмотреть какие библиотеки загружены. Скачиваешь отсюда http://1c.proclub.ru/modules/mydownloads/personal.php?cid=120&lid=9569
 
        проект. Распаковывешь его в куданибуть. Запускаешь РегистрацияКомСервера.exe и выбираешь NetObjetToIDispatch45.dll которая лежит в DLLNetObjetToIDispatch45 Затем запускаешь толстого клиента и ТестNetObjectToIDispatch.epf Выбираешь Имя Файла сборки ФайлыNetObjectToIDispatch\СборкиДляТестов\ЗагрузкаCOMОбъектаБезРегистрации.dll Выбираешь НадписьКаталогОтличнойОтТекущейВерсии1с нужный каталог и жмешь на ЗагрузкаComОбъектаБезРегистрации или ПолучитьИнформациюОКоКлассах  | 
|||
| 
    98
    
        H A D G E H O G s    
     09.12.13 
            ✎
    11:49 
 | 
         
        (96) 
 
        моя ситуация: 1cv8.exe (8.2.18.109) при открытии 1С этот процесс загружает из своей же папки core82.dll (8.2.18.109) Через ВК, через LoadLibraryEx(path,0,8); из другой папки загружаю: comcntr.dll (8.2.17.169) При загрузке, comcntr.dll возбуждает ошибку: "Версия ядра core82.dll (8.2.18.109) отлична от версии comcntr.dll (8.2.17.169)" И это правильно. И это логично.  | 
|||
| 
    99
    
        Serginio1    
     09.12.13 
            ✎
    11:51 
 | 
         
        (98) Еще раз LoadLibraryEx(ИмяФайла, IntPtr.Zero, 8); 
 
        не выдает этой ошибки. И загрузка через TypeLib тоже.  | 
|||
| 
    100
    
        Serginio1    
     09.12.13 
            ✎
    11:53 
 | 
         
        99+ прошу прощения не дочитал до конца. Видно с Net другая ситуация     
         | 
|||
| 
    101
    
        sapphire    
     09.12.13 
            ✎
    12:05 
 | 
         
        (3) что именно ты имеешь ввиду?
 
        ADO DB умеет делать асинхронный запросы. Или ты имеешь ввиду запросы по сети?  | 
|||
| 
    102
    
        sapphire    
     09.12.13 
            ✎
    12:06 
 | 
         
        (87) не надо дельфи     
         | 
|||
| 
    103
    
        Serginio1    
     09.12.13 
            ✎
    12:10 
 | 
         
        (98) Посмотрел vmmap в процессах две библиотеки.     
         | 
|||
| 
    104
    
        H A D G E H O G s    
     09.12.13 
            ✎
    12:17 
 | 
         
        (103) Можно мне подключиться?     
         | 
|||
| 
    105
    
        Serginio1    
     09.12.13 
            ✎
    12:19 
 | 
         
        Давай я тебе скрин куда нибудь выложу.     
         | 
|||
| 
    106
    
        Serginio1    
     09.12.13 
            ✎
    12:24 
 | 
         
        Но я использую в обеих случаях LoadTypeLib
 
        в первом используя загрузку через typeInformation.CreateInstance а во втором случае нахожу GUID и LoadLibraryEx  | 
|||
| 
    107
    
        H A D G E H O G s    
     09.12.13 
            ✎
    12:28 
 | 
         
        (105) Да любой фотохостинг. Но вряд ли мне от этого легче будет.     
         | 
|||
| 
    108
    
        H A D G E H O G s    
     09.12.13 
            ✎
    12:30 
 | 
||||
| 
    109
    
        Serginio1    
     09.12.13 
            ✎
    12:35 
 | 
||||
| 
    110
    
        Serginio1    
     09.12.13 
            ✎
    12:36 
 | 
||||
| 
    111
    
        Serginio1    
     09.12.13 
            ✎
    12:51 
 | 
         
        (108) А почему ты не хочешь скачать разработку?     
         | 
|||
| 
    112
    
        H A D G E H O G s    
     09.12.13 
            ✎
    13:44 
 | 
         
        (109) гхм...
 
        Может это фишка 8.3 Дома вечером попробую. А можно увидеть, какая core82.dll загружена. И одна ли она?  | 
|||
| 
    113
    
        Serginio1    
     09.12.13 
            ✎
    13:53 
 | 
         
        (112)  core82.dll  одна из запускаемой программы     
         | 
|||
| 
    114
    
        Serginio1    
     10.12.13 
            ✎
    17:00 
 | 
         
        (112) http://msdn.microsoft.com/en-us/library/windows/desktop/ms684179.aspx
 
        относительный путь. SetDllDirectory функция может быть использована для изменения пути поиска. Это решение лучше, чем пользоваться SetCurrentDirectory или жесткого кодирования полный путь к DLL. Однако следует помнить, что использование SetDllDirectory эффективно отключает безопасный режим поиска DLL в то время как указанный каталог находится в пути поиска, и это не является потокобезопасным. Если это возможно, то лучше использовать AddDllDirectory изменить путь поиска технологическую умолчанию. Для получения дополнительной информации см. динамически подключаемых библиотек порядок поиска . Windows 7, Windows Server 2008 R2, Windows Vista и Windows Server 2008: LOAD_LIBRARY_SEARCH_ * флаги доступны на системах, которые KB2533623 установленных. Чтобы определить, доступны ли флаги, используйте GetProcAddress , чтобы получить адрес AddDllDirectory , RemoveDllDirectory или SetDefaultDllDirectories функции. Если GetProcAddress успешно, то LOAD_LIBRARY_SEARCH_ * флаги могут быть использованы с LoadLibraryEx.  | 
|||
| 
    115
    
        H A D G E H O G s    
     10.12.13 
            ✎
    17:09 
 | 
         
        (114) Ах тыж елкин кот.
 
        Ну отказывется у меня грузица comcntrl.dll нижней версии в более верхнюю 1cv8.exe. Это в версии 8.2.18.109 и 8.2.16.x Это логично, правильно и понятно. А 8.3 я вчера не смог проверить, ибо сдох дома комп с синим экраном.  | 
|||
| 
    116
    
        Serginio1    
     10.12.13 
            ✎
    17:18 
 | 
         
        (115) Да не логично. Зарегистрируй Regsvr32 нижнюю версию и посмотри что у тебя грузится в процесс     
         | 
|||
| 
    117
    
        Serginio1    
     10.12.13 
            ✎
    17:19 
 | 
||||
| 
    118
    
        H A D G E H O G s    
     10.12.13 
            ✎
    17:23 
 | 
         
        (116) Даже смотреть не надо.
 
        Загрузиться нижняя версия и пошлет меня лесом. И будет права.  | 
|||
| 
    119
    
        H A D G E H O G s    
     10.12.13 
            ✎
    17:24 
 | 
         
        (117) Можно коннект?
 
        Или я сам дам коннект и ты глянешь  | 
|||
| 
    120
    
        H A D G E H O G s    
     10.12.13 
            ✎
    17:24 
 | 
         
        А лучше в аську выйди.     
         | 
|||
| 
    121
    
        Serginio1    
     10.12.13 
            ✎
    17:30 
 | 
         
        Да у меня тим вьювера нет. С админом нужно согласовывать. Лениво.
 
        Сейчас аску поставлю.  | 
|||
| 
    122
    
        H A D G E H O G s    
     10.12.13 
            ✎
    17:32 
 | 
         
        (121) ammy admin
 
        Не требует регистрации.  | 
|||
| 
    123
    
        Serginio1    
     11.12.13 
            ✎
    11:38 
 | 
         
        На 8.3 Все работает. При чем на версию \8.3.2.172\ и ниже ругается на отсутствие DllGetClassObject.
 
        Короче вежзде заменил LoadLibraryEx на LoadLibrary ЗагрузкаComОбъекта.ЗагрузитьБиблиотекуВПроцесс(Путь+"bin\stl83.dll"); ЗагрузкаComОбъекта.ЗагрузитьБиблиотекуВПроцесс(Путь+"bin\core83.dll"); Ком=ЗагрузкаComОбъекта.ЗагрузитьОбъект(ИмяФайла,стр.Гуид); public static void ЗагрузитьБиблиотекуВПроцесс(string ИмяФайла) { // var module = Win32NativeMethods.LoadLibraryEx(ИмяФайла, IntPtr.Zero, 8); var module = Win32NativeMethods.LoadLibrary(ИмяФайла); if (module == IntPtr.Zero) throw new Win32Exception(Marshal.GetLastWin32Error()); } Попробуй на 8.2 на Delphi  | 
|||
| 
    124
    
        H A D G E H O G s    
     11.12.13 
            ✎
    12:24 
 | 
         
        Не все так однозначно, бой еще идет.     
         | 
|||
| 
    125
    
        Serginio1    
     11.12.13 
            ✎
    13:52 
 | 
         
        Прошу извинить меня за дачу ложной информации по поводу возможности подключения к базе, созданной в другой веерсии программы. Впервую очередь у H A D G E H O G s
 
        Веренее comcntr.dll загружается, но вот core83.dll использует текущего процесса. Ошибка была скрыта использованием информации из библиотеки типов. В ней вызов typeInformation.CreateInstance(null, ref IID_IUnknown, out classInstance); приводил к поиску Гуида в реестре и запуск зарегистрированной библиотеки. В 8.3 обратная совместимость с предыдущими версиями. Через COMОбъект("V83.COMConnector") можно подключиться к версии созданоой в более поздней версии.  | 
|||
| 
    126
    
        H A D G E H O G s    
     11.12.13 
            ✎
    14:03 
 | 
         
        (125) Да фигня.
 
        Я уж думал - все, здравый смысл покинул этот мир. Выход - параллельная загрузка полного ядра 1С предыдущей версии (как это делается в не1С процесс при Com.Connect()) и перенаправление в него вызовов.  | 
|||
| 
    127
    
        Serginio1    
     11.12.13 
            ✎
    14:07 
 | 
         
        Но из 7ки загружается
 
        Процедура Подключитьсяк8ке() ИмяФайла="c:\Program Files (x86)\1cv8\8.3.3.715\bin\comcntr.dll"; ИмяФайлаСборки="D:\MyPrograms\Test\ЗагрузкаCOMОбъектаБезРегистрации\ЗагрузкаCOMОбъектаБезРегистрации\bin\Debug\ЗагрузкаCOMОбъектаБезРегистрации.dll"; врап=СоздатьОбъект("NetObjectToIDispatch45"); //ФайлСборки="d:\MyPrograms\Test\ЗагрузкаCOMОбъектаБезРегистрации\ЗагрузкаCOMОбъектаБезРегистрации\bin\Debug\ЗагрузкаCOMОбъектаБезРегистрации.dll"; ФайлСборки=ИмяФайлаСборки; Сборка=врап.загрузитьСборку(ФайлСборки); ЗагрузкаComОбъекта=Сборка.GetType("ЗагрузкаCOMОбъектаБезРегистрации.ЗагрузкаComОбъекта"); //Путь=КаталогПрограммы(); res=ЗагрузкаComОбъекта.ЗагрузитьОбъект(ИмяФайла,"181E893D-73A4-4722-B61D-D604B3D67D47"); Сообщить(res.HighBoundDefault); ком=res.Connect("File=""C:\Тест\ТестоваяБаза"";"); Сообщить(ком.ВнешнееСоединение1.Тест1()); Сообщить(ком.КаталогПрограммы()); Сообщить(Ком.СтрокаСоединенияИнформационнойБазы()); Сообщить(Ком.ПредставлениеПриложения("COMConnection")); КонецПроцедуры при этом выдает c:\Program Files (x86)\1cv8\8.3.3.715\bin\ File="C:\Тест\ТестоваяБаза"; При зарегистрированной C:\Program Files (x86)\1cv8\8.3.4.365\bin\comcntr.dll  | 
|||
| 
    128
    
        H A D G E H O G s    
     11.12.13 
            ✎
    14:09 
 | 
         
        (127) Конечно.
 
        В семерку загружается полноценное ядро из восьмерки. Посмотри список библиотек процесса 1cv7 из восьмерочной папки после вызова ком=res.Connect("File=""C:\Тест\ТестоваяБаза"";"); Все логично.  | 
|||
| 
    129
    
        Serginio1    
     11.12.13 
            ✎
    14:13 
 | 
         
        Но вот в 
 
        Процедура ПодключитьИВывестиИнформацию(ИмяФайла) ИмяФайлаСборки="D:\MyPrograms\Test\ЗагрузкаCOMОбъектаБезРегистрации\ЗагрузкаCOMОбъектаБезРегистрации\bin\Debug\ЗагрузкаCOMОбъектаБезРегистрации.dll"; врап=СоздатьОбъект("NetObjectToIDispatch45"); //ФайлСборки="d:\MyPrograms\Test\ЗагрузкаCOMОбъектаБезРегистрации\ЗагрузкаCOMОбъектаБезРегистрации\bin\Debug\ЗагрузкаCOMОбъектаБезРегистрации.dll"; ФайлСборки=ИмяФайлаСборки; Сборка=врап.загрузитьСборку(ФайлСборки); ЗагрузкаComОбъекта=Сборка.GetType("ЗагрузкаCOMОбъектаБезРегистрации.ЗагрузкаComОбъекта"); //Путь=КаталогПрограммы(); res=ЗагрузкаComОбъекта.ЗагрузитьОбъект(ИмяФайла,"181E893D-73A4-4722-B61D-D604B3D67D47"); Сообщить(res.HighBoundDefault); ком=res.Connect("File=""C:\Тест\ТестоваяБаза"";"); Сообщить(ком.ВнешнееСоединение1.Тест1()); Сообщить(ком.КаталогПрограммы()); Сообщить(Ком.СтрокаСоединенияИнформационнойБазы()); Сообщить(Ком.ПредставлениеПриложения("COMConnection")); КонецПроцедуры // ПодключитьИВывестиИнформацию Процедура Подключитьсяк8ке() ИмяФайла="c:\Program Files (x86)\1cv8\8.3.3.715\bin\comcntr.dll"; ПодключитьИВывестиИнформацию(ИмяФайла); ИмяФайла="c:\Program Files (x86)\1cv8\1cv8\8.3.4.365\bin\comcntr.dll"; ПодключитьИВывестиИнформацию(ИмяФайла); КонецПроцедуры Выдает ошибку "не найден указанный модуль"  | 
|||
| 
    130
    
        Serginio1    
     11.12.13 
            ✎
    14:18 
 | 
         
        Прошу прощения
 
        ком=res.Connect("File=""C:\Тест\ТестоваяБаза"";"); {C:\НОВЫЕОТЧЕТЫ\ТЕСТNETOBJETTOIDISPATCH20.ERT(183)}: V83.COMConnector.1: Версия компоненты 'comcntr' (8.3.4.365) отличается от версии корневого модуля 'core83' (8.3.3.715) То есть она берет уже загруженный core83  | 
|||
| 
    131
    
        Serginio1    
     11.12.13 
            ✎
    14:52 
 | 
         
        Если lpModuleName не включает в себя путь и имеется больше, чем один загруженный модуль с тем же самым базовым именем и расширением, функция извлекает дескриптор модуля, который был загружен сначала.     
         | 
|||
| 
    132
    
        Serginio1    
     13.12.13 
            ✎
    10:49 
 | 
         
        У меня есть еще вопрос. Каким образом 1С обращается к объекту через индексаторы?
 
        Хочу подключить свойства по умолчанию, но мне нужно узнать как 1С обращается через [] Или запращивает интерфейс Который можно вытянуть через QueryInterface или метод который можно выцепить черeз GetIdsOfNames Например как здесь http://delphiworld.narod.ru/base/delphi_and_mapinfo2.html TEvent = class(TInterfacedObject,IUnknown,IDispatch) К сожалению на работе Delphi нет.  | 
|||
| 
    133
    
        Serginio1    
     13.12.13 
            ✎
    11:35 
 | 
         
        Надо понимать, что при обращении к массиву она проверяет на поддежку COMSafeArray, иначе просто обращение к свойсву через GetIdsOfNames     
         | 
|||
| 
    134
    
        Serginio1    
     13.12.13 
            ✎
    12:12 
 | 
         
        COMSafeArray gj по индексатору не дает. Да и ..     
         | 
|||
| 
    135
    
        Serginio1    
     16.12.13 
            ✎
    11:07 
 | 
         
        Вообще можно было бы увеличить функциональность за счет поддержки ExpandoObject. Например http://www.codeproject.com/Articles/461677/Creating-a-dynamic-object-from-XML-using-ExpandoOb
 
        Так же можно расширить за счет использования свойсв-индексаторов у которых сигнатура this[string] о которых можно узнать динамически у типа через GetDefaultMembers(). Но испотлзуя IReflect нужно знать заранее все значения, что бы сгенерить нужный массив PropertyInfo[] GetProperties. Но вот здесьб проблематично. А вот через ВК это уже намного проще. Например http://www.rsdn.ru/forum/dotnet/3471534.1  | 
|||
| 
    136
    
        Serginio1    
     16.12.13 
            ✎
    11:10 
 | 
         
        135+ Но у ВК есть проблемы с перегрузками методов     
         | 
|||
| 
    137
    
        Serginio1    
     16.12.13 
            ✎
    11:26 
 | 
||||
| 
    138
    
        Serginio1    
     17.12.13 
            ✎
    11:54 
 | 
         
        Подправил обертку объектов. Теперь массивы примитивных типов строки, дата, Decimal возвращаются как родные для 1С COMSafeArray.
 
        Для массива объектов нужно отдельно преобразовать через функция ПолучитьSafeArrayИзЭнумератора(Object Массив)  | 
|||
| 
    139
    
        Serginio1    
     17.12.13 
            ✎
    15:52 
 | 
         
        Исправил содержимое папки DLLNetObjetToIDispatch45     
         | 
|||
| 
    140
    
        Serginio1    
     23.12.13 
            ✎
    14:09 
 | 
         
        135 Вообще было бы здорово если можно было бы договориться с 1С, что если не находит свойство для Idispatch через GetIdsOfNames, то передавало по аналогии с запросом Энумератора Invoke c [DISPID=-4] что то типа DISPID=-777 или другие значения для понимания, что вызывается свойства по умолчанию     
         | 
|||
| 
    141
    
        H A D G E H O G s    
     23.12.13 
            ✎
    15:34 
 | 
         
        (140) Было бы здорово, если бы 1С добавили в каждый объект элемента интерфейса - дескриптор Windows. Больше мне от них ничего не нужно.     
         | 
|||
| 
    142
    
        Serginio1    
     23.12.13 
            ✎
    15:43 
 | 
         
        (141) Ну ты их можешь найти, а вот вызвать свойсва индексаторы по другому никак.
 
        Ну и это тоже. Вообще им лучше дать по максимуму возможность расширения за счет сторонних средств.  | 
|||
| 
    143
    
        H A D G E H O G s    
     23.12.13 
            ✎
    15:49 
 | 
         
        (142) Нет. Я их не могу найти. Никак.     
         | 
|||
| 
    144
    
        Serginio1    
     23.12.13 
            ✎
    16:02 
 | 
         
        (143) То есть такие конструкции не работают? Хендл главного окна ты через ВК можешь получить
 
        IntPtr hWnd = Win32Window.FindWindow(null, "Set WLAN Power"); while (hWnd == IntPtr.Zero) { Thread.Sleep(100); hWnd = Win32Window.FindWindow(null, "Set WLAN Power"); } IntPtr gg; IntPtr OKHandle = IntPtr.Zero; IntPtr WLHandle = IntPtr.Zero; IntPtr CancelHandle = IntPtr.Zero; // MessageBox.Show(Win32Window.GetWindowText(hEdit)); gg = Win32Window.GetWindow(hWnd, GW.CHILD).Handle; while (gg != IntPtr.Zero) { if (Win32Window.GetWindowText(gg) == "OK") OKHandle = gg; if (Win32Window.GetWindowText(gg) == "WirelessLAN ON") WLHandle = gg; if (Win32Window.GetWindowText(gg) == "Cancel") CancelHandle = gg; // MessageBox.Show(Win32Window.GetWindowText(gg)); // MessageBox.Show(gg.Text); gg = Win32Window.GetWindow(gg, GW.HWNDNEXT).Handle; // gg = Win32Window.GetWindow(gg, GW.CHILD).Handle; } // MessageBox.Show(isChecked(WLHandle).ToString()); if (isChecked(WLHandle)!=state) { emulPress(WLHandle); emulPress(OKHandle); } else emulPress(CancelHandle); WaitForSingleObject(pi.hProcess, INFINITE);  | 
|||
| 
    145
    
        H A D G E H O G s    
     23.12.13 
            ✎
    16:03 
 | 
         
        (144) Аххх.
 
        Сюрприз, сюрприз. В элементах форм, а также в формах Тонкого клиента нет текста. Пуст.  | 
|||
| 
    146
    
        H A D G E H O G s    
     23.12.13 
            ✎
    16:05 
 | 
         
        Искать в Толстом по заголовку формы - фуфуфу, моветон.
 
        Можно его конечно менять на GUIDСтрока, искать GUIDСтрока, возвращать обратно, но только в отдельном потоке, 1С установить заголовок Windows потом, когда твой код окончиться.  | 
|||
| 
    147
    
        H A D G E H O G s    
     23.12.13 
            ✎
    16:07 
 | 
         
        Вообще что то искать по тексту - моветон. Бррр. Корежит всего. Нельзя по тексту ничего искать.
 
        Я текстам недоверяю еще со времен войны кодировок, когда юникодом в винде и не пахло.  | 
|||
| 
    148
    
        Serginio1    
     23.12.13 
            ✎
    16:18 
 | 
         
        (147) Согласен. При чем ХЭНДЛ окна и AppDispatch можно получить только через ВК. Хотя при появлении событий многие вещи можно делать и из ActiveX.     
         | 
|||
| 
    149
    
        AaNnDdRrEeYy    
     23.12.13 
            ✎
    16:32 
 | 
         
        Когда сборшик мусора уничтожит созданный объект из сборки NET и полученный в 1С? 
 
        Вопрос возник потому что я не видел явного использования интерфейса IDispose. т.е вызова Объект.Dispose() не явно метод вызывается при уничтожении объекта, вот когда происходит это унижтожение?  | 
|||
| 
    150
    
        oleg_km    
     23.12.13 
            ✎
    16:47 
 | 
         
        (149) Как и любой объект без явного вызова Dispose - через какое-то время. Поэтому, если хочу, чтобы был немедленный эффект - сам вызываю Dispose.     
         | 
|||
| 
    151
    
        Serginio1    
     23.12.13 
            ✎
    16:48 
 | 
         
        (149) Если объект использует ресурсы, то лучше сразу закрыть его по окончании использования. Как это сделано для соетов и портов
 
        Процедура ПриЗакрытии() // Вставить содержимое обработчика. Если СерверTCP<>неопределено Тогда СерверTCP.Закрыть(); КонецЕсли; КонецПроцедуры А что касается уничтожения объектов, то GC всю работу сделает сам.  | 
|||
| 
    152
    
        Serginio1    
     23.12.13 
            ✎
    16:50 
 | 
         
        (149) IDispose хорош при использовании конструкции using
 
        . В 1С нужно явно закрывать хэндлы  | 
|||
| 
    153
    
        AaNnDdRrEeYy    
     23.12.13 
            ✎
    17:02 
 | 
         
        (152) есть подозрение что GC не тронет объект пока висит рабочий процесс 1сv8.exe. у мня так было, но не с маршалингом а с обычным ком объектом. воощем сборшик мусора не видит когда 1с его отпускает или 1с его просто не отпускает.     
         | 
|||
| 
    154
    
        Serginio1    
     23.12.13 
            ✎
    17:30 
 | 
         
        (153) Здесь может быть проблема с подсчетом ссылок. Но ты всегда можешь принудительно запустить сборку мусора и посмотреть.
 
        GC.Collect(); // Wait for all finalizers to complete before continuing. // Without this call to GC.WaitForPendingFinalizers, // the worker loop below might execute at the same time // as the finalizers. // With this call, the worker loop executes only after // all finalizers have been called. GC.WaitForPendingFinalizers();  | 
|||
| 
    155
    
        oleg_km    
     23.12.13 
            ✎
    17:37 
 | 
         
        (153) ну счетчик должен нормально работать, когда переменная в 1С утрачивает видимость. А дальше уже сработает сборщик мусора     
         | 
|||
| 
    156
    
        MM    
     23.12.13 
            ✎
    18:39 
 | 
         
        (141) так они оконные ресурсы экономят. У Реймонда Чена написано, что по соображениям совместимости, оконные дескрипторы штука дефицитная, в пределах оконной станции. В 7.7 можно было истратить все дескрипторы запустив 6-7 приложений на компьютере с windows 2000.
 
        (148) Платформа 1С поддерживает массу языков, так что рассчитывать на постоянство текстов окон наивно, как и приводить типы к строке для проверки их значения. (155) так при наличии достаточного количества памяти сборка мусора совсем не обязательна, и системный ресурс (файл, сокет) может долго не освобождаться.  | 
|||
| 
    157
    
        H A D G E H O G s    
     23.12.13 
            ✎
    18:41 
 | 
         
        (156)  так они оконные ресурсы экономят.  Хрень полная.
 
        Каждая надпись, поле ввода - это полноценный элемент окна Windows, имеющий дескриптор, не имеющий текста, с переписанной отрисовкой и перехватом событий.  | 
|||
| 
    158
    
        Serginio1    
     23.12.13 
            ✎
    19:02 
 | 
         
        (156) Я не про тексты. В Net есть Control у которого есть свойство Handle. То есть выдать наружу то, что нужно стороннему разработчику. 
 
        Они пошли по увеличению функциональности, но вот по части интеграции не очень. А можно и Net по максимуму внедрить, и тд.  | 
|||
| 
    159
    
        MM    
     23.12.13 
            ✎
    19:36 
 | 
         
        (157) Посмотрел, точно, видимо недоделали. IE такую технику использует.
 
        (142) А как они это монетизируют? Благотворительность им не свойственна, потому и запрещают всё, что может сэкономить лицензии, особенно инеграцию. Я ошибся отвечал не на (148), а (147).  | 
|||
| 
    160
    
        xReason    
     23.12.13 
            ✎
    19:45 
 | 
         
        в 8.3 использовать .Net - НЕЛЬЗЯ 
 
        Так как решение не полноценное будет  | 
|||
| 
    161
    
        MM    
     23.12.13 
            ✎
    19:48 
 | 
         
        (160) и всё из-за Линукса? Там вроде Mono есть, пусть и без СОМ?     
         | 
|||
| 
    162
    
        xReason    
     23.12.13 
            ✎
    19:56 
 | 
         
        (161) ага, вообще чем дальше, тем больше я понимаю. Что все должно быть внутри 1С , в крайнем случае с использованием кросс-платформеных решений     
         | 
|||
| 
    163
    
        Serginio1    
     23.12.13 
            ✎
    20:24 
 | 
         
        (162) Угу на серверах и клиентах под Win ну никак нельзя использовать?
 
        Опять же есть Java. Просто к нему нужно делать враппер самой 1С .Данная разработка к работает и без участия 1С просто через СОМ. Просто 1С не поддерживает свойства массивы. Кроме всего прочего в C# есть свойства индексаторы, где некая поддержка 1С возможна через вызов Invoke c заранее оговоренным DISPID  | 
|||
| 
    164
    
        Serginio1    
     23.12.13 
            ✎
    20:25 
 | 
         
        (160) А COM тоже нельзя?     
         | 
|||
| 
    165
    
        xReason    
     23.12.13 
            ✎
    20:26 
 | 
         
        (164) как нафиг COM в линуксе или в OSX     
         | 
|||
| 
    166
    
        oleg_km    
     23.12.13 
            ✎
    20:51 
 | 
         
        (164) По крайней мере в 8.3.4 можно. Наверное, нельзя в клиенте, запущеном под Linux     
         | 
|||
| 
    167
    
        xReason    
     23.12.13 
            ✎
    21:07 
 | 
         
        (166) И самое главное также нельзя это сделать на сервере "запущеном под Linux"     
         | 
|||
| 
    168
    
        oleg_km    
     23.12.13 
            ✎
    21:34 
 | 
         
        (167) Каждый может сделать осознанный выбор: или Линукс без .НЕТ или Винда с .НЕТом. Для меня выбор очевиден.     
         | 
|||
| 
    169
    
        Serginio1    
     23.12.13 
            ✎
    21:44 
 | 
         
        (165) Но такая возможность в языке существует и великолепно используется. А вот выбирая линукс и прочие оси ты ССЗБ и знаешь на что идешь уменьшая свой функционал. Любое универсальное решение это удар по объему возможностей. Та же поддержка вэб сервисов в 1С 8.3 далека от идеала итд. Зачем тратить ресурсы на поддержку кросс платформенности, если можно их потратить с умом на другие участки.     
         | 
|||
| 
    170
    
        Serginio1    
     25.12.13 
            ✎
    15:30 
 | 
         
        140 + Вообще для свойств по умолчанию есть DISPID_VALUE
 
        то есть 0. Странно, что 1С этим не пользуется http://www.rsdn.ru/forum/com/4459556.all  | 
| Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |