Вход | Регистрация
    1  2  3  4  5  6  7   
Работа :: Работа

Неспешно ищу работу. 1С + .Net

[aka AMIGO, 07.06.16 - 08:02]
Неспешно ищу работу. 1С + .Net
Я
   Serginio1
 
10.05.16 - 10:42
20 лет программирую на 1С и 13 на C#. Давно интегрирую .Net в 1С для расширения возможностей. Вот мои разработки http://catalog.mista.ru/profile/82159/public/
Основные это Использование сборок .NET в 1С 7.x b 8.x и . Динамическая компиляция класса обертки для использования .Net событий в 1С через ДобавитьОбработчик или ОбработкаВнешнегоСобытия
Если в 8.х есть множество возможносей, то для 7.7 функционал очень скуден.
Для 8.x часто испльзуется доступ к Вэб сервисам неподдерживаемыми 1С. Например Ws-протоколы и тд. Можно использовать асинхронные HTTP запросы, multipart/form-data итд.
Использовать Push-уведомления. Есть множество библиотек для разбора HTML (AngleShart, Silenium)
  При  работе с различными EDI есть уже готовые библиотеки на . Net которые можно использовать как в 7.7 так и в 8.x. В общем возможностей для интеграции огромное количество.
Есть опыт программирования для ТСД на WM. Скоро появятся ТСД на Windows mobile 10 где с использованием  UWP и Xamarin для других осей
Знаний много, но на нынешней работе не могу и малую толику возможностей использовать.
   Serginio1
 
501 - 06.06.16 - 16:49
Попробовал  вызвать CoreCLr из натива.

создал тестовый класс

public class Program
    {
        public static object ExecuteMethod(object objOrig, string MethodName, params object[] argsOrig)
        {
            object res = null;
           // var obj = objOrig;
            Type T = objOrig.GetType();

            var list = new List<Type>();

            foreach (var obj in argsOrig)
                list.Add(obj.GetType());

            var Method=T.GetMethod(MethodName, list.ToArray());

            res = Method.Invoke(objOrig, argsOrig);

            System.Diagnostics.Debug.WriteLine("ExecuteMethod = " + res.ToString());
            return res;

        }
    
    public static int TestFunction(int i)
    {
        // Console.OutputEncoding = Encoding.UTF8;

        var rn = new Random(i);

         //   int res = rn.Next(1000);
            int res =(int)ExecuteMethod( rn,"Next",10000);
                   return res;

    }
    }
   Serginio1
 
502 - 06.06.16 - 16:54
Пример взял отсюда http://www.fancy-development.net/hosting-net-core-clr-in-your-own-process

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

typedef int (STDMETHODCALLTYPE *ManagedMethod)(int);
HRESULT  CreateDelegate2(ICLRRuntimeHost2* pCLRRuntimeHost, DWORD appDomainID, wstring AssemblyName, wstring ClassName, wstring MethodName, INT_PTR *fnPtr)
{

    HRESULT    hr = pCLRRuntimeHost->CreateDelegate(
        appDomainID,
        AssemblyName.c_str(),
        ClassName.c_str(),
        MethodName.c_str(),
        (INT_PTR*)fnPtr);

    return hr;

}


И вызов

ManagedMethod pTestFunction;

    hr = CreateDelegate2(pCLRRuntimeHost, domainId, L"CoreClrDLL", L"CoreClrDLL.Program", L"TestFunction", (INT_PTR*)&pTestFunction);
    if (FAILED(hr))
    {
        printf_s("Failed to create a delegate to the managed entry point: (%d).\n", hr);
    
    }
    else
    printf_s("result method  pTestFunction(555) : (%d).\n", pTestFunction(555));
   Serginio1
 
503 - 06.06.16 - 17:16
Нет InvokeMember придется вручную искать перегруженную функцию.

Вобщем оболочку можно сделать
   Serginio1
 
504 - 10.06.16 - 10:11
0

голос против

accept


В поисках замены InvokeMember мне посоветовали использовать DLR http://rsdn.ru/forum/dotnet/6464866.1

Суть такова, что бы заставить искать подходящий метод DLR по количеству аргументов.

Можно нагенерировать методы по количеству параметров например до 16 и для каждого типа и имени метода сохранять и вызывать. http://rsdn.ru/forum/dotnet/6465142.1

Но есть недостаток, этот подход не касается ref и out параметров.

В итоге решил сам искать нужный метод. Здесь набросок того как искать.

http://rsdn.ru/forum/dotnet/6466131.1

И при таком подходе можно добавить для каждого типа типы содержащие методы расширители и их использовать при поиске нужно сигнатуры. Кроме того можно использовать дженерик методы тип которых можно определить по типу параметров.
   Serginio1
 
505 - 15.06.16 - 12:37
Добил поиск метода
http://rsdn.ru/forum/dotnet/6471273.1

Поэкспериментировал с CallBack


[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
         delegate void myDelegate(IntPtr thisptr);

  public static void TestCallBack(IntPtr Str,IntPtr FuncPtr)
        {

            myDelegate fun = Marshal.GetDelegateForFunctionPointer<myDelegate>(FuncPtr);

            fun(Str);

            var str = Marshal.PtrToStringUni(Str);
        }



На С++

typedef void(STDMETHODCALLTYPE *ManagedTestCallBack)(const wchar_t*, void(*) (const wchar_t*));

    typedef void(STDMETHODCALLTYPE *ManagedTestCallBack)(const wchar_t*, void(*) (const wchar_t*));
    
void TestCallBack(const wchar_t* str)
{

    printf_s("Return string %S.\n", str);
}


    ManagedTestCallBack pTestCallBack;
    
    
    hr = CreateDelegate2(pCLRRuntimeHost, domainId, L"CoreClrDLL", L"CoreClrDLL.Program", L"TestCallBack", (INT_PTR*)&pTestCallBack);
        if (FAILED(hr))
        {
            printf_s("Failed to create a delegate to the managed entry point: (%d).\n", hr);
    
        }
        else
        {
            wchar_t* str = L"Test str from unmanaged";
            pTestCallBack(str, TestCallBack);
        }

ManagedTestCallBack pTestCallBack;


hr = CreateDelegate2(pCLRRuntimeHost, domainId, L"CoreClrDLL", L"CoreClrDLL.Program", L"TestCallBack", (INT_PTR*)&pTestCallBack);
    if (FAILED(hr))
    {
        printf_s("Failed to create a delegate to the managed entry point: (%d).\n", hr);

    }
    else
    {
        wchar_t* str = L"Test str from unmanaged";
        pTestCallBack(str, TestCallBack);
    }


Работает. Так что можно память выделять на стороне натива и использовать обратные вызовы.
   Serginio1
 
506 - 15.06.16 - 12:38
   Serginio1
 
507 - 16.06.16 - 14:32
Сделал маршалинг из _tVariant натива в манагед
http://rsdn.ru/forum/dotnet/6472655.1
   Gary417
 
508 - 16.06.16 - 14:59
пора уж блог заводить, а то на форуме это выгдядит "Тихо сам с собою, я веду беседу" (с)
   Serginio1
 
509 - 16.06.16 - 15:04
   Кирпич
 
510 - 16.06.16 - 15:08
(509) а чо такое "Элемент + 44"?
   Serginio1
 
511 - 16.06.16 - 15:10
(510) Это смещене vt
   Serginio1
 
512 - 22.06.16 - 10:28
В общем выхожу на финишную прямую
http://rsdn.ru/forum/dotnet/6478527.1
   Serginio1
 
513 - 23.06.16 - 11:50
Наткнулся на то, что двоичные данные нельзя передать.
Может есть обходной путь?
   Garykom
 
514 - 23.06.16 - 11:52
(513) В строку их
   Serginio1
 
515 - 23.06.16 - 13:00
(514) Это понятно. Интересно а почему ДД то нельзя?
Получить можно, но передать нет?
   Serginio1
 
516 - 24.06.16 - 10:49
Сделал

Перем   Врап,СсылкаНаДомен;
Функция СоздатьОбъектПоСсылке(Ссылка)

рез = Новый("AddIn.NetObjectToNative.NetObjectToNative");
рез.УстановитьСсылку(СсылкаНаДомен,Ссылка);    
возврат  рез
КонецФункции // СоздатьОбъектПоСсылке()


Процедура КнопкаВыполнитьНажатие(Кнопка)
            
СылкаСБ=Врап.Новый("System.Text.StringBuilder","Первая Строка");
//Сообщить(СылкаСБ);

СсылкаCultureInfo=Врап.ПолучитьТип("System.Globalization.CultureInfo");

    СсылкаCultureInfo=Врап.Новый(СсылкаCultureInfo,"es-ES");

//
    СultureInfo=СоздатьОбъектПоСсылке(СсылкаCultureInfo);
    
    СБ=СоздатьОбъектПоСсылке(СылкаСБ);
    Сообщить(СБ.Capacity);
    Сообщить(СБ.ПолучитьСсылку());
    
    СсылкаInvariantCulture=СultureInfo.InvariantCulture;

    // К сожалению 1С вызывает метод имеющий возвращаемое значение как функцию даже если вызов идет как процедура
    //Нужно очистить ссылку в списке объектов
    ссылка=Сб.Append("Новая Строка"); Врап.ОчиститьСсылку(ссылка);
    ссылка=Сб.AppendLine();   Врап.ОчиститьСсылку(ссылка);
    ссылка=Сб.Append("Вторая Строка"); Врап.ОчиститьСсылку(ссылка);
    ссылка=Сб.AppendLine();     Врап.ОчиститьСсылку(ссылка);

    ссылка=Сб.AppendFormat("AppendFormat {0}, {1}, {2}, {3}, {4},", "Строка", 21, 45.89, ТекущаяДата(),истина );   Врап.ОчиститьСсылку(ссылка);
    ссылка=Сб.AppendLine(); Врап.ОчиститьСсылку(ссылка);

    // Так как в параметрах можно передавать только простые типы закодирум ссылку на объект в строку
    ссылка=Сб.AppendFormat(СсылкаCultureInfo,"AppendFormat {0}, {1}, {2}, {3}, {4},", "Строка", 21, 45.89, ТекущаяДата(),истина );  Врап.ОчиститьСсылку(ссылка);
    ссылка=Сб.AppendLine(); Врап.ОчиститьСсылку(ссылка);

    ссылка=Сб.AppendFormat(СсылкаInvariantCulture,"AppendFormat {0}, {1}, {2}, {3}, {4},", "Строка", 21, 45.89, ТекущаяДата(),истина );
    Врап.ОчиститьСсылку(СсылкаInvariantCulture);





    Сообщить(СБ.ToString());
    СБ.Capacity=40;
    Сообщить(СБ.Capacity);

    // Очистка ссылок СБ и  СultureInfo осуществляется внутри ВК
    КонецПроцедуры

Процедура ПриОткрытии()


ИмяФайла="d:\MyPrograms\VNCOMP83\AddInNetObjectToNative\AddInNetObjectToNative\Debug\AddInNetObjectToNative.dll";

    ПодключитьВнешнююКомпоненту(ИмяФайла, "NetObjectToNative",ТипВнешнейКомпоненты.Native);
    Врап = Новый("AddIn.NetObjectToNative.LoaderCLR");
    CoreClrDir="c:\Program Files\DNX\runtimes\dnx-coreclr-win-x86.1.0.0-rc1-update1\bin\";
    ДиректорияNetObjectToNative="d:\MyPrograms\VNCOMP83\NetObjectToNative\NetObjectToNative\bin\Debug\";
    
    СсылкаНаДомен=Врап.СоздатьОбертку(CoreClrDir,ДиректорияNetObjectToNative,"");
    
КонецПроцедуры
   Serginio1
 
517 - 24.06.16 - 10:57
Модераторам. Можно код выделить?

Пока сделал для Win. Допилю еще вызовы методов расширений. Вызов дженериков определяемых по типу.

Но по моему никому это не надо. А жалко.
Под линукс проще писать расширения будет.

Чуть позже наришу статью и выложу исходники
   Кирпич
 
518 - 24.06.16 - 11:08
Я себе сделал типа такое и мне хватает.

Прог = " //
|public static class AddinHelloClass
|{
|    public static int AddinМойМетод(ref string s)
|    {
|        s = ""hello"";
|        return 100500;
|    }           
|}";

Шарп.ДобавитьМодуль(Прог);
Шарп.Компилировать();    
стр = "раз два три";
ч =Шарп.МойМетод(стр);
Сообщить(стр);
Сообщить(ч);
   Кирпич
 
519 - 24.06.16 - 11:11
т.е. тупо готовую программу в виде текста компилирую и когда надо выполняю. без всяких глазоломательных оберток. текст модулей можно хранить в БД, в макетах или файлах.
   Garykom
 
520 - 24.06.16 - 11:12
(518) Давно на это и намекал )) и не надо больше никаких извратов.

Точнее параметры туда и результаты оттуда еще как то и все.
   Garykom
 
521 - 24.06.16 - 11:14
(519) ВК NativeAPI и классик и чтобы под linux на mono тоже работало на сервере
И на ИС продавать поддержку или наборы готовых "текстов программы"
   Кирпич
 
522 - 24.06.16 - 11:15
(520) ну результаты оттуда идут нормально. сделаю на досуге чтобы можно было из шарпа внешнее событие вызывать. больше особо ничего и не требуется.
   Serginio1
 
523 - 24.06.16 - 11:16
(519) А как события прикручивать?

Ну если ты видел у меня этот подход много где используется.
В том числе и Scripting API
   Кирпич
 
524 - 24.06.16 - 11:17
(523) "у меня этот подход много где используется" ну и правильно. больше ничего и не надо, имхо.
   Garykom
 
525 - 24.06.16 - 11:18
(523) Да у тебя получается мощнее не просто вызов стороннего кода из 1С, а полноценное взаимодействие с этим кодом.
По сути система получается из 2 языков одновременно работающих 1С и .Net
   Кирпич
 
526 - 24.06.16 - 11:19
(523) события сделаю. там ничего сложного не вижу. только нужно решить как удобнее сделать.
   Garykom
 
527 - 24.06.16 - 11:19
(525)+ А в (518) работает только по очереди или 1С или .Net
   Serginio1
 
528 - 24.06.16 - 11:20
   Serginio1
 
529 - 24.06.16 - 11:22
(526) Так у меня это все есть.
Да и суть то новой компонеты в том, что это работает без COM и может работать на Линкусе.
   Кирпич
 
530 - 24.06.16 - 11:26
(529) ну у меня тоже Native API. На счет Линукса не знаю, может и на Линуксе работает. :)
Но писать как в (516) вы меня не заставите. Я лучше напишу и отлажу в VS, а потом скопипастю в 1С.
 
 
   Serginio1
 
531 - 24.06.16 - 11:57
(530)  Ну я никого не заставляю.

Проблемы в архитектуре ВК
1. Вызов метода как процедуры должен и вызвать метод CallAsProc
2. Добавить возможность передавать в параметрах ВК и возвращать ВК что бы обойтись без ссылок.
А так по линуксом это значительно проще  чем писать отдельно ВК
   Serginio1
 
532 - 24.06.16 - 12:00
   Serginio1
 
533 - 24.06.16 - 12:40
Кстати в примере ошибка прокралась
СылкаСБ=Врап.Новый("System.Text.StringBuilder","Первая Строка");
//Сообщить(СылкаСБ);

СсылкаCultureInfo=Врап.ПолучитьТип("System.Globalization.CultureInfo");

    СсылкаCultureInfo=Врап.Новый(СсылкаCultureInfo,"es-ES");
// Здесь уже СсылкаCultureInfo указывает на объект

//
    СultureInfo=СоздатьОбъектПоСсылке(СсылкаCultureInfo);

И СultureInfo это не тип а объект СсылкаCultureInfo,"es-ES");  

  
// Вызываем статический метод    
    СсылкаInvariantCulture=СultureInfo.InvariantCulture;

он проходит, так как нет проверки на статик.

Я думаю так и оставить. Можно из объекта как в Delphi вызывать и методы объекта и статические
   Gary417
 
534 - 24.06.16 - 12:43
(533) <Врап.Новый(СсылкаCultureInfo,"es-ES"); >

Hablo espanol?
   Gary417
 
535 - 24.06.16 - 12:43
+тьфу habla espanol?
   Serginio1
 
536 - 24.06.16 - 12:46
Наверное взял из примера

es-ES

Испанский (Испания)

Международная: 0x00000C0A

Традиционные: 0x0000040A
   Кирпич
 
537 - 24.06.16 - 13:13
(532) и чо там смотреть? опять 8 листов русско-турецкого кода на который я смотреть не могу. а что мне нужно я и так знаю.
   Кирпич
 
538 - 24.06.16 - 13:14
(531) "Вызов метода как процедуры должен и вызвать метод CallAsProc"

ты хочешь сказать, что 1с не вызывает CallAsProc?
у меня вызывает вроде.
   Serginio1
 
539 - 24.06.16 - 13:36
(538) Вызывает если HasRetVal возвращает ложь.

Но например если я вызываю
Сб.AppendLine(); // А у него есть возвращаемое значение this

То даже если метод возвращает значение нужно вызывать
CallAsProc

Тогда не нужно оборачивать результат.
   Кирпич
 
540 - 24.06.16 - 14:20
(539) ну это так и должно быть. как говорил один мой шеф: "если решение некрасивое, то оно обычно и неправильное" :)
   Garykom
 
541 - 24.06.16 - 14:25
(540) Даже неправильные решения могут быть востребованными и хорошо оплачиваемыми.
   Кирпич
 
542 - 24.06.16 - 15:43
(541) это ты намекаешь на сборнуюю РФ по футболу?
   Кирпич
 
543 - 24.06.16 - 15:50
СсылкаCultureInfo=Врап.ПолучитьТип("System.Globalization.CultureInfo");

Вот автор, например, предлагает после каждой выпитой рюмки, ездить в гараж на электричке за соленым огурцом, а я предлагаю съездить в гараж, привезти банку огурцов и сидеть спокойно выпивать и закусывать. Какой метод правильный? Я думаю мой.
   Serginio1
 
544 - 24.06.16 - 17:31
Правильны это тот который удобный.
Еще раз у меня используется Scripting Api из Каропки. При этом я могу передавать любые объекты. В том числе и объекты 1С.
Могу пользоваться IronPithon. Только это не относится к теме. А именно кросплатформенная ВК использования классов .Net в 1С.

А твой метод использует Hosting API?
   Serginio1
 
545 - 24.06.16 - 17:33
(543) Чуть позже сделаю загрузку классов из сторонних сторонних сборок.
   oleg_km
 
546 - 24.06.16 - 18:11
(543) Твой метод реализует процедурный подход. А метод автора объектный. Ты можешь сохранить объект дот нета допустим в реквизит формы и повторно его использовать в течении жизни формы?
   Serginio1
 
547 - 25.06.16 - 16:53
(543) На самом деле я начал использовать классы .Net для использования Вэб сервисов неподдерживаемых 1С с кучей классов которые используют данные 1С и записываются. Все построено на классах. Так вот выбор был делать ручную обертку или автоматическу. Твой подход с кимпиляцией текста не подходит. Нужно сериализовывать объекты десериализовывать. Для передачи в методахь и возврата. Это частный подход который используется как при компиляции событий, так и для заполнения данных 1С так и для получения делегатов
   Serginio1
 
548 - 25.06.16 - 16:53
(543) Для упрощения получения объектов можно создать методы

Функция Ъ(Ссылка)
    рез = Новый("AddIn.NetObjectToNative.NetObjectToNative");
    рез.УстановитьСсылку(СсылкаНаДомен,Ссылка);    
    возврат  рез
КонецФункции // СоздатьОбъектПоСсылке()
Функция ъНовый(стр)
    возврат ъ(Врап.Новый(стр));
КонецФункции

Функция ъТип(стр)
      возврат ъ(Врап.ПолучитьТип(стр));
КонецФункции

Процедура ТестСокпВызоваНажатие(Элемент)
    // Вставить содержимое обработчика.
    СБ=ъНовый("System.Text.StringBuilder");
    CultureInfo=ъТип("System.Globalization.CultureInfo");
    CultureInfoES=ъ(Врап.Новый(CultureInfo.ПолучитьСсылку(),"es-ES"));
    Сообщить(CultureInfoES.ПолучитьСсылку());

    
    Сообщить(СБ.Capacity);
    Сообщить(СБ.ПолучитьСсылку());
    
   InvariantCulture=ъ(CultureInfo.InvariantCulture);
   ссылка= InvariantCulture.ПолучитьСсылку();

    // К сожалению 1С вызывает метод имеющий возвращаемое значение как функцию даже если вызов идет как процедура
    //Нужно очистить ссылку в списке объектов
    ссылка=Сб.Append("Новая Строка"); Врап.ОчиститьСсылку(ссылка);
    ссылка=Сб.AppendLine();   Врап.ОчиститьСсылку(ссылка);
    ссылка=Сб.Append("Вторая Строка"); Врап.ОчиститьСсылку(ссылка);
    ссылка=Сб.AppendLine();     Врап.ОчиститьСсылку(ссылка);
    
    ссылка=Сб.AppendFormat("AppendFormat {0}, {1}, {2}, {3}, {4},", "Строка", 21, 45.89, ТекущаяДата(),истина );   Врап.ОчиститьСсылку(ссылка);
    ссылка=Сб.AppendLine(); Врап.ОчиститьСсылку(ссылка);

    // Так как в параметрах можно передавать только простые типы закодирум ссылку на объект в строку
    
    ссылка=Сб.AppendFormat(InvariantCulture.ПолучитьСсылку(),"AppendFormat {0}, {1}, {2}, {3}, {4},", "Строка", 21, 45.89, ТекущаяДата(),истина );  Врап.ОчиститьСсылку(ссылка);
    ссылка=Сб.AppendLine(); Врап.ОчиститьСсылку(ссылка);
    
    ссылка=Сб.AppendFormat(CultureInfoES.ПолучитьСсылку(),"AppendFormat {0}, {1}, {2}, {3}, {4},", "Строка", 21, 45.89, ТекущаяДата(),истина );
  
    
    
    Сообщить(СБ.ToString());
    СБ.Capacity=40;
    Сообщить(СБ.Capacity);

КонецПроцедуры
   DES
 
549 - 25.06.16 - 19:43
(518) Я дика извиняюсь, это реальность или фантастика ?
   DES
 
550 - 25.06.16 - 20:34
(0) Если помнишь, я тебе давно надоедал насчет
врап=новый COMОбъект("NetObjectToIDispatch45");
в 1с 7.7 ?

Теперь я взялся за ум и перешел на 8.3.

И у меня вопрос, есть ли что-то новое по этой теме  для 8?
   Garykom
 
551 - 25.06.16 - 21:11
(549) это даже проще даже без вк можно
   DES
 
552 - 25.06.16 - 21:23
без ВК любой Д сможет
   Garykom
 
553 - 25.06.16 - 21:29
(552) Не в этом смысла, динамическая компиляция .net можно через запись файлика и выполнение командасистемы или выполнить
   DES
 
554 - 25.06.16 - 23:00
(553) в виде примера можно ?
   Garykom
 
555 - 25.06.16 - 23:06
   Serginio1
 
556 - 26.06.16 - 00:11
(549) Смотри 528.
   Кирпич
 
557 - 26.06.16 - 09:47
(551) можно и без ВК, только данные через файлы передавать и внешнее событие никак не вызвать.
   Кирпич
 
558 - 26.06.16 - 09:53
(548) "Для упрощения получения объектов можно создать методы"
да у меня претензии к скорости выполнения такого кода и сложности разработки. Я то один раз в VS все напишу и с отладчиком, в нормальной IDE все отлажу, а тебе приходится русско-буржуйскую кашу ковырять прямо в 1С. Это же муторно и некрасиво.

А про передачу объектов 1с в ВК я так и не понял. Оно у тебя работает или нет?
   Кирпич
 
559 - 26.06.16 - 09:55
(549) я думаю, лет 8 уже как не фантастика.
   DES
 
560 - 26.06.16 - 11:15
(556) напомни, все еще  нужно что-то регистрировать в винде 2008R2 чтобы заюзать твою обертку в 8.3 ?
 
 
   Serginio1
 
561 - 26.06.16 - 12:07
(559) Да. Вот пример с подгрузкой сборок.

HttpClient=ъТип("System.Net.Http.HttpClient, System.Net.Http, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
HttpClientHandler = ъТип("System.Net.Http.HttpClientHandler, System.Net.Http, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
DecompressionMethods= ъТип("System.Net.DecompressionMethods, System.Net.Primitives, Version=4.0.11.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");


handler = ъНовый(HttpClientHandler.ПолучитьСсылку());
// Можно использовать и так. Только Не соберем ссылки
//handler.AutomaticDecompression=Врап.OR(DecompressionMethods.GZip,DecompressionMethods.Deflate);

ссылкаGZip=DecompressionMethods.GZip;
ссылкаDeflate=DecompressionMethods.Deflate;

handler.AutomaticDecompression=Врап.OR(ссылкаGZip,ссылкаDeflate);
Врап.ОчиститьСсылку(ссылкаGZip);   Врап.ОчиститьСсылку(ссылкаDeflate);

Клиент = ъ(Врап.Новый(HttpClient.ПолучитьСсылку(),handler.ПолучитьСсылку()));

uriSources ="https://msdn.microsoft.com/en-us/library/system.net.decompressionmethods(v=vs.110).aspx";;

Стр=ъ(Клиент.GetStringAsync(uriSources)).Result;
Сообщить(СтрДлина(стр));
   Serginio1
 
562 - 26.06.16 - 12:12
(560 Инструкция в шапке Использование классов .Net в 1С для новичков

кроме того рядом с NetObjetToIDispatch45.dll лежит RegAsm.bat который нужно запустить от имени администратора
   Serginio1
 
563 - 26.06.16 - 12:20
(558) У меня разные подходы. В том числе и твой. Я например заполняю ТаблицуЗначений внутри .Net класса. Могу использовать DLL, могу DynamicMethod.
На самом деле, я легко пишу как ты говоришь мешанину и на 1С. Её проще править и отлаживать. Внутри 1С. Еще раз повторю у тебя очень частный случай возможностей моей компоненты. Но она мощнее так как позволяет использовать объекты, в том числе и 1С. Использование событий .Net объектов. Асинхронное программирование.

Но это опять не по теме. Сейчас я говорю о кроссплатформенном использовании классов .Net в 1С.
   Кирпич
 
564 - 26.06.16 - 17:10
(563) "Я например заполняю ТаблицуЗначений внутри .Net класса"
Такое в NativeAPI возможно? Я от не понимаю как ты это делаешь. Пример есть? Только не надо вываливать листинг на 150 строк :)
   Serginio1
 
565 - 26.06.16 - 18:20
(564) В NativeAPI нет. А в COM легко.
Но на самом деле можно и через Native. Но только на Виндовс.
Обернуть любой объект через СОМ объекта у которого запросить Long на себя, который можно передавать в параметрах и вызывать на нем методы IDispatch.
   DES
 
566 - 26.06.16 - 21:46
(565) подскажи почему не присваивается значение структуре ?
newid = Врап.ПолучитьТип("System.Guid").NewGuid().ToString();
ТипRequest = Врап.ПолучитьТип("ServiceEfactura.ServiceReference.InvoicesRequest");
ТипЛист = Врап.ПолучитьТип("System.Collections.Generic.List`1");
ТипInvoiceIndentificator = Врап.ПолучитьТип("ServiceEfactura.ServiceReference.InvoiceIndentificator");
    
Request = Врап.СоздатьОбъект(ТипRequest);
ТипЛистОбъект = Врап.ТипКакОбъект(ТипЛист);
ТипизированныйЛист = ТипЛистОбъект.MakeGenericType(ТипInvoiceIndentificator);
SeriaAndNumbers = Врап.СоздатьОбъект(ТипизированныйЛист);
SeriaAndNumber = Врап.СоздатьОбъект(ТипInvoiceIndentificator);
SeriaAndNumber.Number = "000000001";
SeriaAndNumber.Seria = "EAA";
SeriaAndNumbers.Add(SeriaAndNumber);
    
request.RequestId = newid; // тут нормально присваивается
А тут затык, так как это массив.
request.SeriaAndNumbers = SeriaAndNumbers;
пишет ошибка в методе SeriaAndNumbers  не найден метод *.*.*.*.SeriaAndNumbers.mscorlib
   Serginio1
 
567 - 26.06.16 - 22:03
Нужно смотреть тип ServiceEfactura.ServiceReference.InvoiceIndentificator

Заведи отдельную ветку.
   Serginio1
 
568 - 26.06.16 - 22:18
Возможно у тебя тип request.SeriaAndNumbers
ServiceEfactura.ServiceReference.InvoiceIndentificator[]

Тогда
request.SeriaAndNumbers = SeriaAndNumbers.ToArray();
   DES
 
569 - 27.06.16 - 00:11
да, спс, таки оно.
   Serginio1
 
570 - 27.06.16 - 12:12
Поработал с интерфейсами и Энумераторами

Функция ПолучитьЭнумератор(Объект)

Перечислимый=ъ(Врап.ПолучитьИнтерфейс(Объект.ПолучитьСсылку(),"IEnumerable"));
ПеречислительСсылка=Перечислимый.GetEnumerator();
// На всякий случай приведем к Интерфейсу IEnumerator
Перечислитель=ъ(Врап.ПолучитьИнтерфейс(ПеречислительСсылка,"IEnumerator"));
Врап.ОчиститьСсылку(ПеречислительСсылка);    
// Можно и так
//IEnumerable=ъТип("System.Collections.IEnumerable");
//IEnumerator=ъТип("System.Collections.IEnumerator")
// Перечислимый=ъ(Врап.ПолучитьИнтерфейс(Объект.ПолучитьСсылку(),IEnumerable));
//ПеречислительСсылка=Перечислимый.GetEnumerator();
// На всякий случай приведем к Интерфейсу IEnumerator
// Перечислитель=ъ(Врап.ПолучитьИнтерфейс(ПеречислительСсылка,IEnumerator));
//Врап.ОчиститьСсылку(ПеречислительСсылка);    

возврат  Перечислитель
КонецФункции // ПолучитьЭнумератор()

Процедура ТестЭнумератораНажатие(Элемент)
    List=ъТип("System.Collections.Generic.List`1[System.String]");
//Сообщить(Врап.ИнформацияОТипе(List.ПолучитьСсылку()));    

//IEnumerable=ъТип("System.Collections.IEnumerable");
//IEnumerator=ъТип("System.Collections.IEnumerator");

Список=ъНовый(List.ПолучитьСсылку());
Для сч=1 По 10 Цикл
Список.Add(строка(сч));    
КонецЦикла;

// Нет поддержки энумераторов. В COM есть
//Для каждого стр   Из Список Цикл

//Сообщить(стр);    

//КонецЦикла;

СписокЭнум=ПолучитьЭнумератор(Список);
  
Пока СписокЭнум.MoveNext() Цикл
//  Врап.ВСтроку вывоит строковое представление всех типов в том числе числовые, строки, неопределено
    Сообщить(СписокЭнум.Current);

КонецЦикла;

КонецПроцедуры
   Serginio1
 
571 - 27.06.16 - 12:24
Протестировал out параметры
TryGetValue(ключ, out значение))

Процедура TestDictionaryНажатие(Элемент)
    // Вставить содержимое обработчика.
Словарь= ъНовый("System.Collections.Generic.Dictionary`2[System.String,System.Int32]");

Для сч=1 По 10 Цикл
  Словарь.Add(строка(сч),сч);    
КонецЦикла;

зн=0;
Если Словарь.TryGetValue("5",зн) Тогда
  Сообщить(зн);
КонецЕсли;

КонецПроцедуры
   Serginio1
 
572 - 28.06.16 - 12:03
Проверил производительность
http://rsdn.ru/forum/dotnet/6484358.1

миллион вызовов функции .Net занимает порядка 3 секунд, на моем не можном компе.
   Serginio1
 
573 - 28.06.16 - 15:20
А вот в 1С
    // Вставить содержимое обработчика.
    КоличествоИтераций=20000;
Тестовый=ъТип("TestDllForCoreClr.Тестовый, TestDllForCoreClr, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null");
Тест=ъ(Врап.Новый(Тестовый.ПолучитьСсылку()," Свойство из Конструктора"));

    stopWatch = ъНовый("System.Diagnostics.Stopwatch,System.Runtime.Extensions, Version=4.0.11.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
    
    стр="";
     Тест.ПолучитьЧисло(1);
    
    НачВремя=ТекущаяДата();
    stopWatch.Start();
    
    
    Для сч=1 по КоличествоИтераций Цикл
        Тест.ПолучитьЧисло(сч);

    КонецЦикла;
    
    stopWatch.Stop();
    
    ВремяВыполнения=ТекущаяДата()-НачВремя;
    Сообщить("ПолучитьЧисло ="+ВремяВыполнения);
    ВывестиВремя(stopWatch);

1 секунда на 20 000 вызовов .
против
1 секунда на 300 000.
   Serginio1
 
574 - 28.06.16 - 15:32
Да еще зачем то хочет установить свойство Elapsed
Хотя никакой установки нет

Процедура ВывестиВремя(знач stopWatch)
     ts = ъ(stopWatch.Elapsed);

    String=ъТип("System.String");
    // Format and display the TimeSpan value.
     Hours=ts.Hours;
     Minutes=ts.Minutes;
     Milliseconds=ts.Milliseconds;
     Seconds=ts.Seconds;
    elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",Hours, Minutes, Seconds,Milliseconds / 10);
    Сообщить(elapsedTime);
КонецПроцедуры
   Кирпич
 
575 - 28.06.16 - 15:34
(0) вчера студент приходил, вебсервис синтезатора речи Ivona испытывали.
как с помощью врапера его к 1с прикрутить?

ниже работающий пример на С#:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Web.Script.Serialization;
using System.Runtime.InteropServices;


class Program
{
    const string AccessKey = "GDNAJP73IAROH72QWEHA";
    const string SecretKey = "9Q7vSMMvVbMw8t9Ti5HRTSWde1E4cah9N9DV8pG7";

    [DllImport("winmm.dll")]
    private static extern long mciSendString(string strCommand, StringBuilder strReturn, int iReturnLength, IntPtr hwndCallback);

    static void Main()
    {
        string errortext = "";

        try
        {
            var path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ApplicationData) + "1.mp3";
            File.Delete(path);

            byte[] voice = IvonaCreateSpeech("Привет, красавчики!");
            File.WriteAllBytes(path, voice);

            string command = "play " + path + " wait ";
            mciSendString(command, null, 0, IntPtr.Zero);

            File.Delete(path);

            return;
        }
        catch (WebException ex)
        {
            errortext = ex.Message;
        }
        catch (Exception ex)
        {
            errortext = ex.Message;
        }
        Console.WriteLine(errortext);
    }

    //-----------------------------------------------------------------------------
    //-----------------------------------------------------------------------------

    private static byte[] IvonaCreateSpeech(string text)
    {
        var date = DateTime.UtcNow;

        const string algorithm = "AWS4-HMAC-SHA256";
        const string regionName = "eu-west-1";
        const string serviceName = "tts";
        const string method = "POST";
        const string canonicalUri = "/CreateSpeech";
        const string canonicalQueryString = "";
        const string contentType = "application/json";

        const string host = serviceName + "." + regionName + ".ivonacloud.com";

        var obj = new
        {
            Input = new
            {
                Data = text,
                Type = "text/plain"
            },
            OutputFormat = new
            {
                Codec = "MP3",
                SampleRate = 22050
            },
            Parameters = new
            {
                Rate = "medium",
                Volume = "medium",
                SentenceBreak = 500,
                ParagraphBreak = 800
            },
            Voice = new
            {
                Name = "Tatyana",
                Language = "ru-RU",
                Gender = "Female"
            }
        };
        var requestPayload = new JavaScriptSerializer().Serialize(obj);

        var hashedRequestPayload = HexEncode(Hash(ToBytes(requestPayload)));

        var dateStamp = date.ToString("yyyyMMdd");
        var requestDate = date.ToString("yyyyMMddTHHmmss") + "Z";
        var credentialScope = string.Format("{0}/{1}/{2}/aws4_request", dateStamp, regionName, serviceName);

        var headers = new SortedDictionary<string, string>
            {
                {"content-type", contentType},
                {"host", host},
                {"x-amz-date", requestDate}
            };

        string canonicalHeaders =
            string.Join("\n", headers.Select(x => x.Key.ToLowerInvariant() + ":" + x.Value.Trim())) + "\n";
        const string signedHeaders = "content-type;host;x-amz-date";

        var canonicalRequest = method + '\n' + canonicalUri + '\n' + canonicalQueryString +
                               '\n' + canonicalHeaders + '\n' + signedHeaders + '\n' + hashedRequestPayload;

        var hashedCanonicalRequest = HexEncode(Hash(ToBytes(canonicalRequest)));

        var stringToSign = string.Format("{0}\n{1}\n{2}\n{3}", algorithm, requestDate, credentialScope,
            hashedCanonicalRequest);

        byte[] signingKey = GetSignatureKey(SecretKey, dateStamp, regionName, serviceName);

        var signature = HexEncode(HmacSha256(stringToSign, signingKey));

        var authorization =
            string.Format("{0} Credential={1}/{2}/{3}/{4}/aws4_request, SignedHeaders={5}, Signature={6}",
                algorithm, AccessKey, dateStamp, regionName, serviceName, signedHeaders, signature);

        // Send the request

        var webRequest = WebRequest.Create("https://"; + host + canonicalUri);

        byte[] buffer = ToBytes(requestPayload);

        webRequest.Method = method;
        webRequest.Timeout = 20000;
        webRequest.ContentType = contentType;
        webRequest.Headers.Add("X-Amz-date", requestDate);
        webRequest.Headers.Add("Authorization", authorization);
        webRequest.Headers.Add("x-amz-content-sha256", hashedRequestPayload);
        webRequest.ContentLength = buffer.Length;

        using (Stream newStream = webRequest.GetRequestStream())
        {
            newStream.Write(buffer, 0, buffer.Length);
            newStream.Flush();
        }

        var response = (HttpWebResponse)webRequest.GetResponse();

        using (Stream responseStream = response.GetResponseStream())
        {
            if (responseStream != null)
            {
                using (var memoryStream = new MemoryStream())
                {
                    responseStream.CopyTo(memoryStream);
                    return memoryStream.ToArray();
                }
            }
        }
        return new byte[0];
    }

    private static byte[] GetSignatureKey(String key, String dateStamp, String regionName, String serviceName)
    {
        byte[] kDate = HmacSha256(dateStamp, ToBytes("AWS4" + key));
        byte[] kRegion = HmacSha256(regionName, kDate);
        byte[] kService = HmacSha256(serviceName, kRegion);
        return HmacSha256("aws4_request", kService);
    }

    private static byte[] ToBytes(string str)
    {
        return Encoding.UTF8.GetBytes(str);
    }

    private static string HexEncode(byte[] bytes)
    {
        return BitConverter.ToString(bytes).Replace("-", string.Empty).ToLowerInvariant();
    }

    private static byte[] Hash(byte[] bytes)
    {
        return SHA256.Create().ComputeHash(bytes);
    }

    private static byte[] HmacSha256(String data, byte[] key)
    {
        return new HMACSHA256(key).ComputeHash(ToBytes(data));
    }
}
   Serginio1
 
576 - 28.06.16 - 15:50
И? Нужно каждую сборку регистрировать. Кроме того если нужно подправить на сервере например нужно сервер останавливать, так как DLL не выгружается.
Используй HTTPClient
там есть расширение PostAsJsonAsync.
И зачем мусорить ветку. Я прекрасно все знаю.
   Serginio1
 
577 - 28.06.16 - 15:51
Я это и на 1С прекрасно напишу. Без всяких DLL и регистрации.
   Кирпич
 
578 - 28.06.16 - 15:55
(576) я думал ты себе в портфолио запишешь. типа вот 1с человеческим голосом заговорила.
(577) не. на 1с не получится. там какие то хеши, массивы...
   Кирпич
 
579 - 28.06.16 - 15:58
(576) "так как DLL не выгружается" кстати проблема. NET вк не выгружаются сами, хоть тресни, а обычные выгружаются.
   Serginio1
 
580 - 28.06.16 - 16:09
(578) Легко. Вот код для 7 ки
Функция ВычислитьHMAC(key,стр)
    врап=СоздатьОбъект("NetObjectToIDispatch45");
    врап.УстЭтоСемерка();
//    если только латиница
//encoding=Врап.ПолучитьТип("System.Text.Encoding").ASCII;
encoding=Врап.ПолучитьТип("System.Text.Encoding").UTF8;

keyByte = encoding.GetBytes(key);

hmacmd5 = Врап.СоздатьОбъект("System.Security.Cryptography.HMACMD5",keyByte);
hmacsha1 = Врап.СоздатьОбъект("System.Security.Cryptography.HMACSHA1",keyByte);

messageBytes = encoding.GetBytes(стр);
hashmessage = hmacmd5.ComputeHash(messageBytes);
hashmessage2 = hmacsha1.ComputeHash(messageBytes);
BitConverter=Врап.ПолучитьТип("System.BitConverter");
Strhashmessage=СтрЗаменить(BitConverter.ToString(hashmessage),"-","");
Strhashmessage2=СтрЗаменить(BitConverter.ToString(hashmessage2),"-","");

Сообщить(Strhashmessage);
Сообщить(Strhashmessage2);
    

КонецФункции// ВычислитьHMAC()
   Serginio1
 
581 - 28.06.16 - 16:11
Почему в этой ветке нет подсветки кода?
   Зая Бусечка
 
582 - 28.06.16 - 16:12
(581) Подсветка работает только в разделе 1с. Ибо нефиг
   Кирпич
 
583 - 28.06.16 - 16:14
(580) это всё вместо двух строчек? ого.

    private static byte[] HmacSha256(String data, byte[] key)
    {
        return new HMACSHA256(key).ComputeHash(ToBytes(data));
    }
   Serginio1
 
584 - 28.06.16 - 16:17
(582) То есть в поиске работы кода не может быть?
(579) На 1С можно все. В том числе и выполнение асинхронных методов, подключение к событиям.

И все это возможно и на Линукс. Тут все кричали .Net отстой он не кросплатформен. Я даю кроссплатформенный вариант.
Который может выполняться и на Линукс

(584) Там тоже 2 строчки только алгоритмы разные

hmacsha1 = Врап.СоздатьОбъект("System.Security.Cryptography.HMACSHA1",keyByte);
hashmessage2 = hmacsha1.ComputeHash(messageBytes);
   Serginio1
 
585 - 28.06.16 - 16:19
Или
Врап.СоздатьОбъект("System.Security.Cryptography.HMACSHA1",keyByte).ComputeHash(messageBytes);
   Кирпич
 
586 - 28.06.16 - 16:21
(585) о. так гораздо лучше
   Serginio1
 
587 - 28.06.16 - 16:22
(583) И еще раз как это относится к Linux?
Я показываю кроссплатформенный код. Который можно улучшить если 1С предпримет шаги для оптимизации своей Native ВК или введения новой более оптимальной версии.
   Serginio1
 
588 - 28.06.16 - 16:24
Или можно так
ъНовый("System.Security.Cryptography.HMACSHA1",keyByte).ComputeHash(messageBytes);
   Зая Бусечка
 
589 - 28.06.16 - 16:25
(587) Если бы 1с "предпринимала шаги", мы бы ещё долго и счастливо сидели на 77
   Кирпич
 
590 - 28.06.16 - 16:26
(587) "И еще раз как это относится к Linux?"
да никак. я про линукс и не заикался.
   Serginio1
 
591 - 28.06.16 - 16:30
(589) Дело в том, что Native ВК они сделали. Но уже сейчас много недостатков.
1. Нельзя передать или возвратить объект ВК
2. Метод имеющий возвращаемое значение вызывается как функция не зависимо от тог как вызывается метод. Даже когда он вызывается как процедура ВК требует возвращаемое значение.
3. При возврате bool SetPropVal(const long lPropNum, tVariant* varPropVal) и GetPropVal при возврате ложь исключение не вызывается
4. Зачем то происходит установка свойств там где этого в коде нет. И вызываются по некольку раз.
   Serginio1
 
592 - 28.06.16 - 16:31
(590) А вся это ветка посвящена Кроссплатформенному использованию классов .Net в 1С.
   Кирпич
 
593 - 28.06.16 - 16:34
(592) так а я как узнаю, что она посвящена там чему то. написано "Неспешно ищу работу. 1С + .Net"
С названием, кстати, не согласен. Нет такой отрасли народного хозяйства "1С + .Net". Хотя, если цель - создать такую отрасль из голого пальца, то пожалуйста.
   Serginio1
 
594 - 28.06.16 - 17:05
(593) Дело в том, что 1С может использовать кроссплатформенность .Net на прямую. Можно для определенных типов прописать рускоязычные ресурсы. Это легко сделать.
Например в Microsoft Dynamics AX есть ClrObject.
И 1С ничем не хуже. При этом если в .Net практически ничего не ломается, то 1С постоянно косячит JOB: HTTPСоединение и SSL connect error

И поверь если бы 1С ввела поддержку .Net все прекрасно писали бы используя классы .Net так как из каропки.

А интегрировать на самом деле много. Ко мне сейчас много обращаются, а у меня вот времени нет совсем.
   Gary417
 
595 - 28.06.16 - 17:25
(594) <При этом если в .Net практически ничего не ломается, то 1С постоянно косячит JOB: HTTPСоединение и SSL connect error>

Ну ненадо, когда начинаются нюансы с алгоритмами шифрования, требованиями FIPS и т.п. всякие глюи и у явы и у .net и вообще с пустого места начинают выползать
   Serginio1
 
596 - 28.06.16 - 17:44
(595) Ну размер библиотек 1С и .Net несопоставим. А вот твой пример касается нового.
Но аналоги HTTPСоединения никогда не ломались, хотя и значительно мощнее. Помню вэб сервисы слетели и пришлось ждать обновления. Ну и по мелочи там сям.
   Serginio1
 
597 - 28.06.16 - 17:46
И каксается я так понимаю, что нет поддержки на уровне ОС
https://msdn.microsoft.com/ru-ru/library/aa738624(v=vs.110).aspx
   Serginio1
 
598 - 28.06.16 - 20:07
Кстати .Net Core релизнули. А Samsung подтвердил поддержку
https://blogs.msdn.microsoft.com/dotnet/2016/06/27/announcing-net-core-1-0/

Samsung присоединяется к .NET Foundation

Повышенный интерес к .NET Ядро также приводится к более глубокому взаимодействию в .NET Foundation , которая в настоящее время управляет более чем 60 проектов.  Сегодня мы объявляя Samsung в качестве нового члена .  В апреле Red Hat, Мозги Jet и Единство приветствовали Руководящей группы технического .NET Foundation.

".NET Является отличным технология , которая значительно повышает производительность труда разработчиков. Samsung вносит свой ??вклад в .NET Ядро на GitHub - особенно в области поддержки ARM - и мы с нетерпением ожидаем дальнейшего содействия в .NET сообщества с открытым исходным кодом. Samsung рада присоединиться к технической руководящей группы .NET Foundation и помочь большему количеству разработчиков пользоваться преимуществами .NET. "Хонг-Сек Ким, вице - президент Samsung Electronics.

Вклады от Samsung были впечатляющими.  У них есть отличная команда разработчиков, которые проявили интерес к .NET Core.  Мы рады иметь их как часть большой команды
   Serginio1
 
599 - 29.06.16 - 09:57
(575) Кстати давно делал. Есть COM класс
glSpeechApi = Новый COMОбъект("SAPI.SpVoice");
        Для каждого звук из glSpeechApi.GetVoices() Цикл
            Сообщить(Звук.ID);
            Если Найти(Звук.ID,"Alyona22k")>0 Тогда
                glSpeechApi.voice=Звук;
                КонецЕсли;
            КонецЦикла;
и вызов
glSpeechApi.Speak(стр);
   Serginio1
 
600 - 30.06.16 - 15:38
Выложил статью и исходники
https://habrahabr.ru/post/304482/
  1  2  3  4  5  6  7   

Список тем форума
 
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.
Тема не обновлялась длительное время, и была помечена как архивная. Добавление сообщений невозможно.
Но вы можете создать новую ветку и вам обязательно ответят!
Каждый час на Волшебном форуме бывает более 2000 человек.