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




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

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

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

<?php // Полная загрузка сервисных книжек, создан 2026-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 не будет опубликован. Обязательные поля помечены *