Использование классов .Net в 1С для новичков




Принцип обмена данными из 1С с сайтом (на MySQL) и выдачи (публикации) этих данных по запросу.
PHP-Скрипт автоматической загрузки данных из файла данных в формате CSV в базу данных сайта работающего на WordPress.

В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "/////    echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1. 
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.

Собственно сам скрипт:

<?php // Полная загрузка сервисных книжек, создан 2024-01-05 12:44:55

global $wpdb2;
global $failure;
global $file_hist;

/////  echo '<H2><b>Старт загрузки</b></H2><br>';

$failure=FALSE;
//подключаемся к базе
$wpdb2 = include_once 'connection.php'; ; // подключаемся к MySQL
// если не удалось подключиться, и нужно оборвать PHP с сообщением об этой ошибке
if (!empty($wpdb2->error))
{
/////   echo '<H2><b>Ошибка подключения к БД, завершение.</b></H2><br>';
$failure=TRUE;
wp_die( $wpdb2->error );
}

$m_size_file=0;
$m_mtime_file=0;
$m_comment='';
/////проверка существования файлов выгрузки из 1С
////файл выгрузки сервисных книжек
$file_hist = ABSPATH.'/_1c_alfa_exchange/AA_hist.csv';
if (!file_exists($file_hist))
{
/////   echo '<H2><b>Файл обмена с сервисными книжками не существует.</b></H2><br>';
$m_comment='Файл обмена с сервисными книжками не существует';
$failure=TRUE;
}

/////инициируем таблицу лога
/////если не существует файла то возврат и ничего не делаем
if ($failure){
///включает защиту от SQL инъекций и данные можно передавать как есть, например: $_GET['foo']
/////   echo '<H2><b>Попытка вставить запись в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>$m_comment));
wp_die();
/////    echo '<H2><b>Возврат в начало.</b></H2><br>';
return $failure;
}
/////проверка лога загрузки, что бы не загружать тоже самое
$masiv_data_file=stat($file_hist);   ////передаем в массив свойство файла
$m_size_file=$masiv_data_file[7];    ////получаем размер файла
$m_mtime_file=$masiv_data_file[9];   ////получаем дату модификации файла
////создаем запрос на получение последней удачной загрузки
////выбираем по штампу времени создания (редактирования) файла загрузки AA_hist.csv, $m_mtime_file

/////   echo '<H2><b>Размер файла: '.$m_size_file.'</b></H2><br>';
/////   echo '<H2><b>Штамп времени файла: '.$m_mtime_file.'</b></H2><br>';
/////   echo '<H2><b>Формирование запроса на выборку из лога</b></H2><br>';
////препарируем запрос
$text_zaprosa=$wpdb2->prepare("SELECT * FROM `vin_logs` WHERE `last_mtime_upload` = %s", $m_mtime_file);
$results=$wpdb2->get_results($text_zaprosa);

if ($results)
{   foreach ( $results as $r)
{
////если штамп времени и размер файла совпадают, возврат
if (($r->last_mtime_upload==$m_mtime_file) && ($r->last_size_upload==$m_size_file))
{////echo '<H2><b>Возврат в начало, т.к. найдена запись в логе.</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>'Загрузка отменена, новых данных нет, т.к. найдена запись в логе.'));
wp_die();
return $failure;
}
}
}
////если данные новые, пишем в лог запись о начале загрузки
/////echo '<H2><b>Попытка вставить запись о начале загрузки в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>0, 'last_size_upload'=>$m_size_file, 'comment'=>'Начало загрузки'));

////очищаем таблицу
$clear_tbl_zap=$wpdb2->prepare("TRUNCATE TABLE %s", 'vin_history');
$clear_tbl_zap_repl=str_replace("'","`",$clear_tbl_zap);
$results=$wpdb2->query($clear_tbl_zap_repl);
/////   echo '<H2><b>Очистка таблицы сервисных книжек</b></H2><br>';
if (empty($results))
{
/////   echo '<H2><b>Ошибка очистки таблицы книжек, завершение.</b></H2><br>';
//// если очистка не удалась, возврат
$failure=TRUE;
wp_die();
return $failure;
}

////загружаем данные
$table='vin_history';         // Имя таблицы для импорта
//$file_hist Имя CSV файла, откуда берется информация     // (путь от корня web-сервера)
$delim=';';          // Разделитель полей в CSV файле
$enclosed='"';      // Кавычки для содержимого полей
$escaped='\

99 Comments

  1. 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
  2. jobkostya1c8

    Интересная статья. Надо будет запомнить для задач интеграции. Жаль, что приводится то что не очень надо 🙁 А хотелось бы иметь под рукой библиотеку функций допустим для работы с зависшими процессами (фоновыми задачами), многими функциями ОС итд.

    Кстати насчет времени до миллисекунд вроде стандартная консоль запросов содержит строчку на JavaScript для записи текущего времени.

    Reply
  3. jobkostya1c8

    Вернее автору статьи (и знающим людям) вопрос по-другому: я могу вызвать API-функции Винды смотря справочник через данные объекты просто смотря справочник, передавать в функции и принимать от них данные в формате винды (или в универсальном формате). Я когда-то давно начинал с делфи, даже на ассемблере чуток писал для аппаратуры, но сейчас это в прошлом. Тогда только через стандарные компоненты делфи работал.

    Чтоб не было голословно приходилось писать только на досовском C++ Может навык пригодится для хотя бы понимания как обратиться к современным библиотекам на C# .net или что там

    Reply
  4. Serginio

    (2) Ну эта статья для начинающих. Посмотри мои другие статьи. Там много других примеров. Все написать невозможно. Показан принцип работы с классами .Net . Просто нужно найти нужный, а примеров в инете правда на C# полно.

    (3) Не понял?

    Reply
  5. jobkostya1c8

    (4) это большой плюс что Вы описали в двух словах «как запустить». Тем более я в этой технологии и есть «начинающий». Хотелось бы узнать кратно что можно и нужно делать через .net если:

    1. Такой технологии НЕТ в 1С.

    2. Стандартные методы сложны, глючны и малоэффективны.

    На что в общем стоит обратить внимание.

    Reply
  6. Serginio

    (5) Я бы посоветовал начать с азов. От простого к сложному.

    http://metanit.com/sharp/general.php

    http://professorweb.ru/my/csharp/charp_theory/level1/infonet.php

    Для начала просмотреть, а уже на конкретных задачах углубляться.

    Reply
  7. Andris_infostart

    (2) kostyaomsk, ТекущаяУниверсальнаяДатаВМиллисекундах(), вполне подходит для получения мс

    Reply
  8. olbu

    Интересно!, а есть простые примерчики применения?

    Reply
  9. Ferroks

    Недавно столкнулся с преобразование типов, за 5 минут задачу решить не получилось)

    Оставлю здесь подсказку.

    Преобразовании типов 1С в типы Net

    Г

    УИД = СОКРЛП(Новый УникальныйИдентификатор());
    UUU = Врап.ПолучитьТип(«System.Guid»).Parse(ГУИД);
    Дата = ТекущаяДата();
    
    
    ЧислоИНТ1 = Врап.ChangeType(«System.Int32»,-2147483648);
    ЧислоИНТ2 = Врап.ChangeType(«System.Int32»,2147483647);
    Десятичное1 = Врап.ChangeType(«System.Decimal»,7.9 * Pow(10,28));
    Десятичное2 = Врап.ChangeType(«System.Decimal»,-7.9 * Pow(10,28));
    Дробное1 = Врап.ChangeType(«System.Decimal»,»0.000001″);
    Дробное2  = Врап.ChangeType(«System.Decimal»,»-0.0000001″);
    

    Показать

    Reply
  10. Ferroks

    можно еще так преобразовать тип 1С в тип Net

    ТипДесЧерезПарсе = Врап.ПолучитьТип(«System.Decimal»).Parse(«0,000001»);

    бывает что получаешь ошибку «Неизвестная ошибка» или метод не найдет, проверьте параметр который передаете.

    ТипДесЧерезПарсе = Врап.ПолучитьТип(«System.Decimal»).Parse(«0,000001»);

    — так отрабатывает нормально.

    а так выдает ошибку — ТипДесЧерезПарсе = Врап.ПолучитьТип(«System.Decimal»).Parse(«0.000001»);

    Reply
  11. avz_1C

    Простите, а как узнать длину строки через свойство Length переменной типа String?

    Я создал строку:

    врап=новый COMОбъект(«NetObjectToIDispatch45″);
    ПространствоИмен=»System.»;
    String=врап.ПолучитьТип(ПространствоИмен+»String»);
    стр = String(«abc»);

    Отработало нормально, в переменной стр находится «abc»

    Теперь добавляю

    ДлинаСтр = стр.Length;

    и получаю ошибку:

    «Значение не является значением объектного типа (Length)»

    Reply
  12. Serginio

    (11) Как я писал в статье для таких случаев нужно использовать CultureInfo

    Decimal=Врап.ПолучитьТип(«System.Decimal»);
    CultureInfo=Врап.ПолучитьТип(«System.Globalization.CultureInfo»);
    culture=CultureInfo.InvariantCulture;
    Число=»0.000001″;
    Сообщить(Decimal.Parse(Число, culture.NumberFormat));
    
    Reply
  13. Serginio

    (12) В статье писал про это

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

    Поэтому если использовать объектные методы, например, String нужно обернуть его.

    Например

    ОбернутаяСтрока=Врап.ОбернутьЛюбойОбъект(«Тестовая строка»);
    ДлинаСтр =ОбернутаяСтрока.Length;
    
    

    Reply
  14. avz_1C

    Получилось так:

    врап = Новый COMОбъект(«NetObjectToIDispatch45»);
    стр = врап.ОбернутьЛюбойОбъект(«1СдотНЕТ»);
    ДлСтр = стр.Length;

    В ДлСтр значение 8

    При попытке посмотреть отладчиком 1С структуру объекта стр, система ругается на множество сборок.

    Reply
  15. avz_1C

    Не успел прочитать ответ, увидел в статье и тут же попробовал.

    О результате сообщил постом выше.

    Спасибо!

    Reply
  16. avz_1C

    Через МИСТА, по ссылке на яндекс-диск, получил проект (исходники) от NetObjectToIDispatch.dll версии 2.0

    А можно ли где-то взять проект (исходники) NetObjectToIDispatch45.dll ?

    Ну, очень интересная тема.

    Reply
  17. avz_1C

    Спасибо. Получил.

    Если, вдруг, потребуются «соучастники» в проект, готов поработать.

    Под Вашим руководством 🙂

    Reply
  18. Serginio

    (19) Спасибо. Буду иметь ввиду. Но самое лучшее это писать статьи как http://infostart.ru/public/434345/

    Reply
  19. avz_1C

    Буду пытаться. Благодарю Вас за совет.

    Да и Вы, если вдруг захотите расширить аудиторию, милости

    просим в авторы блога на сайт http://www.programmist1c.ru

    Reply
  20. Serginio

    (21) Спасибо буду иметь ввиду

    Reply
  21. avz_1C

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

    Тестирую Вашу обработку ТестВКУФ.erf

    Захватывающе! Особенно с окном на WPF.

    Очень хочется посмотреть исходники того, что упаковано в двоичный макет.

    Можно?

    И вот, ещё, встретил в статье след. предложение:

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

    А это в каком примере можно увидеть?

    Прошу прощения, если что-то пропустил, но, вроде бы читал внимательно.

    Reply
  22. avz_1C

    При повторном, начиная с третьего, открытии обработки, через Файл -> Открыть … Появляется сообщение:

    — «Неизвестное имя формы: ХХХХХХХХХХХХХХХХХХХХХХХХ.Form»

    Пока не разобрался, в чем дело.

    Предполагаю, что-то связанное с кэшем.

    Reply
  23. Serginio

    (23) Я же давал ссылку в 18. Исходники лежат в папке ТестВК

    Reply
  24. Serginio

    Только там в public partial class Window1 : Window

    нужно добавить

    public static void СоздатьОкно(dynamic модуль1С, dynamic Object1C)
    {
    модуль1С.СообщитьСтр(«Зашли в метод»);
    var окно = new Window1(модуль1С, Object1C);
    окно.Show();
    модуль1С.СообщитьСтр(«Форма открыта»);
    }
    
    Reply
  25. Serginio

    26+ Исходник есть в этой статье http://infostart.ru/public/457898/

    Reply
  26. avz_1C

    (25)

    Да, спасибо. Нашел эту папку.

    Reply
  27. avz_1C

    (26)

    Спасибо, понял.

    Сейчас попытаюсь.

    Reply
  28. avz_1C

    (27)

    Да, все получилось. Метод СоздатьОкно(dynamic модуль1С, dynamic Object1C)

    работает отлично.

    Ошибка с диагнозом

    «Неизвестное имя формы: ХХХХХХХХХХХХХХХХХХХХХХХХ.Form»

    не появляется при запуске в тонком клиенте.

    Reply
  29. Serginio

    (30) Большое спасибо за использование и тестирование. Помню в 7 ке окно показывалось в списке окон, но при нажатии 1С вылетала. Видно 1С смотрит дочерние окна, но чужое окно она разрулить не может. Посмотрю.

    Reply
  30. avz_1C

    Спасибо за Ваш труд.

    Никак не наиграюсь 🙂

    От перспектив захватывает дух.

    Кстати, на *NIX-ах надо бы попробовать.

    Вероятно, на Linux должно пойти, через Mono?

    Или Mono не увидит под собой технологическую базу для Com Interop?

    Хотя, вот тут говорят, что можно …

    http://www.mono-project.com/docs/advanced/pinvoke/

    Надо потестировать.

    Reply
  31. Serginio

    Эта библиотека основана на преобразование .Net объектов в IDispatch через Ireflect. На линуксе не взлетит

    Reply
  32. 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
  33. Serginio

    Пример алгоритма сжатия строки и результат в Base64 и обратный процесс

    стр = «Строка для теста компрессии декомпрессии»;
    
    // Получим используемые типы
    MemoryStream=Врап.ПолучитьТип(«System.IO.MemoryStream»);
    UTF8=Врап.ПолучитьТип(«System.Text.Encoding»).UTF8;
    CompressionMode = врап.ПолучитьТип(«System.IO.Compression.CompressionMode»);
    
    
    СжатыйПоток = врап.СоздатьОбъект(MemoryStream); //Поток куда запишутся сжатые данные
    
    
    zipStr = врап.СоздатьОбъект(«System.IO.Compression.GZipStream», СжатыйПоток, CompressionMode.Compress);
    
    МассивДанных= UTF8.GetBytes(стр);// Получим массив данных используя кодировку  UTF8
    ПотокДляСжатия = Врап.СоздатьОбъект(MemoryStream,МассивДанных);  // Создадим поток из массива данных
    
    ПотокДляСжатия.CopyTo(zipStr);
    zipStr.Flush(); // Сбросим данные в  СжатыйПоток
    zipStr.Close(); // Закроем  GZipStream
    compressed = СжатыйПоток.ToArray(); // Получим массив байт сжатых данных
    
    Convert=Врап.ПолучитьТип(«System.Convert»);
    стр64=Convert.ToBase64String(compressed); // Переведем сжатые данные в Base64
    //Сообщить(стр64);
    

    Показать

    и обратный процесс

    //===== Процесс разжатия данных из строки кодированной алгоритмом Base64
    
    compressed=Convert.FromBase64String(стр64);
    
    ПотокСжатыхДанных = врап.СоздатьОбъект(MemoryStream,compressed);
    GZipПоток =врап.СоздатьОбъект(«System.IO.Compression.GZipStream»,ПотокСжатыхДанных, CompressionMode.Decompress);
    ПотокРазжатыхДанных = врап.СоздатьОбъект(MemoryStream);
    GZipПоток.CopyTo(ПотокРазжатыхДанных);
    Данные=ПотокРазжатыхДанных.ToArray();
    output = UTF8.GetString(Данные);
    
    Сообщить(output);
    

    Показать

    Reply
  34. Serginio

    (32) Это вызов натива из манагед.

    А вот обратно нужно что типа CLR Hosting API

    Reply
  35. avz_1C

    (36) Пытался провернуть такое на .NET Compact Framework 3.5 …

    Не взлетело.

    Reply
  36. Serginio

    (37) Сейчас в фаворе Universal Windows Platform

    Reply
  37. avz_1C

    (38) Приходится работать с CF3.5, так как на ТСД Motorola Symbol (все остальные бренды — копии той или иной степени копийности) в основном установлены Windows CE или Windows Mobile. Пока только китайские китайцы пытаются клепать ТСД и прочие POS девайсы на Windows Phone 8 и даже Windows 10. Нет желающих переделывать отлаженные логистические цепочки под использование экспериментальных образцов. Нет заказчиков — нет разработок.

    Reply
  38. Serginio

    (39) Согласен у самого под рукой Casio под Win CE. C Compact FW конечно пришлось повозиться. Но когда появились наработки затем писать уже намного легче.

    Reply
  39. avz_1C

    (40) И, может быть, хорошо, что в промышленном оборудовании (ТСД например) нет такого стремительного мелькания техники и технологий, как в товарах группы «Б». Иначе бы все рухнуло. Доля консерватизма необходима в группе «А», не может быть базис текучим и непредсказуемым.

    Reply
  40. Serginio

    Понадобилоссь прописать дефолтный принтер в 7 ке

    врап=СоздатьОбъект(«NetObjectToIDispatch45»);
    
    врап.УстЭтоСемерка();
    
    
    Registry=Врап.ПолучитьТип(«Microsoft.Win32.Registry»);
    
    
    Ключ=»Software1C1Cv77.7ИмяБазыV7″+ИмяПользователя()+»Moxel»;
    Сообщить(Ключ);
    key = Registry.CurrentUser.OpenSubKey(Ключ);
    ОсновнойКлюч=СокрЛП(key.Name)+»»;
    
    Ключи=key.GetSubKeyNames();
    
    
    Перечислимый=Врап.ПолучитьИнтерфейс(Ключи,»IEnumerable»);
    Перечислитель=Перечислимый.GetEnumerator();
    // На всякий случай приведем к Интерфейсу IEnumerator
    
    Перечислитель=Врап.ПолучитьИнтерфейс(Перечислитель,»IEnumerator»);
    // Теперь можем пройтись по коллекции
    
    
    Пока Перечислитель.MoveNext()<>0 Цикл
    //  Врап.ВСтроку вывоит строковое представление всех типов в том числе числовые, строки, неопределено
    
    Сообщить(Врап.ВСтроку(Перечислитель.Current));
    
    Ключ=ОсновнойКлюч+СокрЛП(Перечислитель.Current);
    ТекПринтер=Registry.GetValue(Ключ,»DefaultPrinter»,»»);
    Сообщить(ТекПринтер);
    
    Если (Принтер<>»») и (ТекПринтер<>»») и (Принтер<>ТекПринтер) Тогда
    
    Registry.SetValue(Ключ,»DefaultPrinter»,Принтер);
    КонецЕсли;
    КонецЦикла;
    

    Показать

    Reply
  41. olo_lo4

    Добрый день.

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

    1С-ка пишет

    Ошибка при вызове конструктора (COMОбъект)

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

    по причине:

    -2147221005(0x800401F3): Недопустимая строка с указанием класса

    какие библиотеки нужно доустановить? спасибо

    Reply
  42. olo_lo4

    (44) не получается. можно для тех кто в бронепоезде черным по белому написать.спасибо

    Reply
  43. Serginio

    Вторая ссылка в шапке все написано

    Reply
  44. olo_lo4

    Для таких же как и я в подвоной лодке, для начала работы, скачиваете и распаковываете файл ФайлыNetObjectToIDispatch

    далее в папке DLLNetObjetToIDispatch45 запускаем RegAsm.bat

    либо из корня скаченного файла запускаем РегистрацияКомСервера.exe и выбираем NetObjetToIDispatch45.dll которая лежит в DLLNetObjetToIDispatch45

    Взгляд со стороны, без обид:

    у автора очень интересный и нужный контент, но подача просто швахт, разбираться в этом адском количестве ссылок и каше неразложенной инфы …

    Reply
  45. Serginio

    (47) В пианиста просим не стрелять — он играет как умеет.

    Reply
  46. user650124_dao-piglet

    Сергей Смирнов, спасибо! Библиотека очень полезная, и у меня почти работает)))

    Объекты HttpClient и HttpRequestMessage создаются.

    А дальше нужно добавить к запросу Method и RequestUri — это не получается.

    (В C# аналогичный код работает)

    ХТТПЗапрос.RequestUri = Врап.СоздатьОбъект(«System.Uri», адрес);

    HttpMethod = Врап.ПолучитьТипИзСборки(«System.Net.Http.HttpMethod», «System.Net.Http.dll»);

    ХТТПЗапрос.Method = HttpMethod.Get;

    И в 1-й и в 2-й строках одинаковая ошибка:

    Произошла исключительная ситуация (mscorlib): Exception has been thrown by the target of an invocation.

    Получение System.Uri видел у Вас здесь и в других публикациях, скопировал. HttpMethod попробовал методом тыка.

    Что я делаю не так? Заранее спасибо!

    Reply
  47. Serginio

    Ты бы показал весь код на C#/ .

    Например для WebRequest RequestUri только для чтения.

    WebRequest=Врап.ПолучитьТипИзСборки(«System.Net.WebRequest»,»System.dll»);
    myWebRequest=WebRequest.Create(«https://msdn.microsoft.com/en-us/library/system.net.webrequest.requesturi(v=vs.110).aspx»);
    Сообщить(«RequestUri «+myWebRequest.RequestUri.ToString());
    HttpMethod = Врап.ПолучитьТипИзСборки(«System.Net.Http.HttpMethod», «System.Net.Http.dll»);
    Сообщить(Врап.Встроку(HttpMethod));
    

    Посмотри примеры Как вызвать метод из C# в 1С?

    Там последние версии компонент и куча примеров. .Net Framework 4.6.1

    Reply
  48. asdfgcom

    Пытаюсь подключить dll, не являющуюся COM-видимой.

    {ВнешняяОбработка.ВнешняяОбработка1.Форма.Форма.Форма(13)}: Ошибка при вызове метода контекста (ПолучитьТипИзСборки)

    Infrascturcture=Врап.ПолучитьТипИзСборки(«ZGuard.ZG_CTR_EV_TYPE»,»C:SDK GuardGuard.dll»);

    по причине:

    Произошла исключительная ситуация (mscorlib): Не удалось загрузить файл или сборку «file:///C:SDK GuardGuard.dll» либо одну из их зависимостей. Ожидалось, что модуль содержит манифест сборки.

    Понимаю, что она не является NET-сборкой. Можно ли это исправить, если есть исходник на C#?

    Следует оговориться, что C# не владею (((

    Reply
  49. Serginio

    Я так понимаю, вопрос отсюда http://www.forum.mista.ru/topic.php?id=787047

    Reply
  50. ivan811

    Очень интересно!

    Расширяет возможности интеграции

    Reply
  51. Serginio

    (53) Если интересно то есть еще цикл статей 1С, Linux, Excel, Word, OpenXML, ADO, Net Core

    Reply
  52. asdfgcom

    (52) Верно, Сергей. Главное, удалось, все-таки, перекомпилировать dll, после чего dll стала NET сборкой. Удалось достучаться до типов внутри. Сегодня попрактикуюсь вечером. Может и до контроллера достучусь.

    Заслуженная звезда.

    Reply
  53. asdfgcom

    Вот вопрос…

    Код Dll:

    namespace ZGuard
    {
    …….
    class ZGIntf
    {
    ………
    public static int ZG_SearchDevices(ref IntPtr pHandle, ref ZP_SEARCH_PARAMS pParams, bool fSerial=true, bool fIP=true)
    {
    if (fSerial)
    pParams.nDevMask |= ZG_DEVTYPE_CVTS;
    if (fIP)
    pParams.nIpDevMask |= ZG_IPDEVTYPE_CVTS;
    return ZPIntf.ZP_SearchDevices(ref pHandle, ref pParams);
    }
    …………………
    

    Показать

    т.е. вызов будет выглядеть как:

     врап=новый COMОбъект(«NetObjectToIDispatch45»);
    ZGIntf=Врап.ПолучитьТипИзСборки(«ZGuard.ZGIntf»,»D:КонфигурацииКлиентовИмпульсGuard.dll»);
    
    ZGIntf_Object=Врап.СоздатьОбъект(ZGIntf);
    IntPtr = Врап.ПолучитьТип(«System.IntPtr»);
    m_hCvt = IntPtr.Zero;
    Result = ZGIntf_Object.ZG_SearchDevices(); //пока не передаю параметров, т.к. не вижу метода
    

    получаю Метод объекта не обнаружен (ZG_SearchDevices)

    не понял, как добраться до методов??? Вроде он объявлен public.

    Reply
  54. Serginio

    А точно ZG_SearchDevices это метод объекта?

    Может это статический метод?

    Нужно обязательно передавать параметры, так как из-за перегрузок метод ищется по количеству и типам параметров

    Reply
  55. Serginio

    Приведи код на C#

    Reply
  56. Serginio
    public static  int ZG_SearchDevices
    

    Это метод класса (ключевое слово static). То есть нужно согласно объявлению

    public static int ZG_SearchDevices(ref IntPtr pHandle, ref ZP_SEARCH_PARAMS pParams, bool fSerial=true, bool fIP=true)
    
    

    вызвать

    IntPtr = Врап.ПолучитьТип(«System.IntPtr»);
    m_hCvt = IntPtr.Zero;
    Result = ZGIntf.ZG_SearchDevices(m_hCvt,pParams,истина, истина); //пока не передаю параметров, т.к. не вижу метода
    
    
    ZG_SearchDevices(ref IntPtr pHandle, ref ZP_SEARCH_PARAMS pParams, bool fSerial=true, bool fIP=true)
    
    Reply
  57. asdfgcom

    pParams — непонятно. Вообще, в этом месте предполагается callBack функция, возвращающая найденные контроллеры.

    Вот пример кода на C#, обращающийся к данной функции:

    static bool EnumCtrsCB(ref ZG_FIND_CTR_INFO pInfo, int nPos, int nMax, IntPtr pUserData)
    {
    Console.WriteLine(«{0}, адрес: {1}, с/н: {2}, v{3}.{4}, кл.: {5}, соб.: {6}, {7};»,
    CtrTypeStrs[(int)pInfo.nType],
    pInfo.nAddr,
    pInfo.nSn,
    pInfo.nVersion & 0xff, (pInfo.nVersion >> 8) & 0xff,
    pInfo.nMaxKeys,
    pInfo.nMaxEvents,
    KeyModeStrs[((pInfo.nFlags & ZGIntf.ZG_CTR_F_PROXIMITY) != 0) ? 1 : 0]);
    g_nCtrCount++;
    return true;
    }
    
    static void DoGuardFindCtrs()
    {
    int hr;
    
    Console.WriteLine(«Поиск контроллеров…»);
    Console.WriteLine(«————-«);
    g_nCtrCount = 0;
    hr = ZGIntf.ZG_Cvt_EnumControllers(m_hCvt, EnumCtrsCB, IntPtr.Zero);
    if (hr < 0)
    {
    Console.WriteLine(«Ошибка ZG_Cvt_EnumControllers ({0}).», hr);
    Console.ReadLine();
    return;
    }
    if (g_nCtrCount > 0)
    {
    Console.WriteLine(«————-«);
    Console.WriteLine(«Найдено {0} контроллеров.», g_nCtrCount);
    }
    else
    Console.WriteLine(«Контроллеры не найдены.»);
    }
    
    

    Показать

    Reply
  58. asdfgcom

    Вообще, до конца неясно с dll. Дома стоит VC, попробую внимательно проверить и пересобрать библиотеку.

    Попытка зарегистрировать DLL вываливается в ненайденную точку входа.

    Кроме того обращение к функции инициализации библиотеки без параметров:

    вв = ZGIntf.ZG_GetVersion();//она единственная без параметров точно

    вываливается с ошибкой «Адресат вызова вызвал исключение.mscorelib System.EntryPointNotFoundException

    Reply
  59. asdfgcom

    Вот-вот… С обертками я как раз и слаб пока))) Только-только типы научился брать.

    Reply
  60. Serginio

    Либо при запуске формировать в некий список и из него уже выбирать контроллеры.

    Reply
  61. Serginio

    Её не надо регистрировать. NetObjectToIDispatch45 как раз оборачивает .Net объекты через COM класс.

    Для начала запусти примеры на C#. Потом двигайся к 1С.

    Reply
  62. asdfgcom

    т.е. на стороне DLL предложить уже найденные контроллеры?

    Reply
  63. asdfgcom

    (64) предположим, создать свою функцию в DLL, обращение к которой, с серийным номером контроллера выполнит его поиск и даст его HANDLE ?

    Тем более есть рабочий пример такой функции на C#

    Reply
  64. Serginio

    А System.EntryPointNotFoundException говорит о том, что не нашла она в нативной DLL метод ZG_GetVersion

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

    Reply
  65. Serginio

    (67) Лучше дописать библиотеку под свои нужды.

    Reply
  66. user643502_olapmail

    Прошу прощения за возможно глупый вопрос… но не могу до конца понять как происходит работа с массивами (.Net) со стороны 1С 7.7

    Ar = glWrap.СоздатьМассив(«System.Int32», 7);  // работает без проблем
    Ar.SetValue(2, 4); // выдает ошибку : Не найден метод System.Int32[]SeValue mscorlib
    Зн1 = Ar.GetValue(1); // выдает ошибку : Не найден метод System.Int32[]GetValue mscorlib
    

    Т.е. объявить «.Net» массив возможно, но прямое чтение и прямую запись элементов провести не получилось.

    Конечно же можно исхитриться , создать

    ArrayList = glWrap.СоздатьОбъект(«System.Collections.ArrayList»)
    

    наполнить его:

    ArrayList.Add(Число1);
    ArrayList.Add(Число2);
    …..
    

    и после — выгрузить в массив

    ArrayList.CopyTo(Ar);
    

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

    Reply
  67. Serginio

    (70) Там в примерах к статье есть примеры для 7.7. Проблема в том, что в 7.7 нет целых чисел. Все числа это double и нужно приводить к int.

    Посмотри примеры в https://infostart.ru/public/238584/

    Например есть метод

    public Object ChangeType(string type, object value)
    public Object ToInt(object valueOrig)
    Ar = glWrap.СоздатьМассив(«System.Int32», 7);  // работает без проблем
    Ar.SetValue(glWrap.ToInt(2), glWrap.ToInt(4));    // выдает ошибку : Не найден метод System.Int32[]SeValue mscorlib
    Зн1 = Ar.GetValue(glWrap.ToInt(1));
    

    А так как в C# есть перегрузка методов, то передаваемые параметры должны соответствовать типам метода

    Reply
  68. user643502_olapmail

    (71)

    Ar = glWrap.СоздатьМассив(«System.Int32», 7); // работает без проблем

    Ar.SetValue(glWrap.ToInt(2), glWrap.ToInt(4)); // выдает ошибку : Не найден метод System.Int32[]SeValue mscorlib

    Зн1 = Ar.GetValue(glWrap.ToInt(1));

    Всё заработало!

    СПАСИБО!

    К сожалению не могу скачать скачать файл примеров «ФайлыNetObjectToIDispatch.zip».

    А может у Вашего проекта есть свой сайт?

    Reply
  69. user643502_olapmail

    (73) Спасибо! очень информативно! Но еще есть вопросы.

    Например — работа с .Net — перечислениями.

    Вот пример:

    https://msdn.microsoft.com/ru-ru/library/microsoft.analysisservices.attributeusage.aspx

    U = glWrap.СоздатьОбъект(«Microsoft.AnalysisServices.AttributeUsage»); //работает

    вид перечисления создается.

    Но как создать значение перечисления, а именно:

    Microsoft.AnalysisServices.AttributeUsage.Key

    Microsoft.AnalysisServices.AttributeUsage.Parent

    Microsoft.AnalysisServices.AttributeUsage.Regular

    ?

    Reply
  70. user643502_olapmail

    (74)

    Вопрос снимается….

    Всё просто…

    glWrap.ПолучитьТип(«Microsoft.AnalysisServices.AttributeUsage»).Key = OLE._AutoWrap
    glWrap.ПолучитьТип(«Microsoft.AnalysisServices.AttributeUsage»).Parent = OLE._AutoWrap
    

    СПАСИБО автору!!! Шикарная компонента

    Reply
  71. user643502_olapmail

    (75) Но… лучше было бы иметь не только:

    glWrap.ПолучитьТип(«Microsoft.AnalysisServices.AttributeUsage»).Key
    glWrap.ПолучитьТип(«Microsoft.AnalysisServices.AttributeUsage»).Parent
    

    Но хотелось бы еще, чтобы был метод типа: «ПолучитьПоИдентификатору», чтобы работало:

    glWrap.ПолучитьТип(«Microsoft.AnalysisServices.AttributeUsage»).ПолучитьПоИдентификатору(«Key»)
    glWrap.ПолучитьТип(«Microsoft.AnalysisServices.AttributeUsage»).ПолучитьПоИдентификатору(«Parent»)

    А может уже есть что-то подобное?

    Reply
  72. AnL24

    Создаю объекты криптографии,

    в этом варианте объект создается корректно

    C#
    // Конвертируем в System.Cryptography.X509 для получения дружественного имени алгоритма подписи
    // в случае, если установлен криптопровайдер
    X509Certificate2 pkSign50 = new X509Certificate2();
    
    1C
    pkSign50 = Врап.СоздатьОбъект(«System.Security.Cryptography.X509Certificates.X509Certificate2»);
    

    Показать

    Здесь получаю ошибку. Подскажите, какой текст кода будет правильным для данного варианта?

    C#
    // Объект, в котором будут происходить декодирование и проверка.
    SignedCms signedCms = new SignedCms();
    
    1C
    signedCms = Врап.СоздатьОбъект(«System.Security.Cryptography.Pkcs.SignedCms»);
    
    Reply
  73. AnL24

    (78) В первом случае происходит инициализация нового экземпляра класса X509Certificate2, во втором — конструктор SignedCms() создает экземпляр класса SignedCms.

    Reply
  74. seregasame

    подскажите что делаю не так:

     врап    = новый COMОбъект(«NetObjectToIDispatch45»);
    ФайлСборки   = «C:UsersksvDownloadsjose-jwt.dll»;
    Сборка    = врап.загрузитьСборку(ФайлСборки);
    
    типJWT     = Сборка.GetType(«Jose.JWT»);
    типJweAlgorithm  = Сборка.GetType(«Jose.JweAlgorithm»);
    типJweEncryption = Сборка.GetType(«Jose.JweEncryption»);
    
    Словарь    = Врап.СоздатьОбъект(«System.Collections.Generic.Dictionary`2[System.String,System.String]»);
    
    time     = Строка(Формат(ТекущаяДата() — Дата(1970,1,1),»ЧГ=0″));
    
    Словарь.Add   («sub»,ПользователиИнформационнойБазы.ТекущийПользователь().ПолноеИмя);
    Словарь.Add   («exp»,time);
    
    ключ     = врап.ОбернутьЛюбойОбъект(«top secret»);
    
    Токен    = типJWT.Encode(Словарь, ключ, типJweAlgorithm.PBES2_HS256_A128KW, типJweEncryption.A256CBC_HS512);
    
    Токен2     = врап.ОбернутьЛюбойОбъект(Токен);
    
    Рез     = типJWT.Decode(Токен2, ключ);
    

    Показать

    метод Encode отрабатывает, токен генерится, а Decod возвращает ошибку (скриншоты)

    сама либа тут Jose-JWT

    пример на C# выглядит так:

    var payload = new Dictionary<string, object>()
    {
    { «sub», «mr.x@contoso.com» },
    { «exp», 1300819380 }
    };
    
    string token = Jose.JWT.Encode(payload, «top secret», JweAlgorithm.PBES2_HS256_A128KW, JweEncryption.A256CBC_HS512);
    
    string token = «eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUh­TMjU2IiwicDJjIjo4MTkyLCJwMnMiOiJiMFlFVmxMemtaNW9UUjBMIn0.dhPAhJ9kmaEbP-02VtEoPOF2QSEYM5085V6zYt1U1qIlVNRcHTGDgQ.4QAAq0dVQT41dQKDG7dhRA.H9MgJmesbU1ow6GCa0lEMwv8A_sHvgaWKkaMcdoj_z6O8LaMSgquxA-G85R_5hEILnHUnFllNJ48oJY7VmAJw0BQW73dMnn58u161S6Ftq7Mjxxq7bc­ksWvFTVtG5RsqqYSol5BZz5xm8Fcj-y5BMYMvrsCyQhYdeGEHkAvwzRdvZ8pGMsU2XPzl6GqxGjjuRh2vApAeNrj6M­wKuD-k6AR0MH46EiNkVCmMkd2w8CNAXjJe9z97zky93xbxlOLozaC3NBRO2Q4bmdG­dRg5y4Ew.xNqRi0ouQd7uo5UrPraedg»;
    
    string json = Jose.JWT.Decode(token, «top secret»);

    Показать

    Reply
  75. Serginio
    public static string Decode(string token, object key = null, JwtSettings settings = null)

    Добавь еще null. К сожалению в Com варианте не добавляются параметры с дефолтными значениями

    Рез = типJWT.Decode(Токен2, ключ, неопределено);

    Reply
  76. Serginio

    По 78,79 конкретно какая ошибка?

    Возможно загрузить сборку

    Сборка  = врап.загрузитьСборку(«System.Security.dll»);
    тип=Сборка.GetType(«System.Security.Cryptography.Pkcs.SignedCms»);
    
    signedCms = Врап.СоздатьОбъект(тип);
    Reply
  77. AnL24

    (82)

    По 78,79 конкретно какая ошибка?

    Ошибка создания типа, при создании объекта компонента выводит диалоговое окно: «Неверный тип System.Security.Cryptography.Pkcs.SignedCms»

    На строке

    Сборка = врап.загрузитьСборку(«System.Security.dll»);

    Получаю ошибку «Ошибка при вызове метода контекста (загрузитьСборку): Произошла исключительная ситуация (mscorlib): Не удалось загрузить файл или сборку «file:///C:Program Files (x86)1cv8commonSystem.Security.dll» либо одну из их зависимостей. Не удается найти указанный файл.»

    Reply
  78. Serginio

    (84) А так

    тип = Врап.ПолучитьТипИзСборки(«System.Security.Cryptography.Pkcs.SignedCms»,»System.Security.dll»);
    Reply
  79. AnL24

    (85) Работает, благодарю!

    Reply
  80. AnL24

    (85) Объект SignedCms создал и видны его свойства, но метод Decode не выполняется

    signedCms.Decode(encodedSignedCms);
    
    или
    
    Врап.ВыполнитьМетод(signedCms, «Decode», encodedSignedCms);
    

    пишет «Ошибка в методе Decode Не найден метод «System.Security.Cryptography.Pkcs.SignedCms.Decode». mscorlib»

    Как заставить работать?)

    Reply
  81. Serginio

    А как получаешь encodedSignedCms

    public void Decode(
    byte[] encodedMessage
    )
    Reply
  82. AnL24

    (88)

    File = Врап.ПолучитьТип(«System.IO.File»);
    encodedSignedCms = Врап.ВыполнитьМетод(File, «ReadAllBytes», ПолноеИмяФайла);
    

    Но ругается на то, что метод Decode не найден, а не на содержимое параметра.

    Reply
  83. Serginio

    Он метод Decode не может найти по типу параметра.

    Можешь для интереса через отладчик посмотреть

    Да

    File.ReadAllBytes(ПолноеИмяФайла) 

    должно работать

    Reply
  84. Serginio

    Для интереса проверь методы

    врап.ПолучитьМетоды(ТипSignedCms)

    Reply
  85. AnL24

    (91) Метода Decode нет в списке

    Врап.ПолучитьМетоды(типSignedCms) COMОбъект COMОбъект
    IsFixedSize       Истина  Булево
    IsReadOnly       Ложь  Булево
    IsSynchronized      Ложь  Булево
    Length        19   Число
    LongLength       19   Число
    Rank        1   Число
    SyncRoot       COMОбъект COMОбъект
    Reply
  86. Serginio

    Там получаешь список. Нужно еще для Каждого пройтись

    Reply
  87. AnL24

    (93) Да, в элементах списка метод «Decode» есть.

    Свойство    Значение Тип
    Метод     COMОбъект COMОбъект
    Attributes     COMОбъект COMОбъект
    CallingConvention   COMОбъект COMОбъект
    ContainsGenericParameters Ложь Булево
    CustomAttributes   COMОбъект COMОбъект
    DeclaringType    COMОбъект COMОбъект
    IsAbstract    Ложь Булево
    IsAssembly    Ложь Булево
    IsConstructor    Ложь Булево
    IsFamily     Ложь Булево
    IsFamilyAndAssembly  Ложь Булево
    IsFamilyOrAssembly  Ложь Булево
    IsFinal     Ложь Булево
    IsGenericMethod   Ложь Булево
    IsGenericMethodDefinition Ложь Булево
    IsHideBySig    Истина Булево
    IsPrivate     Ложь Булево
    IsPublic     Истина Булево
    IsSecurityCritical   Истина Булево
    IsSecuritySafeCritical  Истина Булево
    IsSecurityTransparent  Ложь Булево
    IsSpecialName   Ложь Булево
    IsStatic     Ложь Булево
    IsVirtual     Ложь Булево
    MemberType    COMОбъект COMОбъект
    MetadataToken   100 664 537 Число
    MethodHandle    COMОбъект COMОбъект
    MethodImplementationFlags COMОбъект COMОбъект
    Module     COMОбъект COMОбъект
    Name     «Decode» Строка
    ReflectedType    COMОбъект COMОбъект
    ReturnParameter   COMОбъект COMОбъект
    ReturnType    COMОбъект COMОбъект
    ReturnTypeCustomAttributes COMОбъект COMОбъект

    Показать

    Reply
  88. AnL24

    (93) Метод «Decode» есть, куда дальше копать? Проблема в передаваемом в метод параметре?

    Reply
  89. user1017144

    (1) Подскажите, пожалуйста, как можно отменить запущенную длительную задачу (или хотя бы отписаться от события её завершения)?

    У меня есть управляемая форма, в которой запускается Task. У пользователя есть возможность закрыть форму ещё до завершения задачи (задача при этом продолжает выполняться). При завершении задачи возникает ошибка «Поле недоступно для чтения». Я так понимаю, что это возникает из-за того, что форму уже удалена.

    Исключение:

    System.Runtime.InteropServices.COMException (0x000003E9): {Документ.ДоговорТеплоснабжения.Форма.ФормаДокумента.Форма(98)}: Поле объекта недоступно для чтения

    в System.RuntimeType.ForwardCallToInvokeMember(String memberName, BindingFlags flags, Object target, Int32[] aWrapperTypes, MessageData& msgData)

    в NetObjectToIDispatch45.IВрапперДляАсинхронныйВыполнитель.ПриОкончанииВыполненияЗадачи(Object Задача, Object ДанныеКЗадаче)

    в NetObjectToIDispatch45.АсинхронныйВыполнитель.<>c__DisplayClass8_0.<Оповестить>b__0(Object d) в D:Vs2015ProgramsNetObjetToIDispatch45NetObjetToIDispatch45­ClassForEvent.cs:строка 188

    Reply
  90. Serginio

    (97) Наверное

    УдалитьОбработчик Выполнитель.ПриОкончанииВыполненияЗадачи, ПриОкончанииВыполнения;

    Reply
  91. user1017144

    (98)

    Добавил строку

    УдалитьОбработчик Выполнитель.ПриОкончанииВыполненияЗадачи, ПриОкончанииВыполнения;

    в событие «ПередЗакрытием» управляемой формы.

    Оператор выполняется, форма закрывается, но через несколько секунд выходит ошибка .Net:

    ************** Текст исключения **************

    System.NullReferenceException: Ссылка на объект не указывает на экземпляр объекта.

    в NetObjectToIDispatch45.АсинхронныйВыполнитель.<>c__DisplayClass8_0.<Оповестить>b__0(Object d) в D:Vs2015ProgramsNetObjetToIDispatch45NetObjetToIDispatch45­ClassForEvent.cs:строка 188

    Reply
  92. Serginio

    (99) Да тма ошибокчка

    public void Оповестить(object Задача, object ДанныеКЗадаче)
    {
    Sc.Post(d => ПриОкончанииВыполненияЗадачи(AutoWrap.ОбернутьОбъект(Задача), ДанныеКЗадаче), null);
    
    }

    Нужно сделать проверку на null. Ну и в Catch завернуть.

    public void Оповестить(object Задача, object ДанныеКЗадаче)
    {
    if (ПриОкончанииВыполненияЗадачи!=null)
    Sc.Post(d => ПриОкончанииВыполненияЗадачи(AutoWrap.ОбернутьОбъект(Задача), ДанныеКЗадаче), null);
    
    }

    Сейчас пока нет времени выложить новый

    Reply
  93. thezodchiy

    Как получить массив из компоненты?

     врап=СоздатьОбъект(«NetObjectToIDispatch45»);
    array=врап.ПолучитьТип(«System.Collections.IEnumerable»);
    test = СоздатьОбъект(«OneCHelper.test»);
    
    array = test.GetData();
    array=Врап.ПолучитьИнтерфейс(Список,»IEnumerable»);
    array=array.GetEnumerator();
    array=Врап.ПолучитьИнтерфейс(array,»IEnumerator»);
    
    
    Для array.MoveNext() цикл
    Сообщить(Врап.ВСтроку(array.Current));
    
    КонецЦикла;
    

    Показать

    array=Врап.ПолучитьИнтерфейс(Список<<?>>,»IEnumerable»);

    {***ТЕСТОВАЯ.ERT(24)}: Переменная не определена (Список)

    Для array<<?>>.MoveNext() цикл

    {***ТЕСТОВАЯ.ERT(32)}: Ожидается символ ‘=’

    Reply

Leave a Comment

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