Использование сборок .NET в 1С 7.x b 8.x. Создание внешних Компонент.

Данная разработка создана для использования сборок .Net в 1С через преобразование объектов и классов в COM-объекты, которые можно использовать в 1С. Достигается это путем создания класса, реализующего методы интерфейса IReflect public class AutoWrap: IReflect.

Также добавлена возможность использования внешних событий в 1С, в том числе примеры обмена сообщениями по TCP/IP и Работа со сканером ШК, события отслеживание изменений в директории. 
Примеры использование сборок для подключения к Вэб — сервисам, не поддерживаемые 1С. Использование конфигурационных файлов. 

Реализацию ВК внутри сборки для получения Глобального контекста. Использование для установки владельца окна формы главного окна 1С,
вызов внешнего события, использование методов глобального контекста.
Так же добавил возможность показать окно семерки созданное через Новый COMОбъект(«V77.Application»);

Добавил динамическую компиляцию класса обертки для использования .Net событий через ДобавитьОбработчик или ОбработкаВнешнегоСобытия Статья по их использованию лежит здесь //infostart.ru/public/417830/
Реализация 1C Messenger описанного здесь //infostart.ru/public/434771/
Использование классов .Net в 1С для новичков //infostart.ru/public/448668/
Быстрое создание Внешних Компонент на C#. Примеры использования Глобального Контекста, IAsyncEvent, IExtWndsSupport, WinForms и WPF
//infostart.ru/public/457898/
.Net в 1С. Примеры использования HTTPClient, AngleSharp. Асинхронные HTTP запросы, отправка Post нескольких файлов multipart/form-data, сжатие трафика с использованием gzip, deflate, удобный парсинг сайтов и т.д //infostart.ru/public/466052/
.Net в 1С. На примере использования HTTPClient,AngleSharp.Удобный парсинг сайтов с помощью библиотеки AngleSharp в том числе с авторизацией аля JQuery с использованием CSS селекторов. //infostart.ru/public/466196/
Так же статья invertercant 
Строка в дату. Универсальное решение. Применение NetObjetToIDispatch45 //infostart.ru/public/434345/
.Net в 1С. На примере использования HTTPClient,AngleSharp.Удобный парсинг сайтов с помощью библиотеки AngleSharp в том числе с авторизацией аля JQuery с использованием CSS селекторов. //infostart.ru/public/466196/

Кроссплатформенное использование классов .Net в 1С через Native ВК. Или замена COM на Linux //infostart.ru/public/534901/

Данная разработка создана для использования сборок .Net в 1С через преобразование объектов и классов в COM объекты которые можно использовать в 1С. Достигается это путем создания класса реализующим методы интерфейса

IReflect publi cclass AutoWrap : IReflect

Внутри него есть метод который оборачивает объекты не поддерживаемые в 1С в экземпляр класса AutoWrap.

Для облегчения работы с этим классом создан другой класс NetObjectToIDispatch

У него есть следующие методы

public object ПолучитьТип(string type)

Получает тип используя типы загруженных сборок полученный объект позволяет использовать статические методы класса

и члены перечислений примеры взятые отсюда

 http://www.forum.mista.ru/topic.php?id=664174#62

http://dev.mista.ru/topic.php?id=686516

Пример отправки письма по протоколу Ssl

врап=новый COMОбъект("NetObjectToIDispatch45");

smtp = "smtp.yandex.ru";
login = "XXXXX@yandex.ru";
password = "XXXXXXX";
Кому = "XXXXXXX@YYYYYYYY.ru";
Port=25;

mail = врап.СоздатьОбъект("System.Net.Mail.SmtpClient",smtp, Port);

mail.EnableSsl = true;
mail.UseDefaultCredentials = false;
mail.Credentials = врап.СоздатьОбъект("System.Net.NetworkCredential",login, Password);

mail.DeliveryMethod = Врап.ПолучитьТип("System.Net.Mail.SmtpDeliveryMethod").Network;

Message = врап.СоздатьОбъект("System.Net.Mail.MailMessage");
MailAddressType= Врап.ПолучитьТип("System.Net.Mail.MailAddress");
Message.From = врап.СоздатьОбъект(MailAddressType,login);
Message.To.Add(врап.СоздатьОбъект(MailAddressType,Кому));
Message.Subject = "Тема Тест отправки почты SSL";
Message.IsBodyHtml = true;
Message.Body = "Тело Тест отправки почты SSL";

mail.Send(Message);//отправка

Message.Dispose();
mail.Dispose();

Но есть один минус: для типа нельзя вызвать методы типа. Для этого существует метод

public object ТипКакОбъект(object Тип)

из которого можно использовать методы и свойства Type (Например, AssemblyQualifiedName)

public object СоздатьОбъект(object Тип, paramsobject[] args)

Создает объект по типу или по строке, используя параметры, которые можно перечислять через запятую. Например

сервер=врап.СоздатьОбъект(тип,парам1,парам2);

public Object ChangeType(string type, object value)

Используя для преобразования типа в нужный тип. В C# используется перегрузка по параметрам. В .Net для чисел много типов, а  1С только один тип.

public object ПолучитьИнтерфейс(object obj, string InterfaseName)

получить интерфейс  объекта.

public object ЗагрузитьСборку(string ПутьКСборке)

загружает сборку и возвращает ссылку на нё.

К сожалению, иногда не все методы выполняются. Например ToArray() для List

Или методы с параметром типа GUID (сам метод выполняется, но при передаче результата в 1С выдается ошибка «типы не совпадают» )

Для этого добавлен метод

public object ВыполнитьМетод(object obj, string ИмяМетода, params object[] args)

И вызов из 1С

//Ком=ЗагрузкаComОбъекта.ЗагрузитьОбъект(ИмяФайла,стр.Гуид); ошибка  типа
Ком=Врап.ВыполнитьМетод(ЗагрузкаComОбъекта,"ЗагрузитьОбъект",ИмяФайла,стр.Гуид);
// Выполняется без ошибок

В Net особенно в WCF активно используются конфигурационные файлы.

Для использования их в 1С можно создать такой файл в директории запускаемой программы под именем ИмяЗапускаемойПрограммы.exe.config, например

C:Program Files (x86)1Cv77BIN1cv7s.exe.config

Или

C:Program Files (x86)1cv88.3.4.317in1cv8.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

Также добавлена возможность получения событий в 1С.

Для этого нужно создать сборку в которой создать делегаты и события

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 ClassForEvent1C(object Объект,String СобытиеОбъекта,bool ЕстьПараметр=false)

        {

  this.Объект = Объект;

  bf = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;

 EventInfo ei = Объект.GetType().GetEvent(СобытиеОбъекта, bf);

 if (ЕстьПараметр)

            ei.AddEventHandler(Объект,new System.Action(ВнешнееСобытие));

   else

            ei.AddEventHandler(Объект,new System.Action<object>(ВнешнееСобытиеСПараметром));

  SynchronizationContext.SetSynchronizationContext(newWindowsFormsSynchronizationContext());

            Sc =SynchronizationContext.Current;

        }

     

 public event Событие_Delgate Событие;

 public event СобытиеСПараметром_Delgate СобытиеСПараметром;

private void ВнешнееСобытие()

        {

if (this.Событие != null) //Событие();

              Sc.Send(d => Событие(),null);

       }

     

private void ВнешнееСобытиеСПараметром(object value)

        {

if (this.СобытиеСПараметром != null) //Событие();

                Sc.Send(d => СобытиеСПараметром(AutoWrap.ОбернутьОбъект(value)), null);

        }

    }

}

Использование в 1С

Перем ОбъектССобытием;
Процедура ТестСобытияНажатие(Элемент)
врап=новый COMОбъект("NetObjectToIDispatch45");
Сборка=врап.загрузитьСборку(ИмяФайлаСборки); //ПроектИспользованияДелегатов.dll
тип=Сборка.GetType("ПроектИспользованияДелегатов.КлассДляВнешнихСобытий");

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

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

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

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

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

Так же добавил сборку для обмена сообщениями по TCP/IP и сканера Штрих кода

В сборке ОбменПоTCPIP., при этом данные сжимаются GZip ом.

Пример использования на сервере

Функция СоздатьСерверTCP(Врап)

Если не ЗначениеЗаполнено(ИмяФайлаСборки) Тогда
вызватьИсключение   "Не выбрано Имя Файла Сборки"

КонецЕсли;


врап=новый COMОбъект("NetObjectToIDispatch45");
ФайлСборки=ИмяФайлаСборки;//"d:MyProgramsTestОбменПоTCPIPОбменПоTCPIPinDebugОбменПоTCPIP.dll";
Сборка=врап.загрузитьСборку(ФайлСборки); //ПроектИспользованияДелегатов.dll
тип=Сборка.GetType("TCPConnectTo1C.TCPConnector");

СерверTCP=врап.СоздатьОбъект(Тип);
возврат   СерверTCP

КонецФункции // СоздатьTCP()

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

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

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

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

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

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

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


КонецЕсли;

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


На Клиенте

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

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

ServerAdress="127.0.0.1";
порт=6891;
Команда="Тест Отправки Сообщения";
ДанныеДляКоманды=XmlСтрока(ТекущаяДата());

ЕстьОтвет=истина;
ЗакрытьСоединение=истина;
ОшибкаСоединения=false;

резулт=КлиентTCP.ОтправитьКоманду(ServerAdress,порт,Команда,ДанныеДляКоманды,ЕстьОтвет,ЗакрытьСоединение);
Сообщить(резулт.Данные);
Если резулт.ОшибкаСоединения Тогда
СтрОшибки="ОшибкаСоединения
|"+резулт.Данные;
Предупреждение(СтрОшибки);
КонецЕсли;
КонецПроцедуры

И добавлена работа со Сканером ШК. К сожалению проверить его работу не могу, ввиду отсутствия сканера

Процедура ОткрытьПортСканераНажатие(Элемент)
перем Врап;
// Вставить содержимое обработчика.
НомерПорта=0;
Если не ВвестиЧисло(НомерПорта,"Введите номе COM порта",4,0) Тогда
возврат
КонецЕсли;
СерверTCP=СоздатьСерверTCP(Врап);
Событие=Врап.ПолучитьОбъектДляСобытийСПараметром(СерверTCP,"ДанныеОтСканера");
ДобавитьОбработчик Событие.СобытиеСПараметром, ПолучениеДанныхПоTCP;

СерверTCP.ПодключитьСканер(НомерПорта);

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

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


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

И добавлен приер загрузки объекта из DLL без регистрации на примере загрузки

Из comcntr.dll класс COMConnector. Для примера когда нужно подключиться к Базе  с версией отличной от текущей

Добавил пример использования конфигурационного файла в WCF клиентах в DLL

public object СоздатьКлиентаWCFConfigFile(string ИмяФайла, object TChannel, string endpointConfigurationName, object endpointAddress)

        {

  ExeConfigurationFileMap fileMap = newExeConfigurationFileMap();

            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)

                );

return AutoWrap.ОбернутьОбъект(factory1.CreateChannel());

        }

Процедура ВызовСервисаИспользуяConfigFileНажатие(Элемент)     // Вставить содержимое обработчика.         врап=новый COMОбъект("NetObjectToIDispatch45");
//Сборка=врап.загрузитьСборку("d:MyProgramsTestNestNet45NestNet45inDebugNestNet45.dll");     Сборка=врап.загрузитьСборку(ИмяФайлаСборки);     TChannel=Сборка.GetType("NestNet45.ServiceReference1.MorpherSoap");     ConfigFile=ИмяФайлаСборки+".config";     endpointConfigurationName="MorpherSoap";     endpointAddress=Неопределено;     Клиент=врап.СоздатьКлиентаWCFConfigFile(ConfigFile,TChannel,endpointConfigurationName,endpointAddress);
// Вызываю метод и вывожу результат     рез = Клиент.GetForms("Ваяся Пупкин");
Для каждого стр  Из рез Цикл         сообщить(стр)     КонецЦикла;
КонецПроцедуры

Подправил обертку объектов. Теперь массивы примитивных типов строки, дата, Decimal возвращаются как родные для 1С COMSafeArray.

Для массива объектов нужно отдельно преобразовать через функция

ПолучитьSafeArrayИзЭнумератора(Object Массив)

Так же при работе с событиями проще сделать комовский класс с событиями например
// Создаем интерфейс доступных событий из 1С
[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IEventFor1C
{
[DispId(0x00000001)]
void Событие();

[DispId(0x00000002)]
void СобытиеПереименованияФайла(object ИмяДиректории);
}


// Указываем какие комовские события будет реализовывать класс
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDual)]
[ComSourceInterfaces(typeof(IEventFor1C))]
public class КлассДляВнешнихСобытий2
{
public string ИзмененныйФайл;
public string ПереименованныйФайл;
public event System.Action Событие;
[ComVisible(false)]
public delegate void СобытиеСПараметром_Delgate(object value);
public event СобытиеСПараметром_Delgate СобытиеПереименованияФайла;
public FileSystemWatcher watcher;
dynamic Врапер;
private SynchronizationContext Sc;
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)
Sc.Send(d => Событие(), null);

}

// Врапер это объект который создается через
//врап=новый COMОбъект("NetObjectToIDispatch45");
// Нужен для обертки объектов в AutoWrap
public КлассДляВнешнихСобытий2(Object  Врапер,string Директория)
{
this.Врапер=Врапер;
// SynchronizationContext нужен для того, что вызов проходил в потоке 1С
SynchronizationContext.SetSynchronizationContext(new System.Windows.Forms.WindowsFormsSynchronizationContext());
Sc = SynchronizationContext.Current;

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 = "*.*";

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

// Begin watching.
watcher.IncludeSubdirectories = true;

watcher.EnableRaisingEvents = true;



}

private void OnRenamed(object source, RenamedEventArgs e)
{
// Specify what is done when a file is renamed.

ПереименованныйФайл = string.Format("File: {0} renamed to {1}", e.OldFullPath, e.FullPath);
if (this.СобытиеПереименованияФайла != null)
Sc.Send(d => СобытиеПереименованияФайла(Врапер.ОбернутьОбъект(ПереименованныйФайл)),null);
// В данном случае ПереименованныйФайл это строка и Врапер.ОбернутьОбъект(ПереименованныйФайл) для примера,
// что бы показать как обернуть любой объек в AutoWrap не читаемый из 1С Net объект
}

}
И соответственно вызов из 1С

врап=новый COMОбъект("NetObjectToIDispatch45");
Сборка=врап.загрузитьСборку(ИмяФайлаСборки); //ПроектИспользованияДелегатов.dll
тип=Сборка.GetType("ПроектИспользованияДелегатов.КлассДляВнешнихСобытий2");

ОбъектССобытием2=врап.СоздатьОбъект(Тип,врап,КаталогДляОтслеживанияИзменений);

// Нужен для доступа к комовским событиям
КомОбъектССобытием=Врап.ПолучитьРеальныйОбъект(ОбъектССобытием2);

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

При выходе можно очистить события.

Если ОбъектССобытием2<>Неопределено  Тогда

врап.ОчиститьСобытияОбъекта(ОбъектССобытием2.watcher);
врап.ОчиститьСобытияОбъекта(ОбъектССобытием2);

КонецЕсли;

Добавил реализацию ВК внутри сборки для получения Глобального контекста. Использование

Если ПодключитьВнешнююКомпоненту("AddIn.GlobalContext1C") Тогда
объект=Новый ("AddIn.GlobalContext1C");
ГлобальныйКонтекст=объект.ГлобальныйКонтекст;
AppDispatch=ГлобальныйКонтекст.AppDispatch;
AppDispatch.Сообщить("Привет");
иначе
сообщить("Компонента не загружена");
КонецЕсли;

Использование Внутри Net.

public ТестВК(object Object1C)

    {

        this.Object1C = Object1C;

        ГК = new ДинамикГК(Object1C);

}

public string СоздатьОкно() {

    //    m_1cApp.AppDispatch.Сообщить(«Привет из ВК»);

    // не работает для упрощения работы создань динамический объект ДинамикГК

    // выполняющий аналогичную фунцию

            IExtWndsSupport n;

            ГК.Сообщить(«Привет из ВК», ГК.СтатусСообщения.Важное);

            n = (IExtWndsSupport)Object1C;

            IntPtr hwnd;

             n.GetAppMainFrame(out hwnd);

    // Создаем форму, устанавливаем нативные хэндлы и устанвливаем окно 1С владельцем нетовского окна

            var form = new Form1();

            form.CreateControl();

            SetOwner(form.Handle.ToInt32(), hwnd.ToInt32());

            form.EventTo1C = Object1C as IAsyncEvent;

          form.Show();

            return «Методы ВК выполнены!»;

        }

private async void button1_Click(object sender, EventArgs e)

        {

            var ПотокПриложения = Thread.CurrentThread.ManagedThreadId;

            // Для чистоты эксперимента вызовим события из потока отличного от потока приложения.

            // Что бы await не использовал текущий контекст установим ConfigureAwait(false)

            await Task.Delay(1000).ConfigureAwait(false); // делаем задержку в секунду и вызываем событие

            var ПотокСобытия = Thread.CurrentThread.ManagedThreadId;

            // Для вызова в тотоке приложения вызовем метод из его потока

            Sc.Send(d => EventTo1C.ExternalEvent(«ДанныеИзТестВК», «Тест», string.Format(«Поток Приложения={0} Поток события {1}»,ПотокПриложения,ПотокСобытия)), null);

            // Если очень быстро кликать по кнопке то потоки события будут разными

        }

Также добавил возможность показать окно семерки созданное через Новый COMОбъект(«V77.Application»);

67 Comments

  1. oleg_km
    Reply
  2. Serginio

    Исправил метод СоздатьКлиентаWCFConfigFile(string ИмяФайла, object TChannel, string endpointConfigurationName, object endpointAddress=null,string UserName=null, string Password=null)

    Для передачи UserName и Password при соединении

    public object СоздатьКлиентаWCFConfigFile(string ИмяФайла, object TChannel, string endpointConfigurationName, object endpointAddress=null,string UserName=null, string Password=null)
    {
    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)
    );
    
    if (!String.IsNullOrWhiteSpace(UserName))
    {
    
    factory1.Credentials.UserName.UserName = UserName;
    factory1.Credentials.UserName.Password = Password;
    
    }
    
    return AutoWrap.ОбернутьОбъект(factory1.CreateChannel());
    }
    

    Показать

    И применение в 1С

    Функция ПолучитьКлиента()
    TChannel=Сборка.GetType(namespace + «IService»);
    ConfigFile=ИмяФайлаСборки+».config»;
    endpointConfigurationName=»»BasicHttpBinding_IService»;
    //  endpointAddress=Неопределено;
    
    
    
    
    _client=врап.СоздатьКлиентаWCFConfigFile(ConfigFile,TChannel,endpointConfigurationName,,_UserName_,_Password_);
    
    возврат _client
    
    КонецФункции
    

    Показать

    Reply
  3. bayce

    Эта компонента будет работать в УФ?

    Reply
  4. Serginio

    (3) bayce, Это не компонента, а COM объект который доступен Тонкий клиент, веб-клиент, сервер, толстый клиент, внешнее соединение

    При этом библиотека регистрируется как 32 так 64 разрядная. То есть можно использовать на 64 разрядном сервере приложений

    Reply
  5. vasiliy_b

    Добрый день. У меня вопрос по Вашей публикации, как я понял с ее помощью, можно будет реализовать взаимодействие с COM портом на тонком клиенте.

    В моей задаче стоит считывание данных с com порта и запись данных в порт.

    Из выше описаного можно попробовать прочитать данные с порта, но как отправить в порт некоторые значения мне не совсем понятно.

    есть ли у Вас примеры подобной реализации.

    И еше в статье используется понятеи «Сборок», это терминалогия как я понял от .Net, значит мне будет нужна сборка для работы с com портом, верно?

    Есть ли где-то уже готовые сборки, которые можно было бы использовать?

    Reply
  6. Serginio

    Там есть пример работы с ком портами, но я его не проверял.

    Для записи в ком порт можно использовать SerialPort напрямую

    https://msdn.microsoft.com/en-us/library/system.io.ports.serialport.writeline(v=vs.110).aspx

    Reply
  7. Serginio

    В примере для чтения из ком порта используется кнопка ОткрытьПортСканера

    и обработка события в ДанныеОтСканера

    Reply
  8. Serginio

    Кстати работать со сборками проще загрузив их в макет или хранилище

    Процедура ПриОткрытии()
    
    врап=новый COMОбъект(«NetObjectToIDispatch45″);
    врап.ВыводитьСообщениеОбОшибке=ложь;
    
    Каталог=КаталогВременныхФайлов();
    ФайлWebSocket1C=Каталог+»WebSocket1C2.dll»;
    
    
    
    
    попытка
    ПолучитьМакет(«WebSocket1C»).Записать(ФайлWebSocket1C);
    
    исключение
    Сообщить(ОписаниеОшибки());
    конецпопытки;
    
    // ФайлWebSocket1C=»D:TestProgrammsWebSocket1C2WebSocket1C2inDebugWebSocket­1C2.dll»;
    
    
    Сборка=врап.загрузитьСборку(ФайлWebSocket1C);
    
    
    
    
    
    КонецПроцедуры

    Показать

    Reply
  9. Serginio

    Правда нужно не забывать помещать туда же зависимые сборки.

    Reply
  10. Serginio

    Добавил реализацию ВК внутри сборки для получения Глобального контекста. Использование

    Если ПодключитьВнешнююКомпоненту(«AddIn.GlobalContext1C») Тогда
    объект=Новый («AddIn.GlobalContext1C»);
    иначе
    сообщить(«Компонента не загружена»);
    КонецЕсли;

    Использование Внутри Net.

    public ТестВК(object Object1C)
    {
    this.Object1C = Object1C;
    ГК = new ДинамикГК(Object1C);
    
    }
    
    public string СоздатьОкно() {
    //    m_1cApp.AppDispatch.Сообщить(«Привет из ВК»);
    // не работает для упрощения работы создань динамический объект ДинамикГК
    // выполняющий аналогичную фунцию
    
    IExtWndsSupport n;
    ГК.Сообщить(«Привет из ВК», ГК.СтатусСообщения.Важное);
    n = (IExtWndsSupport)Object1C;
    IntPtr hwnd;
    n.GetAppMainFrame(out hwnd);
    
    // Создаем форму, устанавливаем нативные хэндлы и устанвливаем окно 1С владельцем нетовского окна
    var form = new Form1();
    form.CreateControl();
    SetOwner(form.Handle.ToInt32(), hwnd.ToInt32());
    form.EventTo1C = Object1C as IAsyncEvent;
    
    form.Show();
    
    return «Методы ВК выполнены!»;
    }
    
    private async void button1_Click(object sender, EventArgs e)
    {
    var ПотокПриложения = Thread.CurrentThread.ManagedThreadId;
    // Для чистоты эксперимента вызовим события из потока отличного от потока приложения.
    // Что бы await не использовал текущий контекст установим ConfigureAwait(false)
    await Task.Delay(1000).ConfigureAwait(false); // делаем задержку в секунду и вызываем событие
    var ПотокСобытия = Thread.CurrentThread.ManagedThreadId;
    
    // Для вызова в тотоке приложения вызовем метод из его потока
    Sc.Send(d => EventTo1C.ExternalEvent(«ДанныеИзТестВК», «Тест», string.Format(«Поток Приложения={0} Поток события {1}»,ПотокПриложения,ПотокСобытия)), null);
    // Если очень быстро кликать по кнопке то потоки события будут разными
    }
    

    Показать

    Так же добавил возможность показать окно семерки созданное через Новый COMОбъект(«V77.Application»);

    Reply
  11. qvvert

    Доброго времени суток, подскажите пожалуйста, как быть с символом перевода строки при hmac_sha1 некорректно шифруется…

    Reply
  12. qvvert

    Гугл подсказывает что как то надо заменить Символы.Пс на Environment.NewLine — в дотнете… подскажите пожалуйста как это сделать?

    Reply
  13. Serginio

    https://msdn.microsoft.com/ru-ru/library/fk49wtc1(v=vs.110).aspx

    В объекте есть ОбернутьЛюбойОбъект

    Врап.ОбернутьЛюбойОбъект(Строка).Replace(@»
    «,Environment.NewLine)

    Reply
  14. Serginio

    Хотя проще использовать 1С функцию

    Строка=СтрЗаменить(Строка,Символы.Пс,Символы.Пс+Символы.ВК)

    Reply
  15. qvvert

    (13) а как определить Environment.NewLine?

    Врап.ОбернутьЛюбойОбъект(Строка).Replace(»
    «,Environment.NewLine) — Не прокатывает

    создание объекта Врап.СоздатьОбъект(«System.Environment.NewLine») — тоже не прокатывает….

    Не знает что такое Environment.NewLine как его определить?

    Символы.ПС+Символы.ВК — не спасают отца русской демократии… hmac_sha1 — с символом перевода строки генерится неверно…

    Reply
  16. qvvert

    Вопрос Снимается Спасибо!

    в рамках получения hmac Нужно заменять перевод строки на системную переменную (Если в ключе или в сообщении используется перевод строки) соответсвенно в строке вместо символы.пс — передавать служебный например (»
    «) — где столкнулся я — в апи викимпарта

    новаяСтрока = Врап.ПолучитьТип(«System.Environment»).NewLine;

    message = Врап.ОбернутьЛюбойОбъект(message).Replace(»
    «,новаяСтрока);

    key = Врап.ОбернутьЛюбойОбъект(key).Replace(»
    «,новаяСтрока);

    Reply
  17. Serginio

    (16) Да уж 1С с переводом строки не совсем корректно все сделали.

    Reply
  18. Serginio

    Случайно изменил в AssemblyInfo.cs [assembly: ComVisible(true)] и

    Для каждого Цикл перестал работать

    Который работает через EnumVariantImpl : IEnumVARIANT

    / Параметр ComVisible со значением FALSE делает типы в сборке невидимыми

    // для COM-компонентов. Если требуется обратиться к типу в этой сборке через

    // COM, задайте атрибуту ComVisible значение TRUE для этого типа.

    [assembly: ComVisible(false)]

    Reply
  19. Serginio

    Добавил возможность использования ExpandoObject напрямую с добавлением свойств и методов

    Объект=ЗагрузкаComОбъекта.ПолучитьExpandoObject();
    // Получим словарь для чтения и добавления свойств и методов
    Объект2=Врап.ПолучитьИнтерфейс(Объект,»IDictionary`2″);
    
    // Установим свойсва через словарь
    Объект2.set_Item(«Число»,5);
    
    //Сообщить(Объект.Item(«Имя»));
    Сообщить(Объект2.get_Item(«Имя»));
    Сообщить(Объект2.get_Item(«Число»));
    Объект2.set_Item(«Имя»,»Вызов Метода»);
    Сообщить(Объект2.get_Item(«ВСтроку»).DynamicInvoke());
    
    // Теперь можно обращаться в свойствам и методам напрямую
    Объект.Число=6;
    Сообщить(Объект.Имя);
    Сообщить(Объект.Число);
    Объект.Имя=»Вызов Метода»;
    Сообщить(Объект.ВСтроку());
    
    // Добавим новое поле
    Объект2.Add(«НовоеПоле»,66);
    
    // Нужно обновить информацию о новых методах и свойствах
    Объект=врап.ОбновитьДанныеОметодахИСвойствах(Объект);
    //
    Сообщить(Объект.НовоеПоле);

    Показать

    Reply
  20. sandybaev

    Serginio, а вы не планируете развить в этой сборке TSL авторизацию? Она остро в нем нуждается, допустим для тех случаев когда есть связка 1С+Exchange 2013 и почту надо отправлять во внешний мир.

    Reply
  21. Serginio

    (20) Эта сборка нужна для подгрузки сборок .Net. То есть нужно найти, или создать сборку для обмена с Exchange 2013 на Net и использовать её. Например берем примеры https://code.msdn.microsoft.com/office/Exchange-2013-101-Code-3c38582c/view/SamplePack#content и использум их через NetObjectToIDispatch45. После того, как добавил динамическую компиляцию использования событий Net стало значительно проще использовать эту компоненту. Просто нужно начальное знание Net.

    Здесь есть примеры http://habrahabr.ru/post/117268/

    Несложно их переписать на 1С

    Reply
  22. sandybaev

    Ясно. трабл в том что я слабоват в C#.

    Reply
  23. Serginio

    На самом деле не все так сложно. Возьмем для примера код

    var esb = new ExchangeServiceBinding();
    // Указываем используемые креды
    esb.Credentials = new NetworkCredential(user, password, domain);
    // Задаем входную точку для EWS
    esb.Url = «https://» + server + «/EWS/Exchange.asmx»;
    esb.RequestServerVersionValue = new RequestServerVersion();
    // Указываем тип Exchange сервера
    // Для Exchange 2007 SP1 и 2010 подходит Exchange2007_SP1
    // Для Exchange 2007 без SP нужно указать Exchange2007
    esb.RequestServerVersionValue.Version = ExchangeVersionType.Exchange2007_SP1;
    
    return esb;
    

    Показать

    Нужно знать Простанство имен в котором находится ExchangeServiceBinding

    врап=новый COMОбъект(«NetObjectToIDispatch45″);
    врап.ЗагрузитьСборку(ПутьКСборке);
    ПИ=»НужноеПространствоИмен»;
    esb = Врап.СоздатьОбъект(ПИ+»ExchangeServiceBinding»);
    // Указываем используемые креды
    esb.Credentials = врап.СоздатьОбъект(«System.Net.NetworkCredential»,user, password, domain);
    // Задаем входную точку для EWS
    esb.Url = «https://» + server + «/EWS/Exchange.asmx»;
    esb.RequestServerVersionValue =  врап.СоздатьОбъект(«RequestServerVersion);
    // Указываем тип Exchange сервера
    // Для Exchange 2007 SP1 и 2010 подходит Exchange2007_SP1
    // Для Exchange 2007 без SP нужно указать Exchange2007
    esb.RequestServerVersionValue.Version = врап.ПолучитьТип(«ExchangeVersionType»).Exchange2007_SP1;
    
    return esb;

    Показать

    Просто в модуле C# указываются пространство имен, и поэтому можно опускать их при написании класса.

    Reply
  24. Xershi

    Тяжело читается публикация. Можете структурировать информацию?

    Reply
  25. Serginio

    (24) Она больше для тех кто знаком с Net. Надо отдельную статью написать про использование для тех, кто с Net не знаком. Тут главное понять, что не понятно

    Reply
  26. Xershi

    (25) да учили на C# писать лабораторные, но работаю с 1С профессионально. В принципе понятно. Но вникать долго нужно.

    Reply
  27. Serginio

    (26) Так ты задавай вопросы, я буду отвечать. А затем, может и статью напишем для лучшего понимания. Просто в Net можно найти классы на все возможные случаи.

    Reply
  28. zhichkin

    (27)

    Добрый день, Сергей!

    Есть решение, реализованное на C# WPF: интерфейс, бизнес логика, сервисы, работа с данными. Всё как положено, но … Клиент хочет, чтобы всё было в 1С =) Другими словами, нужно всё наше богатство «прикрутить» к интерфейсу 1С. Размышляю над возможностью использовать MVVM в применении к формам и контролам 1С (пока что речь идёт о толстом клиенте). Может быть посоветуете что-нибудь?

    Reply
  29. Serginio

    Я бы сделал класс враппер для событий формы создания формы и свойства для доступа к этой форме.

    События можно сгенерить динамически или статически пример есть здесь http://infostart.ru/public/417830/

    В примерах ВК есть использования WinForms с привязкой к главному окну 1С.

    Reply
  30. Serginio

    Еще вариант это обмен через TCP/IP пример есть в примерах к статье

    Reply
  31. zhichkin

    (29)

    MVVM предполагает наличие класса ViewModel, который использует интерфейс INotifyPropertyChanged. Идея заключается в том, чтобы при создании формы 1С создавать класс ViewModel и каким-то образом выполнять привязку его свойств к элементам управления формы 1С. Вероятно нужна реализация специального биндера контролов 1С к классу .NET.

    Reply
  32. Serginio

    Ты можешь вызывать события, к которым из 1С будет подключаться и обрабатывать

    Reply
  33. Serginio

    То есть ты можешь подключиться к событиям ViewModel через http://infostart.ru/public/417830/

    Reply
  34. Serginio

    Посмотри примеры. Будет понятнее.

    Reply
  35. Serginio

    Кстати используя WindowInteropHelper можно использовать окна WPF передавя ему оно владельца хэндл главного окна 1С. И можешь использовать окна WPF в 1С

    Reply
  36. zhichkin

    (35)

    Спасибо. Понятно.

    Reply
  37. Serginio

    (36) Еще можно передать в нетовский объект ссылку на общий модуль, модуль отчета, модуль формы и вызывать все их экспортные методы. В сборке ТестВК. присоздании объекта класса ТестВК передается глобальный контекст 1С Object1C, через который можно вызваь методы глобального контекста 1С, получать хэндл главного окна 1С GetAppMainFrame и получать интерфейс IAsyncEvent через который вызывать внешнееСобытие в 1С.

    По сути вам нужно по минимуму изменить C# проект

    Reply
  38. Serginio

    35+ Специально проверил на WPF Window

    Создал класс

    public partial class Window1 : Window
    {
    dynamic Модуль1С;
    public Window1(dynamic модуль1С, dynamic Object1C)
    {
    InitializeComponent();
    Модуль1С = модуль1С;
    IExtWndsSupport n;
    n = (IExtWndsSupport)Object1C;
    IntPtr hwnd;
    n.GetAppMainFrame(out hwnd);
    
    var wih = new System.Windows.Interop.WindowInteropHelper(this);
    wih.Owner = hwnd;
    
    }
    
    private void button_Click(object sender, RoutedEventArgs e)
    {
    Модуль1С.СообщитьСтр(textBox.Text);
    }
    }

    Показать

    В модуле отчета прописал

    Процедура СообщитьСтр(стр) Экспорт
    
    Сообщить(стр)
    
    КонецПроцедуры
    

    И соответственно вызов

    врап=новый COMОбъект(«NetObjectToIDispatch45»);
    тип=Врап.ПолучитьТипИзСборки(«WPFLibrary.Window1»,»d:Vs2015ProgramsSignalRWPFLibraryWPFLibraryinDebugWPFL­ibrary.dll»);
    ПодключитьВнешнююКомпоненту(«AddIn.GlobalContext1C»);
    объект=Новый («AddIn.GlobalContext1C»);
    ГлобальныйКонтекст=объект.ГлобальныйКонтекст;
    
    Окно=Врап.СоздатьОбъект(тип,ЭтотОбъект,ГлобальныйКонтекст);
    Окно.Show();
    

    Показать

    Reply
  39. Serginio

    Еще нужно при закрытии уничтожить ссылку на модуль

     private void Window_Closed(object sender, EventArgs e)
    {
    Модуль1С.СообщитьСтр(«Форма закрыта»);
    Marshal.Release(Marshal.GetIDispatchForObject(Модуль1С));
    Marshal.ReleaseComObject(Модуль1С);
    Модуль1С = null;
    GC.Collect();
    GC.WaitForPendingFinalizers();
    }

    Показать

    Reply
  40. Serginio

    Добавил в ТестВК использование WPF форм

    Reply
  41. Serginio

    Сейчас в .Net широко применяют оператор await. Он применяется к методам возвращающие Task или Task<TResult>.

    Task это задача представляет асинхронную операцию. Доступ к результату осуществляется через свойство Result.

    В 1С можно использовать либо синхронный вариант например

    ДанныеРесурса=Клиент.GetStringAsync(«https://msdn.microsoft.com/ru-ru/library/hh551745(v=vs.118).aspx»).Result;

    Но для того, что бы этот метод выполнить асинхронно я создал класс с помощью которого легко использовать эти методы асинхронно.

    врап=новый COMОбъект(«NetObjectToIDispatch45»);
    Выполнитель=Врап.ПолучитьАсинхронныйВыполнитель();
    ДобавитьОбработчик Выполнитель.ПриОкончанииВыполненияЗадачи, ПриОкончанииВыполнения;
    
    Обработчик события выглядит так
    Процедура ПриОкончанииВыполнения(Задача,ДанныеКЗадаче)
    
    // Обязательно нужно отлавливать ошибку в 1С
    // Иначе она передается в .Net где обрабатывается там
    Попытка
    Так как задача может завершиться с ошибкой
    Мы должны проверить, и если ошибка нужно предпринять какие то действия
    Если (Задача.IsFaulted) Тогда  // Ошибка выполнения
    
    Сообщить(«Ошибка «+Врап.ВСтроку(Задача.Exception));
    Сообщить(«Данные к задаче «+Врап.ВСтроку(ДанныеКЗадаче));
    
    иначе
    Сообщить(«=====Выполнена задача ====»);
    Сообщить(«Данные к задаче «+Врап.ВСтроку(ДанныеКЗадаче));
    Сообщить(Врап.ВСтроку(Задача.Result));
    
    
    КонецЕсли;
    
    Исключение
    Сообщить(«Ошибка в процедуре»);
    Сообщить(ОписаниеОшибки());
    КонецПопытки
    
    КонецПроцедуры
    

    Показать

    Вызываем задачу так

    HttpClient=Врап.ПолучитьТипИзСборки(«System.Net.Http.HttpClient»,»System.Net.Http.dll»);
    Клиент=Врап.СоздатьОбъект(HttpClient);
    Задача=Клиент.GetStringAsync(«https://msdn.microsoft.com/ru-ru/library/hh551745(v=vs.118).aspx»);
    Выполнитель.Выполнить(задача,ТекущаяДата());
    

    Вторым параметром можно передавать любые данные, что бы понять какая задача выполнена и что с ней делать, так одновременно может работать множество задач

    Например

    АсинхМетоды = Врап.СоздатьОбъект(КлассДляТестаАсинхронныхМетодов);
    
    Для сч=1 по 10 Цикл
    задача=АсинхМетоды.ДолгаяЗадача(Строка(«Задача «+сч));
    Выполнитель.Выполнить(задача,сч);
    КонецЦикла
    
    Reply
  42. Serginio

    Очень часто приходится использовать битовую операци OR

    например

     AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
    

    или

     watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite| NotifyFilters.FileName | NotifyFilters.DirectoryName;

    Поэтому добавил метод OR. Теперь те же операции можно вызвать

    DecompressionMethods= Врап.ПолучитьТип(«System.Net.DecompressionMethods»);
    handler.AutomaticDecompression=Врап.OR(DecompressionMethods.GZip,DecompressionMethods.Deflate) ;
    

    или

    NotifyFilters=врап.ПолучитьТип(«System.IO.NotifyFilters»);
    рез=Врап.OR(NotifyFilters.LastAccess,NotifyFilters.LastWrite,NotifyFilters.FileName,NotifyFilters.DirectoryName);
    
    Reply
  43. TeMochkiN

    Подскажите, пожалуйста, зависимые сборки нужно как-то загружать или ещё что-то делать, или достаточно чтобы они находились в одном каталоге с основной сборкой, чтобы всё корректно работало??

    Reply
  44. Serginio

    (43) Достаточно, что бы находились в одном каталоге. Но иногда для динамической компиляции нужно что бы были в каталоге программы (основной Домен) . http://infostart.ru/public/466196/

    Reply
  45. asdfgcom

    Где-то я неправ. Помогите разобраться…

    Хочу вывести Прогрессбар:

    врап=новый COMОбъект(«NetObjectToIDispatch45»);
    пб = врап.СоздатьОбъект(«System.Windows.Forms.ProgressBar»);
    пб.Visible = true;
    пб.Minimum = 1;
    пб.Value = 1;
    пб.Step = 1;
    пб.Show();
    

    Показать

    Все без ошибок, но ничего нигде не отрисовывается.

    Оговорюсь, не знаком ни с чем кроме 1С..

    Reply
  46. Serginio
  47. asdfgcom

    (46)т.е. я под него должен создать сначала какую-то форму и передать ее в свойство parent прогрессбара?

    форма, я полагаю, ему нужна не 1Совская а MS windows.forms?..

    Судя по Вашему ответу, даже ВК придется писать?

    Reply
  48. Serginio

    Нет ВК тебе не придется писать. Но тебе нужно написать форму с контролами.

    В том числе и с System.Windows.Forms.ProgressBar.

    Ну и написать метод (в примере конструктор) в который будет передаваться глобальный контекст 1С для получения нэндла 1С окна

    Reply
  49. ArchLord42

    Есть люди, которые пытались юзать враппер на сервере?

    Не могу создать объект из загружаемой сборки.

    У меня на клиенте все работает нормально, а вот на сервере не как не создавать объекты, которые содержатся во внешних сборках, объекты из GAC создаются, а на внешних выдает «Произошла исключительная ситуация (mscorlib): Конструктор для типа «ХХХ» не найден.» как понимаю падает на Activator.CreateInstance, но не могу понять причину отладить серверный вызов в студии нет возможности.

    Сразу говорю, что код клиентского вызова и серверного идентичен.

    Reply
  50. Serginio

    А он на сервере то есть? Если есть, то перед вызовом загрузить все сборки

    Reply
  51. Serginio

    На всякий случай проверить, что сборки AnyCpu

    Reply
  52. ArchLord42

    (51)

    Проблема была с кешем КОМ объекта враппера, в доках в целом написано, что компонента кешируется на время работы сервера, но вот не сразу дошло, что там что-то типа Singleton паттерна применяется, т.е. моя сборка при первой загрузке не содержала нужного мне конструктора, после того, как я еще раз скормил ей сборку, он продолжал выдавать ексепшен на Activator.CreateInstance, после ребута службы все заработало. Получается еще такой момент, что и Assembly.LoadFrom не перезагружает сборку…иначе бы все работало.

    Проверил еще раз, добавив метод, так же песня, загруженную сборку я удалитьзаменить не могу т.к. поток на нее открыт уже, а вот если переименовать ее и добавить с тем же именем, а потом из враппера вызвать ЗагрузитьСборку, то на нее поток даже и не открывается.

    Reply
  53. Serginio

    Да есть такое дело. И 1C тоже держит COM DLL до конца. А сборку можно выгрузить только с доменом её содержащую. Сейчас все грузится в один домен

    Reply
  54. vgrichuk

    А как корректно освободить память от COM-объекта NetObjectToIDispatch45? Ни Quit, ни Close не находятся.

    Reply
  55. Serginio

    Нужно обнулить ссылку на объект, если он роддеживае IDispose то вызвать Dispose и для очистки совести вызвать сборку мусора

    http://www.forum.mista.ru/topic.php?id=763810&page=3#236

    Reply
  56. denverr

    Добрый день, пишу процедуру для обмена сообщениями используя сокеты, ошибка происходит при отправке: «СокетОтправки.BeginSend», что делаю не так, кто может подсказать?

    Вот кусок кода:

    врап=новый COMОбъект(«NetObjectToIDispatch45»);
    
    //// Соединение с сокетом ////
    IPAddress   = врап.ПолучитьТип(«System.Net.IPAddress»);
    ipAddr  = IPAddress.Parse(IP);
    
    ipEndPoint    = врап.СоздатьОбъект(«System.Net.IPEndPoint», ipAddr, 8888);
    
    NetworkAccess   = врап.ПолучитьТип(«System.Net.NetworkAccess»);
    TransportType   = врап.ПолучитьТип(«System.Net.TransportType»);
    SocketPermission  = врап.ПолучитьТип(«System.Net.SocketPermission»);
    
    AddressFamily  = врап.ПолучитьТип(«System.Net.Sockets.AddressFamily»);
    socketType   = врап.ПолучитьТип(«System.Net.Sockets.SocketType»);
    protocolType  = врап.ПолучитьТип(«System.Net.Sockets.ProtocolType»);
    
    СокетОтправки  = врап.СоздатьОбъект(«System.Net.Sockets.Socket», AddressFamily.InterNetwork, socketType.Stream, protocolType.Tcp);
    ПраваСокета   = врап.СоздатьОбъект(«System.Net.SocketPermission», NetworkAccess.Connect, TransportType.Tcp, «», SocketPermission.AllPorts);
    
    СокетОтправки.NoDelay = Истина;
    
    СокетОтправки.Connect(ipEndPoint);
    
    Сообщить(СокетОтправки.Connected); //Возвращает Истина
    
    ///Теперь формируем строку к отправке
    СтрокаКОтправке = СокрЛП(ПолеВвода); //ПолеВвода — на форме
    СтрокаКОтправке = СтрЗаменить(СтрокаКОтправке, Символы.ПС, «»);
    
    Unicode=Врап.ПолучитьТип(«System.Text.Encoding»).Unicode;
    МассивДанных = Unicode.GetBytes(СтрокаКОтправке);
    
    
    //Сама отправка
    ДелегатCallback = Врап.ПолучитьТип(«System.AsyncCallback»);
    SocketFlags = врап.ПолучитьТип(«System.Net.Sockets.SocketFlags»);
    
    СокетОтправки.BeginSend(МассивДанных, 0, 15000, SocketFlags.None, ДелегатCallback, СокетОтправки);

    Показать

    Reply
  57. Serginio

    Для ДелегатCallback нужно получить реальную ссылку на делегат, а не тип.

    Ессть синхронные методы например https://msdn.microsoft.com/ru-ru/library/w93yy28a(v=vs.110).aspx

    Да и в примерах к статье у меня куча примеров по сокетам

    Reply
  58. realchel

    вопрос не в тему. сори.

    Как во внешней компоненте получить указатель на окно 1С откуда внешняя компонента подключена.

    не нашел примеров на C#(наверно плохо искал)

    Так понимаю надо как то интерфейс определить IExtWndsSupport и вызывать GetAppMainFrame

    Вообще цель простая, активизировать окно 1С.

    Само 1С через внешнюю компоненту генерит мессаджбокс.

    (пользователь сейчас сидит в контакте)

    Пользователь жмет кнопку, и открывается окно 1С.

    Reply
  59. ive

    (1)

    учитьТип(«System.IO.Compression.CompressionMode», «System»).Compre

    Спасибо автору,

    обПотокКомпр = врап.СоздатьОбъект(ПолучитьТип(«System.IO.Compression.GZipStream», «System»),

    обФайлАрхив, врап.ПолучитьТип(«System.IO.Compression.CompressionMode», «System»).Decompress); у меня только выдало ошибку с неверным количеством параметров, заработало так:

    врап.СоздатьОбъект(«System.IO.Compression.GZipStream», обФайлАрхив, CompressionMode.Compress)

    Reply
  60. user785046

    Добрый день. Пользуюсь ВК NetObjetToIDispatch45 из внешней обработки все работает. Попытался запихнуть все в регламентные задания. Ругается на строке: врап=новый COMОбъект(«NetObjectToIDispatch45»);

    {ОбщийМодуль.МодульРегламентныхЗаданий.Модуль(10768)}: Ошибка при вызове конструктора (COMОбъект)

    по причине:

    Отказано в доступе.

    Что можно предпринять в таком случае?

    Reply
  61. Serginio

    Её нужно зарегистрировать на сервере

    Reply
  62. user785046

    Регистрировал.

    Reply
  63. Serginio

    (63) Там еще могут быть проблемы с вызовом сом объектов. Можно попробовать для модуля привелигированный режим установить.

    Reply
  64. Serginio

    Да еще там надо и 64 разрядную Dll регистрировать. Проще запустить РегистрацияКомСервера.exe от администратора.

    Reply
  65. Serginio

    Еще вариант с правами на папку где лежит dll

    Reply
  66. user785046

    Спасибо. РегистрацияКомСервера.exe от имени администратора помогла.

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *