AXForum  
Вернуться   AXForum > Блоги > b_nosoff
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск Все разделы прочитаны

Оценить эту запись

Yet another way to use serial port devices in DAX

Запись от b_nosoff размещена 07.05.2011 в 11:00
Обновил(-а) b_nosoff 04.07.2011 в 11:43 (добавил код для сканера штриховых кодов)

Не думал я, что когда-нибудь буду что-либо писать в блог на АксФоруме... Вообще, больше читать люблю )) Но тут на днях столкнулся с темой, по которой не нашел чего почитать, вообще практически ничего по ней нет. Похоже тема столь древняя, что когда она гремела, интернетов еще толком не было.
Тема эта - написание сервисного объекта для OPOS (была такая технология). Почему она меня заинтересовала спустя десять лет, как она была актуальна? А понадобилось мне привязать к Аксапте сканер прокси-карт. Сканер российского производства. Естественно, никаких драйверов, кроме виртуального последовательного порта. Что делать? Писать ActiveX не хотелось. Тем более, что есть готовые ocx для OPOS от Curtiss Monroe, отлаженные и внушающие доверие, спасибо ему за них. Единственное, чего не было, так это сервисного объекта, но его написание не казалось большой проблемой. До тех пор, пока не начал его писать )) Информации в сети о том, как это делать - около нуля. Единственный сайт, где есть хоть что-то - Monroe Consulting Services.
В общем, разработка темы заняла около трех дней, что на мой взгляд многовато. И я решил поделиться полученным результатом, вдруг у кого-нибудь тоже обострится некрофилия )) По крайней мере, три дня назад мне бы эта информация сохранила бы три дня спокойной жизни. Вот такой сумбурный каламбур.
Прошу судить не строго - в C# я еще тот нуб, если будет у кого желание внести исправления, нет проблем.

В общем, я пришел к выводу, что для того, чтобы написать хоть как-то работающий Service object для OPOS, необходимо реализовать следующий интерфейс (пример для SmartCardRW)
Код:
[Guid("your GUID here"), InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface OPOSSmartCardRWServiceObject_Interface
{
    [DispId(0)]    
    long COFreezeEvents(
        [MarshalAs(UnmanagedType.Bool)]
        bool Freeze);

    [DispId(1)]
    [return: MarshalAs(UnmanagedType.I8)]
    long GetPropertyNumber(long PropIndex);
        
    [DispId(2)]
    void SetPropertyNumber(
        long PropIndex, 
        [MarshalAs(UnmanagedType.I8)] 
        long Number);
        
    [DispId(3)]
    [return: MarshalAs(UnmanagedType.BStr)]
    string GetPropertyString(long PropIndex);
        
    [DispId(4)]    
    void SetPropertyString(
        long PropIndex, 
        [MarshalAs(UnmanagedType.BStr)] 
        String String);
        
    [DispId(5)]
    long OpenService( 
        [MarshalAs(UnmanagedType.BStr)] String DeviceClass,
        [MarshalAs(UnmanagedType.BStr)] String DeviceName,
        [MarshalAs(UnmanagedType.IDispatch)] object pDispatch);


    [DispId(6)]
    long CheckHealth(long Level);

    [DispId(7)]
    long ClaimDevice(long Timeout);

    [DispId(8)]
    long ClearInput();
        
    [DispId(9)]
    long ClearOutput();

    [DispId(10)]
    long CloseService();
        
    [DispId(11)]
    long DirectIO(
        long Command, 
        ref long pData, 
        [MarshalAs(UnmanagedType.BStr)]
        out String pString);

    [DispId(12)]
    long ReleaseDevice();

    [DispId(13)]
    long ResetStatistics(
        [MarshalAs(UnmanagedType.BStr)]
        String StatisticsBuffer);        

    [DispId(14)]
    long RetrieveStatistics(
        [MarshalAs(UnmanagedType.BStr)]
        ref String StatisticsBuffer);

    [DispId(15)]
    long UpdateStatistics(
        [MarshalAs(UnmanagedType.BStr)]
        String StatisticsBuffer);
        
    [DispId(16)]
    long BeginInsertion(long Timeout);

    [DispId(17)]
    long BeginRemoval(long Timeout);

    [DispId(18)]
    long EndInsertion();

    [DispId(19)]
    long EndRemoval();

    [DispId(20)]
    long ReadData(
        long Action,
        ref long pCount,
        [MarshalAs(UnmanagedType.BStr)]
        ref String pData);      
        
    [DispId(21)]
    long WriteData(
        long Action,
        long Count,
        [MarshalAs(UnmanagedType.BStr)]
        String Data);   

    [DispId(22)]
    long CompareFirmwareVersion(
        [MarshalAs(UnmanagedType.BStr)]
        String FirmwareFileName,
        out long pResult); 
  
    [DispId(23)]
    long UpdateFirmware(
        [MarshalAs(UnmanagedType.BStr)]
        String FirmwareFileName); 
 
    [DispId(24)]
    long ClearInputProperties();   
}
И это было самое сложное.Потому как у MCS исходники на C++, и они описывают объект управления. Пришлось изучать сначала их, а потом уже думать, как они будут работать с моим кодом. Вот к чему приводит отсутствие примеров кода в интернетах )) Самое веселое в работе по созданию этого интерфейса было найти значения DispId для всех этих методов и осознать, что есть еще и набор идентификаторов для получения доступа к свойствам сервисного объекта через методы GetProperty и SetProperty, и это разные наборы констант )) Но это все детали. После создания интерфейса остальное уже пошло как по маслу. Готовый код для сервисного объекта SmartCardRW прилагаю. Это, конечно, ужасный код, но вдруг он кому-нибудь сбережет три дня. В общем, надеюсь, не зря я здесь виртуальную бумагу мараю. Конечно, поначалу хотелось написать больше, но куча работы бьет по рукам, поэтому закругляюсь. Если вдруг будет у кого интерес к этому посту, по возможности постараюсь ответить на вопросы. Спасибо за внимание.

Пользуясь случаем, выражаю благодарность Curtiss Monroe, MSDN, RSDN и некоторым другим сайтам, на которые меня забросила судьба (точнее поисковик), и где я почерпнул бесценную информацию для реализации вышеописанного чуда!

UPD: интерфейс для Scanner (сканер штрихового кода) несколько отличается
Код:
public interface OPOSScannerServiceObject_Interface
{
    [DispId(0)]
    long COFreezeEvents(
        [MarshalAs(UnmanagedType.Bool)]
        bool Freeze);

    [DispId(1)]
    [return: MarshalAs(UnmanagedType.I8)]
    long GetPropertyNumber(long PropIndex);

    [DispId(2)]
    void SetPropertyNumber(
        long PropIndex,
        [MarshalAs(UnmanagedType.I8)] 
        long Number);

    [DispId(3)]
    [return: MarshalAs(UnmanagedType.BStr)]
    string GetPropertyString(long PropIndex);

    [DispId(4)]
    void SetPropertyString(
        long PropIndex,
        [MarshalAs(UnmanagedType.BStr)] 
        String String);

    [DispId(5)]
    long OpenService(
        [MarshalAs(UnmanagedType.BStr)] String DeviceClass,
        [MarshalAs(UnmanagedType.BStr)] String DeviceName,
        [MarshalAs(UnmanagedType.IDispatch)] object pDispatch);


    [DispId(6)]
    long CheckHealth(long Level);

    [DispId(7)]
    long ClaimDevice(long Timeout);

    [DispId(8)]
    long ClearInput();

    [DispId(9)]
    long CloseService();

    [DispId(10)]
    long DirectIO(
        long Command,
        ref long pData,
        [MarshalAs(UnmanagedType.BStr)]
        out String pString);

    [DispId(11)]
    long ReleaseDevice();

    [DispId(12)]
    long ResetStatistics(
        [MarshalAs(UnmanagedType.BStr)]
        String StatisticsBuffer);

    [DispId(13)]
    long RetrieveStatistics(
        [MarshalAs(UnmanagedType.BStr)]
        ref String StatisticsBuffer);

    [DispId(14)]
    long UpdateStatistics(
        [MarshalAs(UnmanagedType.BStr)]
        String StatisticsBuffer);

    [DispId(15)]
    long CompareFirmwareVersion(
        [MarshalAs(UnmanagedType.BStr)]
        String FirmwareFileName,
        out long pResult);

    [DispId(16)]
    long UpdateFirmware(
        [MarshalAs(UnmanagedType.BStr)]
        String FirmwareFileName);

    [DispId(17)]
    long ClearInputProperties();
}
UPD2: ну и добавил вроде ничего так работающий код для сканера штриховых кодов
Вложения
Тип файла: zip Service.zip (8.5 Кб, 95 просмотров)
Тип файла: zip OPOSScannerSO.zip (11.9 Кб, 55 просмотров)
Размещено в Без категории
Просмотров 14984 Комментарии 0
Всего комментариев 0

Комментарии

 


Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 14:37.