Имя: Пароль:
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/
Суть статьи использование сборок на примере доступа к вэб сервису
1 Serginio1
 
28.11.13
16:13
Данная разработка создана для использования сборок .Net в 1С через преобразование объектов и классов в COM объекты которые можно использовать в 1С. Достигается это путем создания класса реализующим методы интерфейса IReflect public class AutoWrap : IReflect
Внутри него есть метод который оборачивает объекты не поддерживаемые в 1С в экземпляр класса AutoWrap.
Для облегчения работы с этим классом создан другой класс NetObjectToIDispatch
У него есть следующие методы
public object ПолучитьТип(string type)
Получает тип используя типы загруженных сборок

полученный объект позволяет использовать статические методы класса
и члены перечислений
примеры взятые отсюда v8: Вопрос по NetObjectToIDispatch
v8: soap:Header
и созданные oleg_km
обСокет = Плагин.СоздатьОбъект(Плагин.ПолучитьТип("System.Net.Sockets.Socket", "System"),
        Плагин.ПолучитьТип("System.Net.Sockets.AddressFamily", "System").InterNetwork,
        Плагин.ПолучитьТип("System.Net.Sockets.SocketType", "System").Stream,
        Плагин.ПолучитьТип("System.Net.Sockets.ProtocolType", "System").Tcp);

Но есть один мисус для типа нельзя вызвать методы типа. Для этого существует метод
public object ТипКакОбъект(object Тип)
из которого можно использовать методы и свойства Type (Например AssemblyQualifiedName)
public object СоздатьОбъект(object Тип, params object[] args)

Создает объект по типу или по строке используя параметры которые можно перечислять через запятую. Например
сервер=врап.СоздатьОбъект(тип,парам1,парам2);
public Object ChangeType(string type, object value)
Используя для преобразования типа в нужный тип. В C# используется перегрузка по параметрам. В .Net для чисел много типов, а  1С только один тип.
public object ПолучитьИнтерфейс(object obj, string InterfaseName)
получить интерфейс  объекта.
public object ЗагрузитьСборку(string ПутьКСборке)
загружает сборку и возвращает ссылку на нё.

В Net особенно в WCF активно используются конфигурационные файлы.
Для использования их в 1С можно создать такой файл в директории запускаемой программы под именем ИмяЗапускаемойПрограммы.exe.config например
C:\Program Files (x86)\1Cv77\BIN\1cv7s.exe.config
Или
C:\Program Files (x86)\1cv8\8.3.4.317\bin\1cv8.exe.config

Иногда стоит заменить этот файл на другой. Для этого есть метод
ЗаменитьConfigFile(string имяФайла)
Если имяФайла=”” тогда берется файл typeof(NetObjectToIDispatch45).Assembly.Location + ".config"

Как пример показано программное изменение настроек
УстановитьDefaultProxy()

Другие методы созданы для отладки.

Также заложена возможность использования итераторов в 1С например
рез = сервер.GetForms("Ваяся Пупкин");
Для каждого стр  Из рез Цикл
   сообщить(стр)
КонецЦикла;
Для использования в 1С 7.7 предусмотрено установка УстЭтоСемерка() так как в ней не поддерживается беззнаковые, Decimal и ограничена DateTime без времени.

Приведены примеры для 1С 7.7 и 8.3
Использующие сборку для доступа к Веб Сервису http://www.morpher.ru/WebServices/Morpher.asmx

Использующие загрузку сборок, замену м модификацию конфигурационных файлов.
Вы можете создавать любые сборки или использовать стандартные библиотеки без регистрации.

NestNet45.dll для иестирования 4.5 TestWebServices.dll для тестов 2.0

В папке NetObjetToIDispatch содержатся файлы для доступа к Net 2.0
NetObjetToIDispatch45 соответсвенно к 4.5

Пример для 7.7
Процедура ПодключитьсякМорферЧерез45()
    
    врап=СоздатьОбъект("NetObjectToIDispatch45");
    врап.УстЭтоСемерка();
    // Можно указать место конфигурационного файла
    //    врап.ЗаменитьConfigFile("");
    // Устанавливаю в конфигурацию DefaultProxy
    Если ИспользоватьDefaultProxy=1 Тогда
        
        Сообщить(врап.УстановитьDefaultProxy());
    КонецЕсли;
    
    //Сборка=врап.загрузитьСборку("d:\MyPrograms\Test\NestNet45\NestNet45\bin\Debug\NestNet45.dll");
    // Загружаю сборку содержащую классы и методы доступа в Вэб сервису
    Сборка=врап.загрузитьСборку(ИмяФайла);
    
    // Получаю текущие установки прокси
    прокси=врап.ПолучитьТип("System.Configuration.ConfigurationSettings").GetConfig("system.net/defaultProxy");
    Сообщить("прокси.Enabled="+прокси.Enabled);
    Сообщить("прокси.UseDefaultCredentials="+прокси.UseDefaultCredentials);
    
    
    true=врап.ChangeType("System.Boolean","true");
        
    //Создаю экземляр NestNet45.ServiceReference1.MorpherSoapClient используя BasicHttpBinding
    //и remoteAddress
    типСервера=Сборка.GetType("NestNet45.ServiceReference1.MorpherSoapClient");
    типСервера=врап.ПолучитьТип("NestNet45.ServiceReference1.MorpherSoapClient");
    
    remoteAddress =врап.СоздатьОбъект("System.ServiceModel.EndpointAddress",
    врап.СоздатьОбъект("System.Uri","http://www.morpher.ru/WebServices/Morpher.asmx";));
    привязка = врап.СоздатьОбъект("System.ServiceModel.BasicHttpBinding");

    сервер=врап.СоздатьОбъект(типСервера,привязка,remoteAddress);
    //сервер=врап.СоздатьОбъект(типСервера);
    
    
    // Вызываю метод и вывожу результат
    рез = сервер.GetForms("Ваяся Пупкин");
    
    Для сч=0 по рез.Length-1 Цикл
        Сообщить(рез.GetValue(Инт(сч)));
    КонецЦикла;
    
    врап="";
КонецПроцедуры





Для 83

Процедура ТестВызоваСервисаНажатие(Элемент)
    // Вставить содержимое обработчика.
    врап=новый COMОбъект("NetObjectToIDispatch45");
// Можно использовать внешний конфигурационный фай    
//    врап.ЗаменитьConfigFile("");
Если ИспользоватьDefaultProxy Тогда
Сообщить(врап.УстановитьDefaultProxy());    
КонецЕсли;

//Сборка=врап.загрузитьСборку("d:\MyPrograms\Test\NestNet45\NestNet45\bin\Debug\NestNet45.dll");
Сборка=врап.загрузитьСборку(ИмяФайлаСборки);
// Можно получить тип и используя сборку, что будет правильным
//Сборка GetType("NestNet45.ServiceReference1.MorpherSoapClient");
//Но в данном примере используется поиск в загруженных сборках
типСервера=Сборка.GetType("NestNet45.ServiceReference1.MorpherSoapClient");

типСервера=врап.ПолучитьТип("NestNet45.ServiceReference1.MorpherSoapClient");

//Создаю экземляр NestNet45.ServiceReference1.MorpherSoapClient используя BasicHttpBinding
    //и remoteAddress
    
remoteAddress =врап.СоздатьОбъект("System.ServiceModel.EndpointAddress",
                        врап.СоздатьОбъект("System.Uri","http://www.morpher.ru/WebServices/Morpher.asmx";));
привязка = врап.СоздатьОбъект("System.ServiceModel.BasicHttpBinding");

прокси=врап.ПолучитьТип("System.Configuration.ConfigurationSettings").GetConfig("system.net/defaultProxy");
Сообщить("прокси.Enabled="+прокси.Enabled);
Сообщить("прокси.UseDefaultCredentials="+прокси.UseDefaultCredentials);
сервер=врап.СоздатьОбъект(типСервера,привязка,remoteAddress);



// Вызываю метод и вывожу результат
рез = сервер.GetForms("Ваяся Пупкин");

Для каждого стр  Из рез Цикл
    сообщить(стр)
КонецЦикла;

КонецПроцедуры
2 oleg_km
 
28.11.13
17:33
Молодец, осилил. У меня не хватило пороху.

Докину примеры использования из своей копилки:

// Системные
Процедура Приостановить(ВремяПаузы) Экспорт
    ПолучитьТип("System.Threading.Thread").Sleep(ВремяПаузы);
КонецПроцедуры

Функция ПолучитьКоманднуюСтроку() Экспорт
    Возврат ПолучитьТип("System.Environment").CommandLine;
КонецФункции

Функция ПолучитьТекущийПринтер() Экспорт
    Возврат СоздатьОбъект(ПолучитьТип("System.Drawing.Printing.PrinterSettings", "System.Drawing")).PrinterName;
КонецФункции

Функция ПолучитьТекущийПроцесс() Экспорт
    Возврат ПолучитьТип("System.Diagnostics.Process", "System").GetCurrentProcess().Id;
КонецФункции

Процедура СкопироватьПоток(вхПоток, исхПоток, РазмерПорции = 100000) Экспорт
    Пока Истина Цикл
        мсДанные = СоздатьМассив(ПолучитьТип("System.Byte"), РазмерПорции);
        число = вхПоток.Read(мсДанные, 0, мсДанные.Length);
        Если число = 0 Тогда Прервать; КонецЕсли;
        исхПоток.Write(мсДанные, 0, число);
    КонецЦикла;     
КонецПроцедуры

// Компрессия
Процедура GZIPУпаковать(вхФайл, исхФайл) Экспорт
    УдалитьФайлы(исхФайл);
    
    типФайл         = ПолучитьТип("System.IO.FileStream");
    типРежим         = ПолучитьТип("System.IO.FileMode");
    типДоступ         = ПолучитьТип("System.IO.FileAccess");
    типРазделение     = ПолучитьТип("System.IO.FileShare");
    
    обФайлИсходный     = СоздатьОбъект(типФайл, вхФайл, типРежим.Open, типДоступ.Read, типРазделение.ReadWrite);
    обФайлАрхив        = СоздатьОбъект(типФайл, исхФайл, типРежим.CreateNew, типДоступ.Write);
    обПотокКомпр     = СоздатьОбъект(ПолучитьТип("System.IO.Compression.GZipStream", "System"),
                        обФайлАрхив, ПолучитьТип("System.IO.Compression.CompressionMode", "System").Compress);
                        
    СкопироватьПоток(обФайлИсходный, обПотокКомпр);
    
    обПотокКомпр.Close();
    обФайлАрхив.Close();
    обФайлИсходный.Close();
КонецПроцедуры

Процедура GZIPРаспаковать(вхФайл, исхФайл) Экспорт
    УдалитьФайлы(исхФайл);
    
    типФайл         = ПолучитьТип("System.IO.FileStream");
    типРежим         = ПолучитьТип("System.IO.FileMode");
    типДоступ         = ПолучитьТип("System.IO.FileAccess");
    типРазделение     = ПолучитьТип("System.IO.FileShare");
    
    обФайлАрхив     = СоздатьОбъект(типФайл, вхФайл, типРежим.Open, типДоступ.Read, типРазделение.ReadWrite);
    обФайлНовый        = СоздатьОбъект(типФайл, исхФайл, типРежим.CreateNew, типДоступ.Write);
    обПотокКомпр     = СоздатьОбъект(ПолучитьТип("System.IO.Compression.GZipStream", "System"),
                        обФайлАрхив, ПолучитьТип("System.IO.Compression.CompressionMode", "System").Decompress);
                        
    СкопироватьПоток(обПотокКомпр, обФайлНовый);
    
    обПотокКомпр.Close();
    обФайлАрхив.Close();
    обФайлНовый.Close();
КонецПроцедуры

// Получение хеша
Функция ПолучитьХешСтроки(текСтрока, Провайдер = "MD5") Экспорт
    мсДанные = ПолучитьКодировку().GetBytes(текСтрока);
    Возврат Хеш2Строка(СоздатьКриптоПровайдер(Провайдер).ComputeHash(мсДанные));
КонецФункции

Функция ПолучитьХешФайла(ИмяФайла, Провайдер = "MD5") Экспорт
    обФайл = СоздатьОбъект(ПолучитьТип("System.IO.FileStream"), ИмяФайла,
        ПолучитьТип("System.IO.FileMode").Open,
        ПолучитьТип("System.IO.FileAccess").Read,
        ПолучитьТип("System.IO.FileShare").ReadWrite);
        
    Рез = Хеш2Строка(СоздатьКриптоПровайдер(Провайдер).ComputeHash(обФайл));
    обФайл.Close();
        
    Возврат Рез;
КонецФункции

Функция СоздатьКриптоПровайдер(Провайдер)
//SHA                                        SHA1CryptoServiceProvider
//SHA1                                       SHA1CryptoServiceProvider
//System.Security.Cryptography.SHA1          SHA1CryptoServiceProvider
//System.Security.Cryptography.HashAlgorithm SHA1CryptoServiceProvider
//MD5                                        MD5CryptoServiceProvider
//System.Security.Cryptography.MD5           MD5CryptoServiceProvider
//SHA256                                     SHA256Managed
//SHA-256                                    SHA256Managed
//System.Security.Cryptography.SHA256        SHA256Managed
//SHA384                                     SHA384Managed
//SHA-384                                    SHA384Managed
//System.Security.Cryptography.SHA384        SHA384Managed
//SHA512                                     SHA512Managed
//SHA-512                                    SHA512Managed
//System.Security.Cryptography.SHA512        SHA512Managed
    
    КлючПровайдера = "Hash_" + Провайдер;
    обПровайдер = КешОбъектов[КлючПровайдера];
    
    Если обПровайдер = Неопределено Тогда
        обПровайдер = ПолучитьТип("System.Security.Cryptography.HashAlgorithm").Create(Провайдер);
        КешОбъектов.Вставить(КлючПровайдера, обПровайдер);
    КонецЕсли;
    
    Возврат обПровайдер;
КонецФункции

Функция Хеш2Строка(мсХеш)
    стрРез = СоздатьОбъект(ПолучитьТип("System.Text.StringBuilder"), мсХеш.Length * 2);
    Для ии = 0 По мсХеш.Length - 1 Цикл
        стрРез.AppendFormat("{0:X2}", мсХеш.GetValue(ии));
    КонецЦикла;
    Возврат СокрЛП(стрРез.ToString());
КонецФункции
3 Asmody
 
28.11.13
17:39
фигня. вот кто бы научил 1Ску ассинхронным запросам…
4 H A D G E H O G s
 
28.11.13
17:40
Вы нереально круты, круче только яйца.

Получите мне простенькую командную строку стороннего приложения, например outlook.exe в моей win64 - тому мое респект и уважуха.
5 H A D G E H O G s
 
28.11.13
17:40
(3) пфффф
6 Asmody
 
28.11.13
17:40
(5) что "пфффф"?
7 H A D G E H O G s
 
28.11.13
17:43
(6) Я делал это. Правда не с запросом, а с множественными вычислениями. Но думаю, и запрос потянет. Надо проверить.
8 oleg_km
 
28.11.13
17:46
(3) Ну прямые асинхронные SQL запросы посредством дот.нет вполне доступны. А 1Сные с применением сокетов возможны посредством фоновых заданий. Просто с использованием дот.нета я бы выпилил из 1С всю эту шелуху, типа ИнтернетСоединение, ИнтернетПочта, всякие там вебсервисы, географические схемы и прочие наколенные поделки, регулярно неработающие и всегда не до конца реализаованные, а главное через три года, как оно было нужно и уже было в дот.нете. Еще бы как-нибудь это удалить из СП чтобы не мешалось. Я для себя оставил прикладные объекты: справочники, документы, регистры, перечисления и пр. И сразу легче задышалось
9 Asmody
 
28.11.13
17:47
(7) под "запросом" я имел ввиду не только те запросы, которые в 1С, хотя и их тоже, а вообще. те же запросы к внешним веб-сервисам
10 Asmody
 
28.11.13
17:47
(8) с дот.нетом тебе 1С не мешает?
11 H A D G E H O G s
 
28.11.13
17:48
(8) Это все круто, нереально круто. Давно выпилить этот, как ты сказал, нерабочий мусор, согласен на все 100, вот только как реализуешь (4).
12 H A D G E H O G s
 
28.11.13
17:51
(9) Внешние веб-сервисы? Не, не слышал.
13 oleg_km
 
28.11.13
17:51
(4) Не совсем понял найти outlook. Именно файл outlook.exe или скажем текущий почтовый клиент по-умолчанию. Первое реализуется средствами самого 1С, делаешь рекурсивный обход всех каталогов. Второе естественно через поиск по регистру можно сделать через это поделие

(9) Асинхронную работу этим компонентом сделать не получается, т.к. не понятно как туда прикрутить делегаты. Может в поделке Elisy это реализовано, там вроде как целые куски кода на шарпе можно запускать
14 oleg_km
 
28.11.13
17:57
Вон очередной мученик давится кактусом:

v8: Как правильно передать данные по https ?
15 H A D G E H O G s
 
28.11.13
17:57
(13) Командную строку, с помощью которой запущен вот этот вот работающий процесс outlook.exe с PID 1232
16 oleg_km
 
28.11.13
18:05
(15) ну у меня это еще через WMI сделано, но можно и через дот.нет. Непричесанный пример (списаок всех процессов на компьютере ОС_Наименование):

    тзПроцессы = Новый ТаблицаЗначений;
    тзПроцессы.Колонки.Добавить("Программа", Новый ОписаниеТипов("Строка"));
    тзПроцессы.Колонки.Добавить("Домен", Новый ОписаниеТипов("Строка"));
    тзПроцессы.Колонки.Добавить("Пользователь", Новый ОписаниеТипов("Строка"));
    тзПроцессы.Колонки.Добавить("Путь", Новый ОписаниеТипов("Строка"));
    тзПроцессы.Колонки.Добавить("Память", Новый ОписаниеТипов("Число"));
    тзПроцессы.Колонки.Добавить("ДатаЗапуска", Новый ОписаниеТипов("Дата"));
    тзПроцессы.Колонки.Добавить("ВремяЯдра", Новый ОписаниеТипов("Строка"));
    тзПроцессы.Колонки.Добавить("ВремяПользователя", Новый ОписаниеТипов("Строка"));
    тзПроцессы.Колонки.Добавить("Прочитано", Новый ОписаниеТипов("Число"));
    тзПроцессы.Колонки.Добавить("Записано", Новый ОписаниеТипов("Число"));
    тзПроцессы.Колонки.Добавить("ИДПроцесса", Новый ОписаниеТипов("Число"));
    тзПроцессы.Колонки.Добавить("ИДСессии", Новый ОписаниеТипов("Число"));
    
    обПроцессы = ПолучитьCOMОбъект("winmgmts:{impersonationLevel=impersonate}!\\" +
        ОС_Наименование + "\root\cimv2").ExecQuery("Select * from Win32_Process");

    Для каждого текПроцесс Из обПроцессы Цикл
        новПроцесс = тзПроцессы.Добавить();
        новПроцесс.Программа = текПроцесс.Caption;
        Попытка                                                      
            новПроцесс.Путь = текПроцесс.CommandLine;
        Исключение
        КонецПопытки;
        Если ЗначениеЗаполнено(текПроцесс.CreationDate) Тогда
            новПроцесс.ДатаЗапуска = Дата(Лев(текПроцесс.CreationDate, 14));
        КонецЕсли;
        новПроцесс.ВремяЯдра = БиблАП.Время2Строка(Цел(текПроцесс.KernelModeTime/10000000));
        новПроцесс.ВремяПользователя = БиблАП.Время2Строка(Цел(текПроцесс.UserModeTime/10000000));
        новПроцесс.ИДПроцесса = текПроцесс.ProcessId;
        новПроцесс.ИДСессии = текПроцесс.SessionId;
        новПроцесс.Память = текПроцесс.WorkingSetSize;
        новПроцесс.Прочитано = текПроцесс.ReadTransferCount;
        новПроцесс.Записано = текПроцесс.WriteTransferCount;
        
        Попытка
            текПроцесс.GetOwner(новПроцесс.Пользователь, новПроцесс.Домен);
        Исключение
        КонецПопытки;
    КонецЦикла;
    
    тзПроцессы.Сортировать("Домен, Пользователь, Программа");
    ДополнительныеСвойства.Вставить("РезультатПроцессы", тзПроцессы);
17 Serginio1
 
28.11.13
18:22
(2)Блин не думал, что народ подойдет.
Я сделал больше для использования загрузки сборок. И поэксперементировал с конфиг файлом.
18 Serginio1
 
28.11.13
18:25
(4) Что типа такого
System.Diagnostics.Process p = new System.Diagnostics.Process();
                //    p.EnableRaisingEvents = false;
                //    p.StartInfo.CreateNoWindow = false;
                p.StartInfo.FileName = ИмяФайла;
                p.StartInfo.Arguments = КоманднаяСтрока; //(Аргументы командной строки)
                p.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
                p.Start();
                p.WaitForExit();
            }
19 Serginio1
 
28.11.13
18:40
(4)

Процедура ЗапуститьOutlookНажатие(Элемент)
     ИмяФайла="c:\Program Files (x86)\Microsoft Office\Office12\Outlook.exe";
     КоманднаяСтрока="";
     // Вставить содержимое обработчика.
     врап=новый COMОбъект("NetObjectToIDispatch45");
     //System.Diagnostics.Process
     p = врап.СоздатьОбъект("System.Diagnostics.Process");
                //    p.EnableRaisingEvents = false;

                //    p.StartInfo.CreateNoWindow = false;

                p.StartInfo.FileName = ИмяФайла;
                p.StartInfo.Arguments = КоманднаяСтрока; //(Аргументы командной строки)

                p.StartInfo.WindowStyle = врап.ПолучитьТип("System.Diagnostics.ProcessWindowStyle").Normal;
                p.Start();
              //  p.WaitForExit();
    

КонецПроцедуры
20 Serginio1
 
28.11.13
19:04
(9) А это как раз легко решить через внешние сборки. Там ассинхронность уже заложена. И как правило такие сборки даются ввиде примеров создателями веб сервисов
21 Serginio1
 
29.11.13
10:26
(13) Для работы с событиями тебе так или иначе нужно сделать сборку. Динамически или статически. Проще написать сборку хранить её в бд. Сохранять и загружать на клиенте.
При это использовать все возможности RADостей.
Сейчас кстати события прикручу, что бы можно было использовать ДобавитьОбработчик
22 MM
 
29.11.13
11:16
(2) А что это за функции ПолучитьТип, СоздатьОбъект и СоздатьМассив, которые не являются методами.
(21) ДобавитьОбработчик и УдалитьОбработчик это будет кстати. А можно проект с инфостарта куда-нибудь в более удобное для загрузки место перенести.
23 oleg_km
 
29.11.13
11:46
(22) У меня свой компонент, переделанный из компонента Serginio1. Просто привел как пример полезных функций дот.нета

(21) А обработчики к чему прикручиваются?

Сохранять и загружать на клиенте.
А сборки на клиенте можно использовать без регистрации РегАсмом, а то у пользователей прав администратора нет
24 Serginio1
 
29.11.13
12:11
(22) На проф клуб собираюсь.
(23) Хочу просто сделать обертку к нетовским событиям через Com обертку. Пока не получается
http://support.microsoft.com/kb/313891
25 oleg_km
 
29.11.13
12:18
(24) Не очень ориентируюсь в нетовской терминологии: нетовские события это случаем не делегаты?
26 oleg_km
 
29.11.13
12:20
(24) http://support.microsoft.com/kb/313891
Вот, если бы это сделать универсальным, чтобы описывать со стороны 1С
27 MM
 
29.11.13
12:23
(23) и этот компонент размещает свои методы в пространстве имён 1С или это функции обёртки в 1С, для удобства?
28 oleg_km
 
29.11.13
12:28
(27) Да, у меня еще есть обработка-обертка на этим компонентом. Мне так удобне, работает подсказка, это немножно база знаний, один раз полученные типы и сборки кешируются в соответствии. У меня даже уже много оберток: работа с графикой GDI+, сокетами, HTTP, прямые SQL-запросы.
29 Serginio1
 
29.11.13
12:43
(26) Уже сделал
   [ComVisible(true)]
    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    [Guid("33B45C9D-1AED-41F9-8880-36AB6AE84749")]
    public interface IEventFor1C
    {
        [DispId(0x60020000)]
        void Событие();
    }

  

    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.AutoDual)]
    [Guid("62F8156C-13B9-4484-B152-82023243E1D3")]
    [ComSourceInterfaces(typeof(IEventFor1C))]
    public class ClassForEvent1C : System.Windows.Forms.UserControl
    {
        [ComVisible(false)]
        public delegate void Событие_Delgate();

        public object ЗначениеСобытия;//{get;set;}
        public ClassForEvent1C()
        {
            ЗначениеСобытия = "Тестовая Строка";
        
        }
        public event Событие_Delgate Событие;

      
       public string GetText()
        {
            ЗначениеСобытия = AutoWrap.ОбернутьОбъект("Привет из Класса для событий");
            if (this.Событие != null) Событие();
            return "Эта процедура вызвала Событие";
        }

    


    }

(26) А смысл? Все равно городить сборку так или иначе. И мучится без RAD. Я все равно сначала пишу в студии, а затем переношу в 1С
30 Serginio1
 
29.11.13
12:45
29+

Перем ОбъектССобытием;

Процедура ТестСобытияНажатие(Элемент)
     // Вставить содержимое обработчика.
      врап=новый COMОбъект("NetObjectToIDispatch45");
      ОбъектССобытием=врап.ПолучитьОбъектДляСобытий();
      Сообщить(ОбъектССобытием);
      Сообщить("ЗначениеСобытия="+ОбъектССобытием.ЗначениеСобытия);
//      p = врап.СоздатьОбъект("System.Diagnostics.Process");
//      ДобавитьОбработчик p.Событие, ПриИзмененииДокумента;

      ДобавитьОбработчик ОбъектССобытием.Событие, ПриИзмененииДокумента;

      Сообщить(ОбъектССобытием.GetText());
  КонецПроцедуры
  
    Процедура ПриИзмененииДокумента()
      Сообщить(ОбъектССобытием.ЗначениеСобытия);
  КонецПроцедуры
31 Serginio1
 
29.11.13
12:46
И вот сообщения
COMОбъект
ЗначениеСобытия=Тестовая Строка
Привет из Класса для событий
Эта процедура вызвала Событие
32 Serginio1
 
29.11.13
12:47
Сейчас напишу обертку к событию Net, которое будет подключатся к событию объекта и передавать его в 1С
33 Serginio1
 
29.11.13
12:58
Добавил
[DispId(0x60020001)]
        void СобытиеСПараметром(object value);

и вызов
ДобавитьОбработчик ОбъектССобытием.СобытиеСПараметром, ПриИзмененииДокументаСПараметром;

  Процедура ПриИзмененииДокументаСПараметром(Парам)
      Сообщить(парам);
  КонецПроцедуры


Но в принципе достаточно события без параметров, а результат передавать в ЗначениеСобытия
34 MM
 
29.11.13
13:06
(33) А как в 1С получать события из системных сборок или без исходного кода? Будет переходник?
35 Serginio1
 
29.11.13
13:31
(34) Да нужно написать сборку в которой нужно создать классы которые будут предоставлять делегаты для событий. А внутри класса создать событие которое будет вызыватся в делегате.
Сомовская обертка будет над этим классом. Внутри будет через рефлексию GetEvent подключаться к событию
AddEventHandler передавать метод внутри кторого будут запоминаться данные для 1С и передаваться события.

Кстати какие системные события интересуют. Сейчас как раз и хочу написать пример. Желательно с вызовом в отдельном потоке для синхронизации
36 Serginio1
 
29.11.13
15:02
Сделал Класс обертку
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Threading;
using System.Reflection;

namespace NetObjectToIDispatch45
{

  
    [ComVisible(true)]
    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    [Guid("33B45C9D-1AED-41F9-8880-36AB6AE84749")]
    public interface IEventFor1C
    {
        [DispId(0x60020000)]
        void Событие();

        [DispId(0x60020001)]
        void СобытиеСПараметром(object value);
    }

  

    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.AutoDual)]
    [Guid("62F8156C-13B9-4484-B152-82023243E1D3")]
    [ComSourceInterfaces(typeof(IEventFor1C))]
    public class ClassForEvent1C : System.Windows.Forms.UserControl
    {
        [ComVisible(false)]
        public delegate void Событие_Delgate();
        public delegate void СобытиеСПараметром_Delgate(object value);
        public object Объект;
        private SynchronizationContext Sc;

        public object ЗначениеСобытия;//{get;set;}
        public ClassForEvent1C(object Объект,String СобытиеОбъекта)
        {
            this.Объект = Объект;
            BindingFlags bf = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
            EventInfo ei = Объект.GetType().GetEvent(СобытиеОбъекта, bf);
            ei.AddEventHandler(Объект, new System.Action(ВнешнееСобытие));

            SynchronizationContext.SetSynchronizationContext(new WindowsFormsSynchronizationContext());
            Sc = SynchronizationContext.Current;

        }
        public event Событие_Delgate Событие;
        public event СобытиеСПараметром_Delgate СобытиеСПараметром;
      
        private void ВнешнееСобытие()
        {
          if (this.Событие != null) //Событие();
              Sc.Send(d => Событие(), null);

        
        }
       public string GetText()
        {
            ЗначениеСобытия = AutoWrap.ОбернутьОбъект("Привет из Класса для событий");
            if (this.Событие != null) Событие();

            if (this.СобытиеСПараметром != null) СобытиеСПараметром("Вызов события с Параметром");

            return "Эта процедура вызвала Событие";
        }

    


    }

}
37 Serginio1
 
29.11.13
15:04
Сделал Тестовую сборку
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Security.Permissions;


namespace ПроектИспользованияДелегатов
{
    public class КлассДляВнешнихСобытий
    {
        public string ИзмененныйФайл;
        public string ПереименованныйФайл;
        public event System.Action Событие;
        public event System.Action СобытиеПереименованияФайла;
  

        private  void ИзмененияВДиректории(object source, FileSystemEventArgs e)
        {
            // Specify what is done when a file is changed, created, or deleted.
            ИзмененныйФайл = e.FullPath + " " + e.ChangeType;
            if (this.Событие != null) Событие();
    
        }

        public КлассДляВнешнихСобытий(string Директория)
        {
            FileSystemWatcher watcher = new FileSystemWatcher();
            watcher.Path = Директория;
            /* Watch for changes in LastAccess and LastWrite times, and
               the renaming of files or directories. */
            watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
               | NotifyFilters.FileName | NotifyFilters.DirectoryName;
            // Only watch text files.
            watcher.Filter = "*.txt";

            // Add event handlers.
            watcher.Changed += new FileSystemEventHandler(ИзмененияВДиректории);
            watcher.Created += new FileSystemEventHandler(ИзмененияВДиректории);
            watcher.Deleted += new FileSystemEventHandler(ИзмененияВДиректории);
            watcher.Renamed += new RenamedEventHandler(OnRenamed);

            // Begin watching.
            watcher.EnableRaisingEvents = true;


        
        }

        private  void OnRenamed(object source, RenamedEventArgs e)
    {
        // Specify what is done when a file is renamed.
        Console.WriteLine("File: {0} renamed to {1}", e.OldFullPath, e.FullPath);
        ПереименованныйФайл = string.Format("File: {0} renamed to {1}", e.OldFullPath, e.FullPath);
        if (this.СобытиеПереименованияФайла != null) СобытиеПереименованияФайла();
    }

    }
}
38 Serginio1
 
29.11.13
15:06
И вызов из 1С

ОбъектССобытием
Процедура ТестСобытияНажатие(Элемент)

врап=новый COMОбъект("NetObjectToIDispatch45");
Сборка=врап.загрузитьСборку("d:\MyPrograms\Test\ПроектИспользованияДелегатов\ПроектИспользованияДелегатов\bin\Debug\ПроектИспользованияДелегатов.dll");
тип=Сборка.GetType("ПроектИспользованияДелегатов.КлассДляВнешнихСобытий");

ОбъектССобытием=врап.СоздатьОбъект(Тип,"c:\Тест\");
Событие=Врап.ПолучитьОбъектДляСобытий(ОбъектССобытием,"Событие");
СобытиеПереименования=Врап.ПолучитьОбъектДляСобытий(ОбъектССобытием,"СобытиеПереименованияФайла");

ДобавитьОбработчик Событие.Событие, ПриИзмененииДиректории;
ДобавитьОбработчик СобытиеПереименования.Событие, ПриПереименованииФайла;

  КонецПроцедуры
  
  Процедура ПриИзмененииДиректории()
      Сообщить(ОбъектССобытием.ИзмененныйФайл);
  КонецПроцедуры
  
  Процедура ПриПереименованииФайла()
      Сообщить(ОбъектССобытием.ПереименованныйФайл);
  КонецПроцедуры


Работает только почемуто при изменении срабатывает два раза.
39 oleg_km
 
29.11.13
15:13
А если приходится делать отдельную сборку, почему бы ее саму не сделать как КОМ и пользовать без всяких оберток? Ну возвращаемые объекты оборачивать в AutoWrap и все.
40 Serginio1
 
29.11.13
15:48
Так её регистрировать надо. Опять же AutoWrap добавлять. Намного больше действий
41 Serginio1
 
29.11.13
15:49
Добавил файлы и описание
http://1c.proclub.ru/modules/mydownloads/personal.php?cid=120&lid=9569
42 Serginio1
 
29.11.13
16:00
40+ Я кстати начал использовать ради доступа к Вэб сервисам.
А там куча типов и замучаешься каждый тип описывать.
А используя AutoWrap все становится элементарно.

Модераторам. Можно ссылочку в 41 перенести в Шапку?
43 oleg_km
 
29.11.13
16:08
Еще есть вопрос. Вот этот класс:

public class EnumVariantImpl : IEnumVARIANT

и соответственно этот код:

if (name == "[DISPID=-4]")
{
return new EnumVariantImpl(((IEnumerable)O).GetEnumerator());
}

Это же как я понимаю должны превращать коллекции НЕТ в пригодные для Для каждого 1С? У меня почему то конструкция Для каждого с коллекциями дот.нет не работает. Можно маленький пример, где это у тебя работает?
44 Serginio1
 
29.11.13
16:13
Это для Энумераторв для использования
Для каждого стр  Из рез Цикл
45 Serginio1
 
29.11.13
16:15
У меня работает все. Например даже из v8: Объекты Net в IDispatch
рез=мд5.ComputeHash(типЭнкодинг.Default.GetBytes("Строка"));
    для каждого стр из рез Цикл
        Сообщить(стр);
        КонецЦикла;
46 oleg_km
 
29.11.13
17:33
(46) Я тоже так думаю, но у меня почему-то не работает. У тебя именно в восьмерке работает или они одинаково коллекции "раскручивают"?
47 Serginio1
 
29.11.13
17:37
(46) А только в 8 ке есть
для каждого
в 7.7 только через индексы.
А посмотри в отладчике, что передается при  
для каждого стр из рез Цикл

Скачай мои примеры из 41
48 oleg_km
 
29.11.13
17:42
(47) Индексы тоже не работают
49 Serginio1
 
29.11.13
17:44
(48) То есть 45 у тебя не идет? А мои примеры?
50 Serginio1
 
29.11.13
17:46
(48) Индексы нужно к Int32 приводить.
Из-за перегрузки методов не работают. Поэтому я и сделал
public Object ChangeType(string type, object value)
        {

            if (value is AutoWrap)
                value = ((AutoWrap)value).O;

            Type result = НайтиТип(type);//Type.GetType(type, false);
            if (result == null)
                throw new Exception("Не найден тип " + type);

            return new AutoWrap(Convert.ChangeType(value, result, CultureInfo.InvariantCulture));

        }
51 Serginio1
 
29.11.13
17:48
Функция Инт(стр)
    возврат врап.ToInt(Строка(стр));
    
КонецФункции // Децимал

рез = сервер.GetForms("Ваяся Пупкин");
    
    Для сч=0 по рез.Length-1 Цикл
        Сообщить(рез.GetValue(Инт(сч)));
    КонецЦикла;
52 oleg_km
 
29.11.13
17:53
(51) Как раз GetValue прекрасно работает, а вот как в (45) не получается. Я немножко AutoWrap переделал, может что-то там сбилось.
53 Serginio1
 
29.11.13
17:54
(52) Скорее всего. Посмотри мои примеры
54 Serginio1
 
02.12.13
18:35
Также добавлена возможность использования  внешних событий в 1С, в том числе примеры обмена сообщениями по TCP/IP и Работа со сканером ШК
55 Serginio1
 
02.12.13
18:36
Пример использования на сервере

Функция СоздатьСерверTCP(Врап)
      
      Если ЗначениеЗаполнено(ИмяФайлаСборки) Тогда
      предупреждение("Не выбрано Имя Файла Сборки");
          
      
      КонецЕсли;
      
      
       врап=новый COMОбъект("NetObjectToIDispatch45");
ФайлСборки=ИмяФайлаСборки;//"d:\MyPrograms\Test\ОбменПоTCPIP\ОбменПоTCPIP\bin\Debug\ОбменПоTCPIP.dll";
Сборка=врап.загрузитьСборку(ФайлСборки); //ПроектИспользованияДелегатов.dll
тип=Сборка.GetType("TCPConnectTo1C.TCPConnector");

СерверTCP=врап.СоздатьОбъект(Тип);
возврат   СерверTCP
  
  КонецФункции // СоздатьTCP()
  
  Процедура ЗапуститьСерверTCPIPНажатие(Элемент)
      // Вставить содержимое обработчика.
      перем Врап;
СерверTCP=СоздатьСерверTCP(Врап);

  Событие=Врап.ПолучитьОбъектДляСобытийСПараметром(СерверTCP,"ПришлоСообщениеПоTCP");

ДобавитьОбработчик Событие.СобытиеСПараметром, ПолучениеДанныхПоTCP;
СерверTCP.ОткрытьАйПиПортСНомеромПорта(6891);

ЭлементыФормы.ОтправитьКоманду.Видимость=ложь;

КонецПроцедуры

Процедура ПолучениеДанныхПоTCP(Данные)
Сообщить("Команда="+Данные.Команда);
Сообщить("Данные="+Данные.Данные);
Сообщить("ЕстьОтвет="+Данные.ЕстьОтвет);    

Если Данные.ЕстьОтвет Тогда
Ответ="Ответ на команду "+Данные.Команда+"
|Данные "+Данные.Данные+"
|ВремяНаСервере="+XmlСтрока(ТекущаяДата());
СерверTCP.Ответить(Ответ);
    

КонецЕсли;

КонецПроцедуры
56 Serginio1
 
02.12.13
18:37
На Клиенте

Процедура ОтправитьКомандуНажатие(Элемент)
перем Врап;

    КлиентTCP=СоздатьСерверTCP(Врап);

    ServerAdress="127.0.0.1";
    порт=6891;
    Команда="Тест Отправки Сообщения";
    ДанныеДляКоманды=XmlСтрока(ТекущаяДата());
    
    ЕстьОтвет=истина;
    ЗакрытьСоединение=истина;
    ОшибкаСоединения=false;
    
    резулт=КлиентTCP.ОтправитьКоманду(ServerAdress,порт,Команда,ДанныеДляКоманды,ЕстьОтвет,ЗакрытьСоединение);
    Сообщить(резулт.Данные);    
        Если резулт.ОшибкаСоединения Тогда
            СтрОшибки="ОшибкаСоединения
            |"+резулт.Данные;
        Предупреждение(СтрОшибки);
        КонецЕсли;
КонецПроцедуры
57 Serginio1
 
02.12.13
18:39
Ну и работа со сканером ШК
Процедура ОткрытьПортСканераНажатие(Элемент)
    перем Врап;
    // Вставить содержимое обработчика.
    НомерПорта=0;
    Если не ВвестиЧисло(НомерПорта,"Введите номе COM порта",4,0) Тогда
        возврат
    КонецЕсли;
     СерверTCP=СоздатьСерверTCP(Врап);
    Событие=Врап.ПолучитьОбъектДляСобытийСПараметром(СерверTCP,"ДанныеОтСканера");
    ДобавитьОбработчик Событие.СобытиеСПараметром, ПолучениеДанныхПоTCP;
    
    СерверTCP.ПодключитьСканер(НомерПорта);
    
КонецПроцедуры

Процедура ПолучениеДанныхОтСканераШК(Данные)
Сообщить("ИмяПорта="+Данные.ИмяПорта);
Сообщить("ШтрихКод="+Данные.Данные);
    

КонецПроцедуры
58 Serginio1
 
03.12.13
11:42
Для упрощения регистрации добавил интерактивную регистрацию
59 Serginio1
 
03.12.13
16:01
Кстати часто спрашивают как загрузить СОМ Объект без регистрации

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Reflection;


namespace WindowsFormsApplication3
{
    [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), ComVisible(false), Guid("00000001-0000-0000-C000-000000000046")]
    internal interface IClassFactory
    {
        [return: MarshalAs(UnmanagedType.Interface)]
        object CreateInstance([In, MarshalAs(UnmanagedType.IUnknown)] object pUnkOuter, [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid);
        void LockServer([In, MarshalAs(UnmanagedType.Bool)] bool fLock);
    }





    [ComImport, Guid("00020400-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    internal interface IDispatch
    {
        void GetTypeInfoCount(out uint pctinfo);
        void GetTypeInfo(uint iTInfo, int lcid, out IntPtr info);

        void GetIDsOfNames(ref Guid iid, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr, SizeParamIndex = 2)] string[] names, uint cNames, int lcid, [Out, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.I4, SizeParamIndex = 2)] int[] rgDispId);

        void Invoke(int dispIdMember, ref Guid riid, int lcid, System.Runtime.InteropServices.ComTypes.INVOKEKIND wFlags, ref System.Runtime.InteropServices.ComTypes.DISPPARAMS pDispParams, IntPtr pvarResult, IntPtr pExcepInfo, IntPtr puArgErr);
    }




    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, 0);
            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);


        }

        public static object ЗагрузитьОбъектПоИнформацииОТипе(string ИмяФайла)
        {

            UCOMITypeLib typeLibrary;
            Win32NativeMethods.LoadTypeLib(ИмяФайла, out typeLibrary);

            string typeName, typeDocumentation, typeHelpFile;
            int typeHelpContext;
            for (int i = 0; i < typeLibrary.GetTypeInfoCount(); i++)
            {
                typeLibrary.GetDocumentation(i, out typeName, out
typeDocumentation, out typeHelpContext, out typeHelpFile);


                System.Runtime.InteropServices.TYPEKIND tk;
                typeLibrary.GetTypeInfoType(i, out tk);

                if (tk == System.Runtime.InteropServices.TYPEKIND.TKIND_COCLASS)
                {
                    UCOMITypeInfo typeInformation;
                    typeLibrary.GetTypeInfo(i, out typeInformation);

        
                    //IntPtr ptr;
                    // typeInformation.GetTypeAttr(out ptr);
                    // System.Runtime.InteropServices.TYPEATTR pta =(System.Runtime.InteropServices.TYPEATTR) Marshal.PtrToStructure(ptr, typeof(System.Runtime.InteropServices.TYPEATTR));

                    // return ЗагрузитьОбъект(ИмяФайла, pta.guid);
                  
                    object classInstance;
                    var IID_IUnknown = new Guid("00000000-0000-0000-C000-000000000046");

                    
                    typeInformation.CreateInstance(null, ref IID_IUnknown, out classInstance);
                    return classInstance;
                    
                    //method.Invoke(classInstance, new object[0]);

                }
            }
            return null;
        }
    }
}
60 Serginio1
 
03.12.13
16:02
И пример использования
dynamic res = ЗагрузкаComОбъекта.ЗагрузитьОбъектПоИнформацииОТипе(@"c:\Program Files (x86)\1cv8\8.3.4.317\bin\comcntr.dll");
            MessageBox.Show(res.HighBoundDefault.ToString());
61 Serginio1
 
03.12.13
16:17
Загружать DLL нужно с параметром 8
var module = Win32NativeMethods.LoadLibraryEx(ИмяФайла, IntPtr.Zero, 8);

что бы исказ зависимые DLL в каталоге имени файла

http://wm-help.net/books-online/print-page/59464/59464-14.html
LOAD_WITH_ALTERED_SEARCH_PATH

Этот флаг изменяет алгоритм, используемый LoadLibraryEx при поиске DLL-файла. Обычно поиск осуществляется так, как я рассказывал в главе 19 Однако, если данный флаг установлен, функция ищет файл, просматривая каталоги в таком порядке
1.Каталог, заданный в napaмeтре pszDLLPathName.
2.Текущий каталог процесса.
3.Системный каталог Windows.
4.Основной каталог Windows.
5.Каталоги, перечисленные в переменной окружения PATH
62 Serginio1
 
03.12.13
18:13
Немного изменил загркзку. Добавив загрузку по имени класса

public static object ЗагрузитьОбъектПоИнформацииОТипе(string ИмяФайла,String ИмяКласса="")
        {

            UCOMITypeLib typeLibrary;
            Win32NativeMethods.LoadTypeLib(ИмяФайла, out typeLibrary);

            string typeName, typeDocumentation, typeHelpFile;
            int typeHelpContext;
            for (int i = 0; i < typeLibrary.GetTypeInfoCount(); i++)
            {
                typeLibrary.GetDocumentation(i, out typeName, out
typeDocumentation, out typeHelpContext, out typeHelpFile);


                System.Runtime.InteropServices.TYPEKIND tk;
                typeLibrary.GetTypeInfoType(i, out tk);

                if (tk == System.Runtime.InteropServices.TYPEKIND.TKIND_COCLASS)
                {

                    if (!string.IsNullOrEmpty(ИмяКласса) && (string.Compare(typeName,ИмяКласса,true)!=0))
                         continue;

                    UCOMITypeInfo typeInformation;
                    typeLibrary.GetTypeInfo(i, out typeInformation);

        
                    IntPtr ptr;
                     typeInformation.GetTypeAttr(out ptr);
                     System.Runtime.InteropServices.TYPEATTR pta =(System.Runtime.InteropServices.TYPEATTR) Marshal.PtrToStructure(ptr, typeof(System.Runtime.InteropServices.TYPEATTR));

                     return ЗагрузитьОбъект(ИмяФайла, pta.guid);
                  
                    object classInstance;
                    var IID_IUnknown = new Guid("00000000-0000-0000-C000-000000000046");

                    
                    typeInformation.CreateInstance(null, ref IID_IUnknown, out classInstance);
                    return classInstance;
                    
                    //method.Invoke(classInstance, new object[0]);

                }
            }
            return null;
        }
63 Serginio1
 
03.12.13
18:14
И соответственно вызов
dynamic res = ЗагрузкаComОбъекта.ЗагрузитьОбъектПоИнформацииОТипе(@"c:\Program Files (x86)\1cv8\8.3.4.317\bin\comcntr.dll", "COMConnector".ToUpper());
            MessageBox.Show(res.HighBoundDefault.ToString());

Таким способом можно загружать нужные версии comcntr.dll
64 H A D G E H O G s
 
03.12.13
18:23
(62) GUID фабрики есть в библиотеке типов?
65 H A D G E H O G s
 
03.12.13
18:24
(61) Неа. Версия ядра core82 не соответствует версии библиотеки, как то так.
Этот метод возможен только для работы одинаковых версия 1cv8.exe и comcntrl.dll
66 Serginio1
 
03.12.13
18:28
(64) Да можно загрузить так
IntPtr ptr;
                     typeInformation.GetTypeAttr(out ptr);
                     System.Runtime.InteropServices.TYPEATTR pta =(System.Runtime.InteropServices.TYPEATTR) Marshal.PtrToStructure(ptr, typeof(System.Runtime.InteropServices.TYPEATTR));

                     return ЗагрузитьОбъект(ИмяФайла, pta.guid);

При этом она вызывает var module = Win32NativeMethods.LoadLibraryEx(ИмяФайла, IntPtr.Zero, 8);
и находит все связанные библиотеки.

Сделан просто для использование через LoadLibraryEx

но лучше сразу

object classInstance;
                    var IID_IUnknown = new Guid("00000000-0000-0000-C000-000000000046");

                    
                    typeInformation.CreateInstance(null, ref IID_IUnknown, out classInstance);
                    return classInstance;
67 H A D G E H O G s
 
03.12.13
18:28
(65) Тут только - перехват getmodulehandle(), ручной loadlibraryex() по нужному пути и возврат handle загруженных dll в перехваченный getmodulehandle()

Вернее не getmodulehandle() а его native предок zwgetmodulehandle() из winnt.dll. Вот чую это.
68 Serginio1
 
03.12.13
18:31
(67) Я выкладываю рабочий вариант. При использовании
Win32NativeMethods.LoadLibrary(ИмяФайла);
или
Win32NativeMethods.LoadLibraryEx(ИмяФайла, IntPtr.Zero, 0);

Вылетает твоя ошибка. Но при
Win32NativeMethods.LoadLibraryEx(ИмяФайла, IntPtr.Zero, 8);
все чики пики
69 H A D G E H O G s
 
03.12.13
18:32
(66) Стоп. Тпрррр.

1) 1C загружает dll
2) Из StringTable 100 она берет ProgID
3) Вызывает DllRegisterServer
4) DllregisterServer регистрирует в реестре само, пиша туда ProgID и CLSID
5) 1C по ProgID получает CLSID
6) Создает фабрику COM
7) Создает Инстансы.
70 H A D G E H O G s
 
03.12.13
18:32
(68) Я пробовал.

У меня в процесс загружалось по 2 dll из разных папок
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