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

Программирование - Практика программирования

.Net C#

136
Руководство для новичков. Написав статью http://infostart.ru/public/238584/, я понял, что многие не понимают того, что написано. Поэтому в этой статье постараюсь более подробно остановиться на азах и без кода на вражеском языке (C#)

В  .Net есть классы, структуры(Value типы), перечисления. С точки зрения 1С их можно рассматривать как классы. Каждый класс характеризуется типом.

По аналогии с 1С классы это справочники, документы и т.д.

У классов могут быть статические методы и свойства  и методы и свойства объекта. По аналогии с 1С статические методы это методы менеджера (НайтиПоКоду,НайтиПоНомеру), а методы объекта аналогичны методам объекта (Модифицированность, Удалить, Номер,Дата)

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

Каждый класс характеризуется именем класса, пространством имен и сборкой (размещение Dll, Exe).

Рассмотрим класс String https://msdn.microsoft.com/ru-ru/library/system.string(v=vs.110).aspx

Представляет текст как последовательность знаков Юникода.

Исходный код .NET Framework для этого типа см. в указанном источнике.

Пространство имен:   System
Сборка:  mscorlib (в mscorlib.dll)

Начнем сразу на примерах. Итак, для начала создадим объект, который будет обертывать объекты .Net в COM объекты.

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

Теперь получим тип System

String=Врап.ПолучитьТип("System.String");

Для понимания правильнее будет так

ПространствоИмен="System.";
String=Врап.ПолучитьТип(ПространствоИмен+"String");

Кто работал с ФабрикаXDTO, то там тоже есть простанство имен и типы.

К типам, которые находятся в GAC, мы можем не указывать сборку, в которой она находится.

КлассНеГак=Врап.ПолучитьТипИзСборки(ПолноеИмяКласса,ПолноеИмяФайла)

Теперь мы можем вызвать статические методы.

Например, аналог  1С функции ПустаяСтрока

Сообщить(String.IsNullOrWhiteSpace(неопределено));
Сообщить(String.IsNullOrWhiteSpace("  "));

Вернет Истина.

 

Статические методы в справке https://msdn.microsoft.com/ru-ru/library/system.string(v=vs.110).aspx

Помечаются  символом S.

К сожалению, есть проблемы с функциями, которые принимают параметры как массив params.

Например, у класса String  есть статическая функция Format

У неё есть множество перегрузок.

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

public static string Format(

               string format,

               params object[] args

)

Которая вызывается, когда параметров больше 3

При объявлении  параметра как params object[] мы можем задавать параметры через запятую.

Сообщить(String.Format("загружено {0} из {1} байт. {2}  % complete...", 
        e.BytesReceived, 
        e.TotalBytesToReceive,
		e.ProgressPercentage,
        0));

Я добвил еще один неиспользуемый параметр 0, иначе последний параметр вывелся бы как System.Object[]

Для того, что бы исправлять такие ошибки я добавил  метод ВыполнитьМетод

Который принимает первым параметром тип или строковое представление типа ("System.String");

Вторым параметром имя метода, а дальше параметры для запрашиваемого метода

 

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

Теперь перейдем с созданию объекта и вызову методов объекта.

Объект можно получить двумя способами

DateTime= Врап.ПолучитьТип("System.DateTime ");
Дата=Врап.СоздатьОбъект(DateTime,2015,1,2);

или

Дата=Врап.СоздатьОбъект("System.DateTime",2015,1,2);

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

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

Например

ОбернутаяСтрока=Врап.ОбернутьЛюбойОбъект("Тестовая строка");

Теперь можно применить к ней объектные методы

Найдем первое вхождение строки "ст" начиная с 6 символа (Возвращает индекс с отсчетом от нуля первого вхождения значения указанной строки в данном экземпляре. Поиск начинается с указанной позиции знака.)

Сообщить(ОбернутаяСтрока.IndexOf("ст",5));

Вернет 9

В .Net есть дженерик типы, у которых используемые типы заданы неявно.

http://professorweb.ru/my/csharp/charp_theory/level11/11_1.php

 

Возьмем для примера System.Collections.Generic.List<T>

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

 

В C# Для того, чтобы создать список строк

var список = new List<String>();
Можно посмотреть строковое представление класса
Список.GetType().ToString()
Или
typeof(List<String>).ToString();

 

он выдаст System.Collections.Generic.List`1[System.String]

Теперь мы можем использовать его

Список=Врап.СоздатьОбъект("System.Collections.Generic.List`1[System.String]");
Для сч=1 По 10 Цикл
Список.Add(строка(сч));	
КонецЦикла; 

Для каждого стр Из Список Цикл
	 Сообщить(стр)
КонецЦикла;

Но тоже можно добиться другим способом

Узнав строковое представление typeof(List<>).ToString()

System.Collections.Generic.List`1[T]

Оно совпадает с названием класса, только добавляется `1 это говорит, что дженерик поддерживает 1 неопределенный тип.

ListT=Врап.ПолучитьТип("System.Collections.Generic.List`1");
ListT=Врап.ТипКакОбъект(ListT); 
Список=Врап.СоздатьОбъект(ListT.MakeGenericType(String));

Нужно отметить, для того, что бы у объекта полученного как  ПолучитьТип был доступ к методам класса Type нужно его преобразовать через метод ListT=Врап.ТипКакОбъект(ListT);

Так как в реализации обертки он отвечает за статические методы класса.

Аналогично можно создать и словарь Dyctionary, это типизированный аналог 1С Соответствие

Dictionary<String,int>

Словарь= Врап.СоздатьОбъект("System.Collections.Generic.Dictionary`2[System.String,System.Int32]");

Для сч=1 По 10 Цикл

Словарь.Add(строка(сч),сч);	

КонецЦикла; 

Для каждого стр Из Словарь Цикл
	 Сообщить(стр.Key+"="+стр.Value)
КонецЦикла; 

//Аналогично это можно достигнуть через
СловарьT=Врап.ПолучитьТип("System.Collections.Generic.Dictionary`2");
Int32=Врап.ПолучитьТип("System.Int32");
СловарьT=Врап.ТипКакОбъект(СловарьT);
Словарь=Врап.СоздатьОбъект(СловарьT.MakeGenericType(String,Int32));

Еще одна особенность работы с C# реализацией this[]

Например, в 1С мы не можем вызвать Список[0]. Доступ осуществляется через

get_Itemи set_Item

Список.set_Item(0,"1С+Net");
Сообщить(Список.get_Item(0));

Вот полный список классовSystem.Collections.Generic

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

Регулярные выражения тоже часто применяются для поиска замены.

http://professorweb.ru/my/csharp/charp_theory/level4/4_10.php

Я покажу, как их использовать на примерах

input = "Добро пожаловать в наш магазин, вот наши цены: 
 |1 кг. яблок - 20 руб. 
 |2 кг. апельсинов - 30 руб.
 |0.5 кг. орехов - 50 руб.";
 
 pattern = "\b(\d+\W?руб)";
 regex = Врап.СоздатьОбъект("System.Text.RegularExpressions.Regex",pattern);
  // Получаем совпадения в экземпляре класса Match
 matches = regex.Matches(input);
// отображаем все совпадения
Для Каждого match in matches Цикл
	 // Т.к. мы выделили в шаблоне одну группу (одни круглые скобки),
	 // ссылаемся на найденное значение через свойство Groups класса Match
	 Сообщить(match.Groups.get_Item(1).Value);
КонецЦикла

В статье многого не затронешь, но хочу показать быстродействие вызова методов .Net классов через обертку.

В 1С нет явного аналога StringBuilder Предоставляет изменяемую строку символов.

В этом тесте нужно собрать строку из маленьких фрагментов строк. В 1С для соединения строк есть неявный аналог ЗаписьXML ЗаписатьБезОбработки.

Для  замера времени используем Stopwatch который замеряет время до миллисекунды

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

Процедура ВывестиВремя(врап,stopWatch)
	ts = stopWatch.Elapsed;
	String=Врап.ПолучитьТип("System.String");
	// Format and display the TimeSpan value.
	elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
	ts.Hours, ts.Minutes, ts.Seconds,
	ts.Milliseconds / 10,0);
	Сообщить(elapsedTime);
КонецПроцедуры	
Процедура StringBuilderНажатие(Элемент)
	// Вставить содержимое обработчика.
	врап=новый COMОбъект("NetObjectToIDispatch45");

	КоличествоИтераций=200000;
	stopWatch = Врап.СоздатьОбъект("System.Diagnostics.Stopwatch");
	
	стр="";
	
	НачВремя=ТекущаяДата();
	stopWatch.Start();
	
	Для сч=1 по КоличествоИтераций Цикл
		стр=стр+Строка(сч);
	КонецЦикла;
	stopWatch.Stop();
	
	ВремяВыполнения=ТекущаяДата()-НачВремя;
	Сообщить("Конкатенация ="+ВремяВыполнения+" сек. ДлинаСтр="+СтрДлина(Стр));
	
	ВывестиВремя(врап,stopWatch);
	стр="";
	НачВремя=ТекущаяДата();
	stopWatch.Restart();
	SB =  врап.СоздатьОбъект("System.Text.StringBuilder");
	Для сч=1 по КоличествоИтераций Цикл
		SB.Append(Строка(сч));
	КонецЦикла;
	
	стр=SB.ToString();
	stopWatch.Stop();
	
	ВремяВыполнения=ТекущаяДата()-НачВремя;
	Сообщить("StringBuilder ="+ВремяВыполнения+" сек. ДлинаСтр="+СтрДлина(Стр));
	ВывестиВремя(врап,stopWatch);
	
	НачВремя=ТекущаяДата();
	stopWatch.Restart();
	ЗаписьXML = Новый ЗаписьXML;
	ЗаписьXML.УстановитьСтроку();
	
	Для сч = 1 по КоличествоИтераций Цикл
		ЗаписьXML.ЗаписатьБезОбработки(Строка(сч));
	КонецЦикла;
	Стр = ЗаписьXML.Закрыть();
	stopWatch.Stop();
	
	ВремяВыполнения=ТекущаяДата()-НачВремя;
	Сообщить("ЗаписьXML ="+ВремяВыполнения+" сек. ДлинаСтр="+СтрДлина(Стр));
	ВывестиВремя(врап,stopWatch);
	
//Конкатенация =96 сек. ДлинаСтр=1 287 896
//00:01:36.22
//StringBuilder =10 сек. ДлинаСтр=1 287 896
//00:00:09.91
//ЗаписьXML =4 сек. ДлинаСтр=1 287 896
//00:00:04.40



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

Как видно, скорость вызова .Net класса в 2.25 раза медленнее обычного метода. Это нужно учитывать при обработке больших массивов данных.

Используем информацию о культуре .

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

Но часто нужно получать с данных без учета культуры

Целое   = 55333;
Дробное   = 66333.44;
Строка   = "абвгд";
Дата=ТекущаяДата();

CultureInfo=Врап.ПолучитьТип("System.Globalization.CultureInfo");
SB.AppendFormat(CultureInfo.InvariantCulture,"{0} {1} {2} {3}",Целое,Дробное,Строка,Дата,0);
Сообщить(SB.ToString());

Получаем

55333 66333.44 абвгд 01/26/2016 17:10:05

Стоит еще добавить приведение типа к Интерфейсу. На примере прохода по коллекции. Если в 1С можно пройтись через Для Каждого то для 7 ки этого сделать нельзя. Заодно понять как приводить к интерфейсу.

Так из документации мы знаем что List<T> поддерживает интерфейс IEnumerable

https://msdn.microsoft.com/ru-ru/library/system.collections.ienumerable(v=vs.100).aspx

 Перечислимый=Врап.ПолучитьИнтерфейс(Список,"IEnumerable");
 Перечислитель=Перечислимый.GetEnumerator();
 // На всякий случай приведем к Интерфейсу IEnumerator
 Перечислитель=Врап.ПолучитьИнтерфейс(Перечислитель,"IEnumerator");
 // Теперь можем пройтись по коллекции
 
Пока Перечислитель.MoveNext() Цикл
//  Врап.ВСтроку вывоит строковое представление всех типов в том числе числовые, строки, неопределено
	Сообщить(Врап.ВСтроку(Перечислитель.Current));

КонецЦикла; 
// Для того что бы получить методы объекта реализующего интерфейс можно
// спомощью метода  ОбновитьДанныеОметодахИСвойствах(object objOrig)


// Для того что бы получить массив String[] можно вызвать
Массив=Список.ToArray();
 Сообщить(Массив);

 // В 1С он будет определен как COMSafeArray VT_BSTR
 // Доступ к элементам массива также как и в COMSafeArray через  GetValue и SetValue
//https://msdn.microsoft.com/library/system.array(v=vs.100).aspx
// Создать массив можно через метод врапера СоздатьМассив(object type, int length)

Еще в .Net для асинхронного программирования используют await и методы возвращающие Task<>

Для того, чтобы получить результат, нужно обратиться к свойству Result, если нужно подождать, то вызвать метод Wait()

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

// Следует отметить, что не все типы из GAC модно подгрузить
// Например  System.Net.Http.HttpClient который находится с System.Net.Http.dll
//Получить тип можно двумя способами
// По полному имени 
//Клиент=Врап.СоздатьОбъект("System.Net.Http.HttpClient, System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
//Либо просто указать имя библиотеку в котором находится класс без полного пути
//Тогда  ПолучитьТипИзСборки будет искать в катаорге GAC
HttpClient=Врап.ПолучитьТипИзСборки("System.Net.Http.HttpClient","System.Net.Http.dll");
Клиент=Врап.СоздатьОбъект(HttpClient);
ДанныеРесурса=Клиент.GetStringAsync("https://msdn.microsoft.com/ru-ru/library/hh551745(v=vs.118).aspx").Result;

Сообщить(Врап.ВСтроку(ДанныеРесурса));

Стоит вспомнить про вложенные типы на примере System.Environment.SpecialFolder 

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

 

Environment=Врап.ПолучитьТип("System.Environment");
	SpecialFolder=Врап.ПолучитьТип("System.Environment+SpecialFolder");
	Сообщить(Environment.GetFolderPath(SpecialFolder.CommonProgramFilesX86));
	Сообщить(Environment.GetFolderPath(SpecialFolder.Desktop));
	Сообщить(Environment.GetFolderPath(SpecialFolder.MyDocuments));
 

Используя System.IO.Path можно получить доступ к Temp директории

Path=Врап.ПолучитьТип("System.IO.Path");
Сообщить(Path.GetTempPath());

Там же много методов для манимулирования с наименованием файла, получение каталога, расширения, объединять строки в путь итд

Очень часто приходится использовать битовую операци 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);
 

Надеюсь, данная статья поможет использовать классы .Net даже тем, кто не знает C#. Ничего сложного нет, но поможет сильно увеличить возможности 1С без написания COM объектов или ВК

136

См. также

Специальные предложения

Комментарии
Избранное Подписка Сортировка: Древо
1. Serginio 757 27.01.16 17:43 Сейчас в теме
Сейчас в .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 Цикл
        задача=АсинхМетоды.ДолгаяЗадача(Строка("Задача "+сч));
        Выполнитель.Выполнить(задача,сч);
    КонецЦикла
70. user643502_olapmail 25.03.18 21:43 Сейчас в теме
Прошу прощения за возможно глупый вопрос... но не могу до конца понять как происходит работа с массивами (.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);


Но хотелось бы иметь под рукой инструменты прямого чтения и прямой записи элементов массива.
71. Serginio 757 25.03.18 22:29 Сейчас в теме
(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# есть перегрузка методов, то передаваемые параметры должны соответствовать типам метода
user643502_olapmail; +1 Ответить
72. user643502_olapmail 25.03.18 23:50 Сейчас в теме
(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".
А может у Вашего проекта есть свой сайт?
74. user643502_olapmail 27.03.18 00:07 Сейчас в теме
(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

?
75. user643502_olapmail 27.03.18 01:42 Сейчас в теме
(74)
Вопрос снимается....
Всё просто...

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

СПАСИБО автору!!! Шикарная компонента
76. user643502_olapmail 28.03.18 17:57 Сейчас в теме
(75) Но... лучше было бы иметь не только:

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

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

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


А может уже есть что-то подобное?
97. user1017144 11.09.18 15:49 Сейчас в теме
(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:\Vs2015Programs\NetObjetToIDispatch45\NetObjetToIDispatch45\­ClassForEvent.cs:строка 188
98. Serginio 757 11.09.18 16:14 Сейчас в теме
(97) Наверное
УдалитьОбработчик Выполнитель.ПриОкончанииВыполненияЗадачи, ПриОкончанииВыполнения;
99. user1017144 12.09.18 08:14 Сейчас в теме
(98)
Добавил строку

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

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

Оператор выполняется, форма закрывается, но через несколько секунд выходит ошибка .Net:
************** Текст исключения **************
System.NullReferenceException: Ссылка на объект не указывает на экземпляр объекта.
в NetObjectToIDispatch45.АсинхронныйВыполнитель.<>c__DisplayClass8_0.<Оповестить>b__0(Object d) в D:\Vs2015Programs\NetObjetToIDispatch45\NetObjetToIDispatch45\­ClassForEvent.cs:строка 188
100. Serginio 757 12.09.18 10:54 Сейчас в теме
(99) Да тма ошибокчка

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

        }


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

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

        }



Сейчас пока нет времени выложить новый
2. jobkostya1c8 28.01.16 18:02 Сейчас в теме
Интересная статья. Надо будет запомнить для задач интеграции. Жаль, что приводится то что не очень надо :( А хотелось бы иметь под рукой библиотеку функций допустим для работы с зависшими процессами (фоновыми задачами), многими функциями ОС итд.
Кстати насчет времени до миллисекунд вроде стандартная консоль запросов содержит строчку на JavaScript для записи текущего времени.
4. Serginio 757 28.01.16 18:22 Сейчас в теме
(2) Ну эта статья для начинающих. Посмотри мои другие статьи. Там много других примеров. Все написать невозможно. Показан принцип работы с классами .Net . Просто нужно найти нужный, а примеров в инете правда на C# полно.
(3) Не понял?
5. jobkostya1c8 28.01.16 19:01 Сейчас в теме
(4) это большой плюс что Вы описали в двух словах "как запустить". Тем более я в этой технологии и есть "начинающий". Хотелось бы узнать кратно что можно и нужно делать через .net если:
1. Такой технологии НЕТ в 1С.
2. Стандартные методы сложны, глючны и малоэффективны.
На что в общем стоит обратить внимание.
6. Serginio 757 28.01.16 23:34 Сейчас в теме
(5) Я бы посоветовал начать с азов. От простого к сложному.
http://metanit.com/sharp/general.php
http://professorweb.ru/my/csharp/charp_theory/level1/infonet.php

Для начала просмотреть, а уже на конкретных задачах углубляться.
7. Andris_infostart 03.02.16 12:37 Сейчас в теме
(2) kostyaomsk, ТекущаяУниверсальнаяДатаВМиллисекундах(), вполне подходит для получения мс
3. jobkostya1c8 28.01.16 18:05 Сейчас в теме
Вернее автору статьи (и знающим людям) вопрос по-другому: я могу вызвать API-функции Винды смотря справочник через данные объекты просто смотря справочник, передавать в функции и принимать от них данные в формате винды (или в универсальном формате). Я когда-то давно начинал с делфи, даже на ассемблере чуток писал для аппаратуры, но сейчас это в прошлом. Тогда только через стандарные компоненты делфи работал.
Чтоб не было голословно приходилось писать только на досовском C++ Может навык пригодится для хотя бы понимания как обратиться к современным библиотекам на C# .net или что там
Прикрепленные файлы:
CH.C
TEST.C
8. olbu 04.02.16 14:51 Сейчас в теме
Интересно!, а есть простые примерчики применения?
10. Ferroks 17.02.16 13:32 Сейчас в теме
Недавно столкнулся с преобразование типов, за 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");
Показать
11. Ferroks 17.02.16 13:41 Сейчас в теме
можно еще так преобразовать тип 1С в тип Net
ТипДесЧерезПарсе = Врап.ПолучитьТип("System.Decimal").Parse("0,000001");

бывает что получаешь ошибку "Неизвестная ошибка" или метод не найдет, проверьте параметр который передаете.
ТипДесЧерезПарсе = Врап.ПолучитьТип("System.Decimal").Parse("0,000001");
- так отрабатывает нормально.
а так выдает ошибку - ТипДесЧерезПарсе = Врап.ПолучитьТип("System.Decimal").Parse("0.000001");
13. Serginio 757 17.02.16 14:34 Сейчас в теме
(11) Как я писал в статье для таких случаев нужно использовать CultureInfo

Decimal=Врап.ПолучитьТип("System.Decimal");
   CultureInfo=Врап.ПолучитьТип("System.Globalization.CultureInfo");
   culture=CultureInfo.InvariantCulture;
   Число="0.000001";
   Сообщить(Decimal.Parse(Число, culture.NumberFormat));
51. asdfgcom 252 12.12.16 21:18 Сейчас в теме
Пытаюсь подключить dll, не являющуюся COM-видимой.

{ВнешняяОбработка.ВнешняяОбработка1.Форма.Форма.Форма(13)}: Ошибка при вызове метода контекста (ПолучитьТипИзСборки)
Infrascturcture=Врап.ПолучитьТипИзСборки("ZGuard.ZG_CTR_EV_TYPE","C:\SDK Guard\ZGuard.dll");
по причине:
Произошла исключительная ситуация (mscorlib): Не удалось загрузить файл или сборку "file:///C:\SDK Guard\ZGuard.dll" либо одну из их зависимостей. Ожидалось, что модуль содержит манифест сборки.

Понимаю, что она не является NET-сборкой. Можно ли это исправить, если есть исходник на C#?
Следует оговориться, что C# не владею (((
12. avz_1C 10 17.02.16 14:28 Сейчас в теме
Простите, а как узнать длину строки через свойство Length переменной типа String?

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

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


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

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

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


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

"Значение не является значением объектного типа (Length)"
14. Serginio 757 17.02.16 14:36 Сейчас в теме
(12) В статье писал про это

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

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

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




15. avz_1C 10 17.02.16 14:41 Сейчас в теме
Получилось так:

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


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

При попытке посмотреть отладчиком 1С структуру объекта стр, система ругается на множество сборок.
16. avz_1C 10 17.02.16 14:43 Сейчас в теме
Не успел прочитать ответ, увидел в статье и тут же попробовал.
О результате сообщил постом выше.
Спасибо!
17. avz_1C 10 17.02.16 14:46 Сейчас в теме
Через МИСТА, по ссылке на яндекс-диск, получил проект (исходники) от NetObjectToIDispatch.dll версии 2.0

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

Ну, очень интересная тема.
19. avz_1C 10 17.02.16 16:20 Сейчас в теме
Спасибо. Получил.
Если, вдруг, потребуются "соучастники" в проект, готов поработать.
Под Вашим руководством :-)
20. Serginio 757 17.02.16 16:48 Сейчас в теме
(19) Спасибо. Буду иметь ввиду. Но самое лучшее это писать статьи как http://infostart.ru/public/434345/
21. avz_1C 10 17.02.16 18:34 Сейчас в теме
Буду пытаться. Благодарю Вас за совет.
Да и Вы, если вдруг захотите расширить аудиторию, милости
просим в авторы блога на сайт www.programmist1c.ru
22. Serginio 757 18.02.16 09:41 Сейчас в теме
(21) Спасибо буду иметь ввиду
23. avz_1C 10 18.02.16 15:02 Сейчас в теме
Добрый день, Сергей.

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

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

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

Можно?

И вот, ещё, встретил в статье след. предложение:
- "Также добавил возможность показать окно семерки созданное через Новый COMОбъект("V77.Application")

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

Прошу прощения, если что-то пропустил, но, вроде бы читал внимательно.
25. Serginio 757 18.02.16 16:34 Сейчас в теме
(23) Я же давал ссылку в 18. Исходники лежат в папке ТестВК
28. avz_1C 10 18.02.16 18:21 Сейчас в теме
(25)

Да, спасибо. Нашел эту папку.
24. avz_1C 10 18.02.16 15:56 Сейчас в теме
При повторном, начиная с третьего, открытии обработки, через Файл -> Открыть ... Появляется сообщение:

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

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

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

26. Serginio 757 18.02.16 16:41 Сейчас в теме
Только там в public partial class Window1 : Window
нужно добавить

public static void СоздатьОкно(dynamic модуль1С, dynamic Object1C)
        {
            модуль1С.СообщитьСтр("Зашли в метод");
            var окно = new Window1(модуль1С, Object1C);
            окно.Show();
            модуль1С.СообщитьСтр("Форма открыта");
        }
29. avz_1C 10 18.02.16 18:22 Сейчас в теме
(26)

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

Сейчас попытаюсь.
27. Serginio 757 18.02.16 16:57 Сейчас в теме
30. avz_1C 10 18.02.16 18:44 Сейчас в теме
(27)

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

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

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

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

не появляется при запуске в тонком клиенте.
31. Serginio 757 19.02.16 10:13 Сейчас в теме
(30) Большое спасибо за использование и тестирование. Помню в 7 ке окно показывалось в списке окон, но при нажатии 1С вылетала. Видно 1С смотрит дочерние окна, но чужое окно она разрулить не может. Посмотрю.
32. avz_1C 10 19.02.16 17:14 Сейчас в теме
Спасибо за Ваш труд.

Никак не наиграюсь :-)

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

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

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

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

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

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

Надо потестировать.
36. Serginio 757 26.02.16 16:11 Сейчас в теме
(32) Это вызов натива из манагед.
А вот обратно нужно что типа CLR Hosting API
37. avz_1C 10 26.02.16 19:22 Сейчас в теме
(36) Пытался провернуть такое на .NET Compact Framework 3.5 ...
Не взлетело.
38. Serginio 757 26.02.16 19:33 Сейчас в теме
39. avz_1C 10 27.02.16 15:32 Сейчас в теме
(38) Приходится работать с CF3.5, так как на ТСД Motorola Symbol (все остальные бренды - копии той или иной степени копийности) в основном установлены Windows CE или Windows Mobile. Пока только китайские китайцы пытаются клепать ТСД и прочие POS девайсы на Windows Phone 8 и даже Windows 10. Нет желающих переделывать отлаженные логистические цепочки под использование экспериментальных образцов. Нет заказчиков - нет разработок.
40. Serginio 757 27.02.16 17:28 Сейчас в теме
(39) Согласен у самого под рукой Casio под Win CE. C Compact FW конечно пришлось повозиться. Но когда появились наработки затем писать уже намного легче.
41. avz_1C 10 28.02.16 15:29 Сейчас в теме
(40) И, может быть, хорошо, что в промышленном оборудовании (ТСД например) нет такого стремительного мелькания техники и технологий, как в товарах группы "Б". Иначе бы все рухнуло. Доля консерватизма необходима в группе "А", не может быть базис текучим и непредсказуемым.
33. Serginio 757 19.02.16 17:26 Сейчас в теме
Эта библиотека основана на преобразование .Net объектов в IDispatch через Ireflect. На линуксе не взлетит
34. Serginio 757 20.02.16 14:32 Сейчас в теме



Очень часто приходится использовать битовую операци 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);


35. Serginio 757 21.02.16 08:12 Сейчас в теме
Пример алгоритма сжатия строки и результат в 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);
Показать
42. Serginio 757 15.03.16 14:52 Сейчас в теме
Понадобилоссь прописать дефолтный принтер в 7 ке

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

    врап.УстЭтоСемерка();
    

Registry=Врап.ПолучитьТип("Microsoft.Win32.Registry");


Ключ="Software\1C\1Cv7\7.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",Принтер);
    КонецЕсли;
КонецЦикла;
Показать
43. olo_lo4 23.04.16 20:01 Сейчас в теме
Добрый день.
врап=новый COMОбъект("NetObjectToIDispatch45");

1С-ка пишет
Ошибка при вызове конструктора (COMОбъект)
врап=новый COMОбъект("NetObjectToIDispatch45");
по причине:
-2147221005(0x800401F3): Недопустимая строка с указанием класса

какие библиотеки нужно доустановить? спасибо
45. olo_lo4 23.04.16 20:32 Сейчас в теме
(44) не получается. можно для тех кто в бронепоезде черным по белому написать.спасибо
46. Serginio 757 23.04.16 21:18 Сейчас в теме
Вторая ссылка в шапке все написано
47. olo_lo4 23.04.16 21:25 Сейчас в теме
Для таких же как и я в подвоной лодке, для начала работы, скачиваете и распаковываете файл ФайлыNetObjectToIDispatch
далее в папке DLLNetObjetToIDispatch45 запускаем RegAsm.bat
либо из корня скаченного файла запускаем РегистрацияКомСервера.exe и выбираем NetObjetToIDispatch45.dll которая лежит в DLLNetObjetToIDispatch45

Взгляд со стороны, без обид:
у автора очень интересный и нужный контент, но подача просто швахт, разбираться в этом адском количестве ссылок и каше неразложенной инфы ...
user643502_olapmail; Misanets; mevgenym; +3 Ответить
48. Serginio 757 23.04.16 21:38 Сейчас в теме
(47) В пианиста просим не стрелять - он играет как умеет.
49. user650124_dao-piglet 09.12.16 18:34 Сейчас в теме
Сергей Смирнов, спасибо! Библиотека очень полезная, и у меня почти работает)))
Объекты 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 попробовал методом тыка.
Что я делаю не так? Заранее спасибо!

50. Serginio 757 10.12.16 18:48 Сейчас в теме
Ты бы показал весь код на 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
52. Serginio 757 13.12.16 11:14 Сейчас в теме
55. asdfgcom 252 13.12.16 16:36 Сейчас в теме
(52) Верно, Сергей. Главное, удалось, все-таки, перекомпилировать dll, после чего dll стала NET сборкой. Удалось достучаться до типов внутри. Сегодня попрактикуюсь вечером. Может и до контроллера достучусь.
Заслуженная звезда.
53. ivan811 13.12.16 11:17 Сейчас в теме
Очень интересно!
Расширяет возможности интеграции
54. Serginio 757 13.12.16 11:39 Сейчас в теме
56. asdfgcom 252 13.12.16 18:13 Сейчас в теме
Вот вопрос...
Код 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:\КонфигурацииКлиентов\Импульс\ZGuard.dll");
	
	ZGIntf_Object=Врап.СоздатьОбъект(ZGIntf);
    IntPtr = Врап.ПолучитьТип("System.IntPtr");
    m_hCvt = IntPtr.Zero;
	Result = ZGIntf_Object.ZG_SearchDevices(); //пока не передаю параметров, т.к. не вижу метода	


получаю Метод объекта не обнаружен (ZG_SearchDevices)
не понял, как добраться до методов??? Вроде он объявлен public.
57. Serginio 757 13.12.16 19:53 Сейчас в теме
А точно ZG_SearchDevices это метод объекта?
Может это статический метод?
Нужно обязательно передавать параметры, так как из-за перегрузок метод ищется по количеству и типам параметров
58. Serginio 757 13.12.16 19:54 Сейчас в теме
59. Serginio 757 13.12.16 20:01 Сейчас в теме
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)
60. asdfgcom 252 13.12.16 20:16 Сейчас в теме
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("Контроллеры не найдены.");
        }

Показать
62. asdfgcom 252 13.12.16 20:23 Сейчас в теме
Вообще, до конца неясно с dll. Дома стоит VC, попробую внимательно проверить и пересобрать библиотеку.
Попытка зарегистрировать DLL вываливается в ненайденную точку входа.
Кроме того обращение к функции инициализации библиотеки без параметров:

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


вываливается с ошибкой "Адресат вызова вызвал исключение.mscorelib System.EntryPointNotFoundException
63. asdfgcom 252 13.12.16 20:25 Сейчас в теме
Вот-вот... С обертками я как раз и слаб пока))) Только-только типы научился брать.
64. Serginio 757 13.12.16 20:25 Сейчас в теме
Либо при запуске формировать в некий список и из него уже выбирать контроллеры.
67. asdfgcom 252 13.12.16 20:31 Сейчас в теме
(64) предположим, создать свою функцию в DLL, обращение к которой, с серийным номером контроллера выполнит его поиск и даст его HANDLE ?
Тем более есть рабочий пример такой функции на C#
69. Serginio 757 13.12.16 21:25 Сейчас в теме
(67) Лучше дописать библиотеку под свои нужды.
65. Serginio 757 13.12.16 20:28 Сейчас в теме
Её не надо регистрировать. NetObjectToIDispatch45 как раз оборачивает .Net объекты через COM класс.

Для начала запусти примеры на C#. Потом двигайся к 1С.
66. asdfgcom 252 13.12.16 20:29 Сейчас в теме
т.е. на стороне DLL предложить уже найденные контроллеры?
68. Serginio 757 13.12.16 20:38 Сейчас в теме
А System.EntryPointNotFoundException говорит о том, что не нашла она в нативной DLL метод ZG_GetVersion

https://msdn.microsoft.com/ru-ru/library/system.entrypointnotfoundexception(v=vs.110).aspx
78. AnL24 29.06.18 11:42 Сейчас в теме
Создаю объекты криптографии,

в этом варианте объект создается корректно
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");
79. AnL24 29.06.18 15:57 Сейчас в теме
(78) В первом случае происходит инициализация нового экземпляра класса X509Certificate2, во втором - конструктор SignedCms() создает экземпляр класса SignedCms.
80. seregasame 07.07.18 16:57 Сейчас в теме
подскажите что делаю не так:

	врап				= новый COMОбъект("NetObjectToIDispatch45"); 
	ФайлСборки			= "C:\Users\ksv\Downloads\jose-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");
Показать
Прикрепленные файлы:
81. Serginio 757 10.07.18 10:31 Сейчас в теме
public static string Decode(string token, object key = null, JwtSettings settings = null)


Добавь еще null. К сожалению в Com варианте не добавляются параметры с дефолтными значениями
Рез = типJWT.Decode(Токен2, ключ, неопределено);
82. Serginio 757 10.07.18 17:01 Сейчас в теме
По 78,79 конкретно какая ошибка?

Возможно загрузить сборку
Сборка  = врап.загрузитьСборку("System.Security.dll");
тип=Сборка.GetType("System.Security.Cryptography.Pkcs.SignedCms"); 

signedCms = Врап.СоздатьОбъект(тип);
84. AnL24 11.07.18 11:04 Сейчас в теме
(82)
По 78,79 конкретно какая ошибка?


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

На строке

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


Получаю ошибку "Ошибка при вызове метода контекста (загрузитьСборку): Произошла исключительная ситуация (mscorlib): Не удалось загрузить файл или сборку "file:///C:\Program Files (x86)\1cv8\common\System.Security.dll" либо одну из их зависимостей. Не удается найти указанный файл."
85. Serginio 757 11.07.18 17:23 Сейчас в теме
(84) А так
тип = Врап.ПолучитьТипИзСборки("System.Security.Cryptography.Pkcs.SignedCms","System.Security.dll");
86. AnL24 12.07.18 14:05 Сейчас в теме
87. AnL24 13.07.18 10:15 Сейчас в теме
(85) Объект SignedCms создал и видны его свойства, но метод Decode не выполняется

signedCms.Decode(encodedSignedCms);

или

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


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

Как заставить работать?)
88. Serginio 757 13.07.18 12:54 Сейчас в теме
А как получаешь encodedSignedCms

public void Decode(
	byte[] encodedMessage
)
89. AnL24 13.07.18 17:07 Сейчас в теме
(88)
File = Врап.ПолучитьТип("System.IO.File");
encodedSignedCms = Врап.ВыполнитьМетод(File, "ReadAllBytes", ПолноеИмяФайла);


Но ругается на то, что метод Decode не найден, а не на содержимое параметра.
90. Serginio 757 13.07.18 18:18 Сейчас в теме
Он метод Decode не может найти по типу параметра.
Можешь для интереса через отладчик посмотреть

Да
File.ReadAllBytes(ПолноеИмяФайла) 
должно работать
91. Serginio 757 13.07.18 18:27 Сейчас в теме
Для интереса проверь методы

врап.ПолучитьМетоды(ТипSignedCms)
92. AnL24 16.07.18 09:14 Сейчас в теме
(91) Метода Decode нет в списке

Врап.ПолучитьМетоды(типSignedCms)	COMОбъект	COMОбъект
IsFixedSize							Истина		Булево
IsReadOnly							Ложь		Булево
IsSynchronized						Ложь		Булево
Length								19			Число
LongLength							19			Число
Rank								1			Число
SyncRoot							COMОбъект	COMОбъект
93. Serginio 757 16.07.18 10:14 Сейчас в теме
Там получаешь список. Нужно еще для Каждого пройтись
94. AnL24 16.07.18 14:57 Сейчас в теме
(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Объект
Показать
95. AnL24 17.07.18 17:04 Сейчас в теме
(93) Метод "Decode" есть, куда дальше копать? Проблема в передаваемом в метод параметре?
96. Serginio 757 18.07.18 12:07 Сейчас в теме
Да проблема в передаваемом параметре (выяснили, что это не метод расширения)

Можешь через отладчик если что посмотреть. Исходники то у тебя есть.
Оставьте свое сообщение