2015-07-14 6 views
0

Пример объекта службы MSOS OPOS, который я пишу, не инициализировался должным образом. Я добавляю этот вопрос, чтобы помочь другим, сталкивающимся с одной и той же проблемой, поскольку различные поиски не привели к какой-либо помощи.OPOS_E_NOSERVICE после возврата из DllGetClassObject() в простой объект службы ATL COM OPOS

Мой вопрос: Как определить, какой метод в объекте службы OPOS отсутствует? Есть ли какая-либо полезность, которая может использовать объект службы OPOS и сказать мне, чего не хватает? Есть ли способ определить, какие методы должен предоставлять интерфейс, а какие отсутствуют?

Я следую процедуре в Writing an OPOS Service Object using ATL, чтобы узнать, как создается объект службы OPOS. Я использую Visual Studio 2005 под Windows XP. Чтобы проверить базовую функциональность, я использую утилиту NCR Retail Services Manager (RSM) для создания профиля для MSR, чтобы проверить базовые функциональные возможности сервисного объекта Simulator Reader Mag Stripe Reader.

Проект Visual Studio создает COM-объект и регистрирует его должным образом. Когда я пытаюсь использовать функцию диагностики RSM в профиле объекта службы, я получаю сообщение об ошибке OPOS_E_NOSERVICE. Я создал функцию регистрации журнала в объекте COM, которая показывает, что объект службы загружен, вызывается функция объекта DLLMain() объекта COM и вызывается DLLGetClassObject(). Однако второй файл журнала, который регистрирует различные методы интерфейса Service Object, не создается, показывая, что не вызваны ни один из методов интерфейса Service Object.

По-видимому, существует проблема с интерфейсом Service Object, который не выполняет проверку, выполняемую во время загрузки COM-объекта.

Функция DllGetClassObject() создана мастером проектов Visual Studio ATL и не требует изменений.

С помощью утилиты Microsoft POS .NET, которая поставляется с POS .NET 1.12, я попытался использовать утилиту sample. Я вижу профиль, созданный с помощью NCR RSM в дереве управления под узлом MSR. Однако при попытке ввода Open появляется сообщение об ошибке. В журнале событий Windows отображается следующая ошибка.

Microsoft.PointOfService.PosControlException: метод Open бросил исключение . Объект службы не поддерживает один или несколько методов , необходимых для его выпуска.

+0

Ваше сообщение будет удалено, если вы не сделаете это надлежащим образом. Задайте вопрос, напишите ответ. –

+0

@ HansPassant, это лучше? Я выполнил поиск в Google на OPOS_E_NOSERVICE, и этот вопрос появился на первой странице результатов. Если бы у меня был этот вопрос два дня назад, это помогло бы мне, поэтому я надеюсь, что это поможет другим. Это кажется довольно эзотерической областью без большой документации. –

ответ

0

Я, наконец, нашел отсутствующий метод от осмотра и обзора кода. Оказывается, существует один отсутствующий метод, OpenService(), который мастер интерфейса интерфейса Visual Studio 2005 не создавался должным образом, возможно, потому что это был первый метод, который должен быть добавлен в интерфейс для объекта службы.

Когда я попытался добавить этот метод к интерфейсу с помощью мастера классов Visual Studio, мастер выдал сообщение об ошибке после ввода сигнатуры метода в диалоговое окно мастера и нажал кнопку «Далее».

Когда повторная попытка с нуля нового проектом ATL, диалоговая ошибка имела следующий текст:

Add/Remove операция невозможна, так как элемент кода «OpenServiceW» только для чтения.

Хотя метод показал в пользовательском интерфейсе Visual Studio в представлении класса при щелчке по методу, определение интерфейса в файле .idl показало его пустым.

interface IVirtSo : IDispatch{ 
}; 

Я закрыл Visual Studio затем вновь проект и попытался снова добавить его в этот раз получаю сообщение об ошибке:

Не удалось вернуть новый элемент кода. Возможно синтаксическая ошибка. Новый элемент Имя: OpenService

Дальнейшее исследование указывает на то, что существует OpenService() метод в Windows API, и это может быть, что Visual Studio 2005 врезался в конфликт между моей попытке добавить этот метод к моему Object Service и этим существующий в API Windows (фактическое имя - OpenServiceW()).

То, что я, наконец, в конечном итоге делаю, чтобы добавить метод интерфейса с той же подписью, названным CheckService() с помощью мастера класса, а затем изменил имя методы интерфейса везде, где он существовал в моем сгенерированном коде OpenService() включая пару мест, где CheckService был частью имени или ярлыка. По какой-то причине мастер класса Visual Studio думал, что метод интерфейса OpenService() существует, когда на самом деле этого не произошло.

Однако, прежде чем я смог сделать это успешно, мне пришлось сначала выйти из Visual Studio, а затем удалить файлы Intellisense (файл .ncb и файл .suo), чтобы добавить новые методы с помощью мастера классов. Перед удалением файлов, номер идентификатора Add -> Method в мастере продолжал увеличиваться даже при неудачной попытке метода. После удаления файла Intellisense номер идентификатора снова начинался с 1, и я смог добавить метод CheckService() с помощью мастера, а затем изменить имя метода на OpenService() вручную, используя инструмент «Найти» с включенным «Матч-регистр» и «Сопоставить целое слово " выключен.

Единственный способ, который я могу видеть до сих пор, - это просмотреть спецификацию объекта OPOS-службы в отношении реализации объекта-объекта исходного кода.

Я ищу другие возможные способы поиска методов, отсутствующих в объекте службы OPOS.

Из статьи и моего текущего опыта представляется, что следующие общие подмножества методов, которые должны быть доступны в объекте службы OPOS, чтобы объект службы загружался должным образом. Некоторые из них вызывается только один раз в качестве части запуска и инициализации объекта службы. Другие, такие как GetPropertyNumber() и GetPropertyString(), а также версии SET, могут быть вызваны несколько раз в рамках настройки среды объекта службы. Могут быть другие точки входа, предлагаемые конкретным объектом OPOS Common Controls для определенного типа устройства, который должен иметь соответствующий метод в объекте службы.

HRESULT OpenService(BSTR DeviceClass, BSTR DeviceName, IDispatch* pDispatch, [out, retval] long* pRC); 
HRESULT CheckHealth(long Level, [out, retval] long* pRC); 
HRESULT ClaimDevice(long ClaimTimeout, [out, retval] long* pRC); 
HRESULT ClearInput([out, retval] long* pRC); 
HRESULT CloseService([out, retval] long* pRC); 
HRESULT COFreezeEvents(VARIANT_BOOL Freeze, [out, retval] long* pRC); 
HRESULT DirectIO(long Command, [in, out] long* pData, [in, out] BSTR* pString, [out, retval] long* pRC); 
HRESULT ReleaseDevice([out, retval] long* pRC); 

HRESULT GetPropertyNumber(long PropIndex, [out, retval] long* pNumber); 
HRESULT GetPropertyString(long PropIndex, [out, retval] BSTR* pString); 
HRESULT SetPropertyNumber(long PropIndex, long Number); 
HRESULT SetPropertyString(long PropIndex, BSTR PropString); 
+1

Все методы, определенные в исходной версии OPOS (1.0) для класса устройства, должны быть в вашем SO, чтобы он успешно открывался.Вы можете найти методы и версию, которые они изначально появились в спецификации OPOS. Когда open не удается, используйте метод GetOpenResult, чтобы получить описательный код ошибки. – dhanushka