Имя: Пароль:
1C
1C 7.7
v7: Помогите разобраться с одной сборкой .Net.
0 Maximich
 
09.11.16
19:12
Добрый день. Помогите пожалуйста понять почему не хочет работать один из методов сборки .Net

Предыстория: Понадобилось из 7.7 организовать работу с базой mysql на сайте. Есть два варианта:
1) прямой доступ. тут проблем нет, через внешнюю компоненту все работает, но данный метод не подходит из соображений безопасности.
2) через web-сервис. На сайте стоит framework позволяющий работать по протоколу amf3. Нашел решение для .Net https://code.google.com/archive/p/fluorinefx/ которое позволяет настроить обмен данными по протоколу amf. Открыл конфигуратор и множество примеров Serginio1. Удалось загрузить эту сборку, создать объекты и даже проверить работоспособность некоторых методов. Но споткнулся на вызове основного метода.
1 Maximich
 
09.11.16
19:13
Кусок кода из 1С:
net=СоздатьОбъект("NetObjectToIDispatch45");
    сборка = net.ЗагрузитьСборку("C:\Program Files (x86)\FluorineFx\Bin\net\3.5\FluorineFx.dll");
    _netConnection=net.СоздатьОбъект("FluorineFx.Net.NetConnection");
    
    ObjectEncoding = net.ПолучитьТип("FluorineFx.ObjectEncoding");
    _netConnection.ObjectEncoding = ObjectEncoding.AMF3;
    
    _netConnection.Connect("http://127.0.0.1/instrument/eOrder/Amfphp/index.php";);
    _netConnection.Close();
    Сообщить(_netConnection.Connected);
2 Maximich
 
09.11.16
19:17
при вызове метода .Connect выскакивают 3 ошибки:

1) Ошибка в методе Connect Не найден метод "FluorineFx.Net.NetConnection.Connect". mscorlib

2) в System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams)

   в NetObjectToIDispatch45.AutoWrap.InvokeMember(String name, BindingFlags invokeAttr, Binder binder, Object target, Object[] argsOrig, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParameters)

3) InvokeMethod, OptionalParamBinding

Сам метод существует, подозреваю что ругается на строку подключения, может 1С передает ее не в той кодировке ?
3 Serginio1
 
09.11.16
19:47
Выложи FluorineFx.dll Завтра посмотрю.
Возможно нужны еще параметры или тип другой.
4 Garykom
 
гуру
09.11.16
19:51
_netConnection.Connect("http://127.0.0.1/instrument/eOrder/Amfphp/index.php";;);

лишняя ";" в конце перед );
5 Garykom
 
гуру
09.11.16
19:52
(4)+ или это форум парит?
6 Garykom
 
гуру
09.11.16
19:56
кста
This library has been deprecated in favour of https://github.com/astralfoxy/rtmp-sharp.
7 Garykom
 
гуру
09.11.16
19:58
(3) собрать отсюда https://github.com/imiuka/fluorinefx-core
8 Maximich
 
09.11.16
19:59
(4) Это форум. в коде их нет
9 Maximich
 
09.11.16
20:01
(3) https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/fluorinefx/setup.exe
тут и сама dll и исходники/примеры на c# и chm-файлы. Заранее благодарен
10 Maximich
 
09.11.16
20:08
(6) я так понимаю там только исходники ? документации нет, примеров нет, короче для меня еще большая задница )
11 Garykom
 
гуру
09.11.16
20:24
сборка = net.ЗагрузитьСборку("C:\Program Files (x86)\FluorineFx\Bin\net\3.5\FluorineFx.dll");

мне очень не нравится x86 и .Net 3.5
12 Garykom
 
гуру
09.11.16
20:24
(11)+ По хорошему бы пересобрать из исходников под целевую платформу и версию .Net
13 Serginio1
 
09.11.16
20:25
(11) Да это не проблема.
(9) Ща посмотрю
14 Serginio1
 
09.11.16
20:37
Там
public void Connect(string command, params object[] arguments)

Нужно во втором параметре передать нулевой массив

Object=net.ПолучитьТип("System.Object"):
аргументы=net.СоздатьМассив(Object, 0);

_netConnection.Connect("http://127.0.0.1/instrument/eOrder/Amfphp/index.php";,аргументы);
15 Serginio1
 
09.11.16
20:48
или
аргументы=net.СоздатьМассив("System.Object", 0);
16 Serginio1
 
09.11.16
21:42
Кстати http://catalog.mista.ru/public/448668/

Для того, что бы исправлять такие ошибки я добавил  метод ВыполнитьМетод
Который принимает первым параметром тип или  объект
Вторым параметром имя метода, а дальше параметры для запрашиваемого метода
 
Сообщить(Врап.ВыполнитьМетод(String,"Format","загружено {0} из {1} байт. {2}  % complete...",
        e.BytesReceived,
        e.TotalBytesToReceive,
        e.ProgressPercentage));


В твоем случае это будет
net.ВыполнитьМетод(_netConnection,"Connect",("http://127.0.0.1/instrument/eOrder/Amfphp/index.php";);
17 Serginio1
 
09.11.16
23:30
Да еще для 77 нужно прописать

net.УстЭтоСемерка()

и так как в семерке нет int то

аргументы=net.СоздатьМассив("System.Object",net.ToInt(0));
18 Maximich
 
10.11.16
02:42
(17) Спасибо за советы.
при вызове
аргументы=net.СоздатьМассив("System.Object",net.ToInt(0));
выскакивает ошибка
Ошибка в методе [DISPID=0] Не найден метод "System.Int32.ToString". mscorlib

но при этом спокойно отработал код
аргументы=net.СоздатьМассив("System.Object", 0);
_netConnection.Connect("http://127.0.0.1/instrument/eOrder/Amfphp/index.php";,аргументы);

а вот дальше возникла другая проблема - как получить результат вызова методов

в документации приведен пример

_netConnection = new NetConnection();
_netConnection.ObjectEncoding = ObjectEncoding.AMF3;
_netConnection.NetStatus += new NetStatusHandler(_netConnection_NetStatus);
_netConnection.Connect(“http://localhost:1781/SilverlightApplicationWeb/Gateway.aspx”);
...
_netConnection.Call("ServiceLibrary.MyDataService.GetCustomers", new GetCustomersHandler(), new object[] { txtSearch.Text });

сами методы Call и Connect ничего не возвращают, а вместо этого вызываются функции _netConnection_NetStatus и GetCustomersHandler в которых и идет обработка результатов или ошибок. Как это можно реализовать в случае вызова из 1С ?
19 Maximich
 
10.11.16
04:46
чую что нужно копать в сторону "СоздатьОберткуДляСобытий77"
20 Serginio1
 
10.11.16
07:41
Нужно подключать события

.NET(C#) для 1С. Динамическая компиляция класса обертки для использования .Net событий в 1С через ДобавитьОбработчик или ОбработкаВнешнегоСобытия

http://catalog.mista.ru/public/417830/

Там есть пример и для 7.7
В обработке можно получить описания обработчиков в 1С
21 Maximich
 
10.11.16
08:21
(20) Сергей, а что в моем случае будет обертываемым объектом ?

Перем net;
Перем ОберткаСобытий;

Функция СоздатьОбертку(ОбертываемыйОбъект)
    ПодключитьВнешнююКомпоненту("AddIn.GlobalContext1C");
    объект = СоздатьОбъект("AddIn.GlobalContext1C");
    ГлобальныйКонтекст= объект.ГлобальныйКонтекст;
    ОберткаСобытий= net.СоздатьОберткуДляСобытий77(ОбертываемыйОбъект,ГлобальныйКонтекст);
КонецФункции

//*******************************************
Процедура Сформировать()
    net=СоздатьОбъект("NetObjectToIDispatch45");
    
    сборка = net.ЗагрузитьСборку("C:\Program Files (x86)\FluorineFx\Bin\net\3.5\FluorineFx.dll");
    _netConnection=net.СоздатьОбъект("FluorineFx.Net.NetConnection");
    
    ObjectEncoding     = net.ПолучитьТип("FluorineFx.ObjectEncoding");
    NetStatus        = net.ПолучитьТип("FluorineFx.ObjectEncoding");
    _netConnection.ObjectEncoding = ObjectEncoding.AMF3;
    net.УстЭтоСемерка();
    
    //аргументы=net.СоздатьМассив("System.Object",net.ToInt(0));
    аргументы=net.СоздатьМассив("System.Object", 0);
    _netConnection.Connect("http://127.0.0.1/instrument/eOrder/Amfphp/index.php";,аргументы);
    СоздатьОбертку(_netConnection);
    _netConnection.Close();
КонецПроцедуры

Процедура ОбработкаВнешнегоСобытия(Источник, Событие, Данные)
  Сообщить("Внешнее событие: Источник="+Источник+"  Событие="+Событие+"Данные="+Данные);
КонецПроцедуры

Ошибка:
ОберткаСобытий= net.СоздатьОберткуДляСобытий77(ОбертываемыйОбъект,ГлобальныйКонтекст);
mscorlib: Адресат вызова создал исключение.
22 Serginio1
 
10.11.16
08:25
_netConnection

Через час посмотрю.
23 Maximich
 
10.11.16
08:26
или мне сначала нужно создать объект NetStatusHandler и именно к нему применить этот код ?
24 Serginio1
 
10.11.16
09:56
Нет посмотри примеры в отчете ТестКомпиляцииСобытий.ert
Там кстати и можно получить описание событий

_netConnection=net.СоздатьОбъект("FluorineFx.Net.NetConnection");
СоздатьОбертку(_netConnection);
25 Serginio1
 
10.11.16
10:07
В отчете ТестКомпиляцииСобытий.ert
Устанавливаешь поля
ПолноеИмяКласса
FluorineFx.Net.NetConnection

ПолноеИмяФайла
C:\Program Files (x86)\FluorineFx\Bin\net\3.5\FluorineFx.dll

И жмякаешь на кнопку ПолучитьОписаниеМодулей
26 Serginio1
 
10.11.16
10:08
Получаешь описание всех событий

Перем врап,ОберткаСобытий;

           Функция СоздатьОбертку(ОбертываемыйОбъект)
            ПодключитьВнешнююКомпоненту("AddIn.GlobalContext1C");
            объект = СоздатьОбъект("AddIn.GlobalContext1C");
            ГлобальныйКонтекст = объект.ГлобальныйКонтекст;

            ОберткаСобытий = врап.СоздатьОберткуДляСобытий77(ОбертываемыйОбъект,ГлобальныйКонтекст);
           КонецФункции // СоздатьОбертку



// Свойства ОберткаСобытий.ПоследняяОшибка
//Событие:String Имя События в котором произошло исключение
//Данные:object Параметры события
//ИсключениеСобытия:Exception Ошибка произошедшая при вызове события
Функция ОшибкаСобытия()
    ПоследняяОшибка=ОберткаСобытий.ПоследняяОшибка;
    Сообщить("Не обработано событие "+ПоследняяОшибка.Событие);
    Сообщить(Врап.ВСтроку(Шаблон("[ОберткаСобытий." + ПоследняяОшибка.Событие + "]")));
    Сообщить("Ошибка");
    Сообщить(врап.ВСтроку(ПоследняяОшибка.Исключение))
КонецФункции  
//  Свойства ОберткаСобытий.NetStatus
// sender:System.Object
// e:FluorineFx.Net.NetStatusEventArgs

            Функция NetStatus()
               Сообщить("NetStatus "+Врап.ВСтроку(ОберткаСобытий.NetStatus));
            КонецФункции

//  Свойства ОберткаСобытий.OnConnect
// sender:System.Object
// e:System.EventArgs

            Функция OnConnect()
               Сообщить("OnConnect "+Врап.ВСтроку(ОберткаСобытий.OnConnect));
            КонецФункции

//  Свойства ОберткаСобытий.OnDisconnect
// sender:System.Object
// e:System.EventArgs

            Функция OnDisconnect()
               Сообщить("OnDisconnect "+Врап.ВСтроку(ОберткаСобытий.OnDisconnect));
            КонецФункции




Процедура ПриОткрытии()
    врап=СоздатьОбъект("NetObjectToIDispatch45");

КонецПроцедуры // ПриОткрытии
               //======================================================================
Процедура ОбработкаВнешнегоСобытия(Источник, ИмяСобытия, Данные)
             Если Источник = "FluorineFx_Net_NetConnection" Тогда

                  Шаблон("[" + ИмяСобытия + "()]");
            КонецЕсли;
            КонецПроцедуры // ОбработкаВнешнегоСобытия
27 Serginio1
 
10.11.16
10:27
Пот попробуй. У меня какие то проблемы с VS

//*******************************************

Перем врап,ОберткаСобытий;

           Функция СоздатьОбертку(ОбертываемыйОбъект)
            ПодключитьВнешнююКомпоненту("AddIn.GlobalContext1C");
            объект = СоздатьОбъект("AddIn.GlobalContext1C");
            ГлобальныйКонтекст = объект.ГлобальныйКонтекст;

            ОберткаСобытий = врап.СоздатьОберткуДляСобытий77(ОбертываемыйОбъект,ГлобальныйКонтекст);
           КонецФункции // СоздатьОбертку



// Свойства ОберткаСобытий.ПоследняяОшибка
//Событие:String Имя События в котором произошло исключение
//Данные:object Параметры события
//ИсключениеСобытия:Exception Ошибка произошедшая при вызове события
Функция ОшибкаСобытия()
    ПоследняяОшибка=ОберткаСобытий.ПоследняяОшибка;
    Сообщить("Не обработано событие "+ПоследняяОшибка.Событие);
    Сообщить(Врап.ВСтроку(Шаблон("[ОберткаСобытий." + ПоследняяОшибка.Событие + "]")));
    Сообщить("Ошибка");
    Сообщить(врап.ВСтроку(ПоследняяОшибка.Исключение))
КонецФункции  
//  Свойства ОберткаСобытий.NetStatus
// sender:System.Object
// e:FluorineFx.Net.NetStatusEventArgs

            Функция NetStatus()
               Сообщить("NetStatus "+Врап.ВСтроку(ОберткаСобытий.NetStatus));
            КонецФункции

//  Свойства ОберткаСобытий.OnConnect
// sender:System.Object
// e:System.EventArgs

            Функция OnConnect()
               Сообщить("OnConnect "+Врап.ВСтроку(ОберткаСобытий.OnConnect));
            КонецФункции

//  Свойства ОберткаСобытий.OnDisconnect
// sender:System.Object
// e:System.EventArgs

            Функция OnDisconnect()
               Сообщить("OnDisconnect "+Врап.ВСтроку(ОберткаСобытий.OnDisconnect));
            КонецФункции




Процедура ПриОткрытии()
    врап=СоздатьОбъект("NetObjectToIDispatch45");
    врап.УстЭтоСемерка();
КонецПроцедуры // ПриОткрытии
               //======================================================================
Процедура ОбработкаВнешнегоСобытия(Источник, ИмяСобытия, Данные)
             Если Источник = "FluorineFx_Net_NetConnection" Тогда

                  Шаблон("[" + ИмяСобытия + "()]");
            КонецЕсли;
            КонецПроцедуры // ОбработкаВнешнегоСобытия  

Процедура Сформировать()


    
ПутьКСборке="C:\Program Files (x86)\FluorineFx\Bin\net\3.5\FluorineFx.dll";
    сборка = врап.ЗагрузитьСборку(ПутьКСборке);
NetConnection=Врап.ПолучитьТипИзСборки("FluorineFx.Net.NetConnection",ПутьКСборке);
    _netConnection=врап.СоздатьОбъект(NetConnection);
     СоздатьОбертку(_netConnection);
    

    ObjectEncoding     = врап.ПолучитьТип("FluorineFx.ObjectEncoding");

    NetStatus        = врап.ПолучитьТип("FluorineFx.ObjectEncoding");

    _netConnection.ObjectEncoding = ObjectEncoding.AMF3;

    

    

    аргументы=врап.СоздатьМассив("System.Object",врап.ToInt(0));

    аргументы=врап.СоздатьМассив("System.Object", 0);

  //  _netConnection.Connect("http://127.0.0.1/instrument/eOrder/Amfphp/index.php";;,аргументы);

  

   // _netConnection.Close();

КонецПроцедуры
28 Serginio1
 
10.11.16
12:32
Нужно дать права на папку C:\Program Files (x86)\FluorineFx\Bin\net\3.5\
с полным доступом или запустить 1С от администратора
29 Maximich
 
10.11.16
13:28
(28) Спасибо.

Ошибок не вылетает, но правда и событий никаких не появляется, ни при Connect, ни при Close. Короче ОбработкаВнешнегоСобытия даже не вызывается ни разу. )

у меня в коде отсутствует аналог _netConnection.NetStatus += new NetStatusHandler(_netConnection_NetStatus);
может в этом причина ?
30 Maximich
 
10.11.16
13:30
и еще вопрос немного не по теме. А есть ли в природе софтинка каторая бы показавала инфу как "Обозреватель объектов" в VS ?

Ну и уже по теме. Какаие типы данных можно передавать/получать из 1С в .Net ? Стока, число это понятно, а ТЗ ?
31 Maximich
 
10.11.16
13:44
Или я туплю и мне сгенерированный код на c# нужно скомпилировать ?

И странно что всего три события
NetStatus, OnConnect и OnDisconect

а как-же события метода Call ? там же должен возвращаться результат или тут событий уже нет ?
32 Serginio1
 
10.11.16
13:59
Ты пробовал использовать ТестКомпиляцииСобытий.ert из 25?
Там формируется и компилируется такой файл

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Threading;
using System.Threading.Tasks;

[Guid("ab634004-f13d-11d0-a459-004095e1daea"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IAsyncEvent
        {
            void SetEventBufferDepth(int lDepth);
            void GetEventBufferDepth(ref int plDepth);
            void ExternalEvent(string bstrSource, string bstrMessage, string bstrData);
            void CleanBuffer();
        }

        public class ВрапперДляFluorineFx_Net_NetConnection77
    {
        FluorineFx.Net.NetConnection РеальныйОбъект;
        public object NetStatus;
public object OnConnect;
public object OnDisconnect;


      
        private SynchronizationContext Sc;
        IAsyncEvent СобытиеДля1С;
        private Object thisLock = new Object();
        public object ПоследняяОшибка;
        public   ВрапперДляFluorineFx_Net_NetConnection77(Object ГлобальныйКонтекст, FluorineFx.Net.NetConnection РеальныйОбъект)
          {

            СобытиеДля1С = ГлобальныйКонтекст as IAsyncEvent;
            if (SynchronizationContext.Current == null)
                SynchronizationContext.SetSynchronizationContext(new WindowsFormsSynchronizationContext());

            Sc = SynchronizationContext.Current;


            this.РеальныйОбъект = РеальныйОбъект;
            
            РеальныйОбъект.NetStatus += (sender,e) =>
            {
                  NetStatus =  new { sender=sender,e=e};
                ОтослатьСобытие("NetStatus");
            };

РеальныйОбъект.OnConnect += (sender,e) =>
            {
                  OnConnect =  new { sender=sender,e=e};
                ОтослатьСобытие("OnConnect");
            };

РеальныйОбъект.OnDisconnect += (sender,e) =>
            {
                  OnDisconnect =  new { sender=sender,e=e};
                ОтослатьСобытие("OnDisconnect");
            };



        }

        void ОтослатьСобытие(string ИмяСобытия)
{


    Task.Run(() =>
    {

        lock (thisLock)
        {

            try
            {
                Sc.Send(d => СобытиеДля1С.ExternalEvent("FluorineFx_Net_NetConnection", ИмяСобытия, ""), null);
            }

            catch (Exception ex)
            {
                try
                {
                    ПоследняяОшибка = new { Событие = ИмяСобытия, Исключение = ex };
                    Sc.Send(d => СобытиеДля1С.ExternalEvent("FluorineFx_Net_NetConnection", "ОшибкаСобытия", ""), null);
                }
                catch (Exception)
                {
                }

            }
        }

    });
}

public static object СоздатьОбъект(Object ГлобальныйКонтекст, FluorineFx.Net.NetConnection РеальныйОбъект)
{

    return new ВрапперДляFluorineFx_Net_NetConnection77(ГлобальныйКонтекст, РеальныйОбъект);
}
    }
33 Serginio1
 
10.11.16
14:01
В 27 я закоментировал
//  _netConnection.Connect("http://127.0.0.1/instrument/eOrder/Amfphp/index.php";,аргументы);

раскомментируй, а
// _netConnection.Close();

так как соединение должно принимать события
34 Serginio1
 
10.11.16
14:08
35 Serginio1
 
10.11.16
14:10
Надо тогда еще и к GetCustomersHandler события подключать
36 Maximich
 
10.11.16
14:16
(32) я просто даже не подозреваю что с ним делать )
37 Serginio1
 
10.11.16
14:18
Терерь осталось понять откуда берется new GetCustomersHandler() он должен реализовать
public interface IPendingServiceCallback
    {
        void ResultReceived(IPendingServiceCall call);
    }
38 Maximich
 
10.11.16
14:20
(37) А что мне нужно сделать с Описанием модуля на C# который сгенерировался обработкой ?
39 Serginio1
 
10.11.16
14:22
(38) Ничего. Он динамически компилируется.
Но вот если ты хочешь добавить еще код, то можешь создать сборку и добавить этот код и еще дополнительную обвязку
40 Serginio1
 
10.11.16
14:30
Попробуй для начала создать проект в VS, а затем уж возиться с 1С