Имя: Пароль:
1C
1С v8
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
Основная теорема систематики: Новые системы плодят новые проблемы.