0

我正在编写的示例 MSR OPOS 服务对象未正确初始化。我添加这个问题是为了帮助遇到同样问题的其他人,因为各种搜索都没有任何帮助。

我的问题是:如何确定 OPOS 服务对象中缺少什么方法?是否有某种实用程序可以运行 OPOS 服务对象并告诉我缺少什么?有什么方法可以确定接口应该提供哪些方法以及缺少哪些方法?

我正在按照使用 ATL 编写 OPOS 服务对象中的过程来了解如何创建 OPOS 服务对象。我在 Windows XP 下使用 Visual Studio 2005。为了测试基本功能,我使用 NCR 零售服务管理器 (RSM) 实用程序为 MSR 创建配置文件,以便测试磁条阅读器模拟器服务对象的基本功能。

Visual Studio 项目创建 COM 对象并正确注册它。当我尝试在服务对象配置文件上使用 RSM 的诊断功能时,我收到一个错误OPOS_E_NOSERVICE。我在 COM 对象中创建了一个日志文件记录函数,它显示服务对象已加载,DLLMain()COM 对象的函数被调用并被DLLGetClassObject()调用。然而,没有创建记录各种服务对象接口方法的第二个日志文件,表明没有调用任何服务对象接口方法。

因此,服务对象接口似乎存在问题,无法在加载 COM 对象时进行检查。

DllGetClassObject()函数由 Visual Studio ATL 项目向导生成,不需要更改。

使用 POS .NET 1.12 附带的 Microsoft POS .NET 示例实用程序,我尝试使用示例实用程序。我可以在 MSR 节点下的树控件中看到使用 NCR RSM 创建的配置文件。但是,当我尝试Open出现错误消息时。Windows 事件日志显示以下错误。

Microsoft.PointOfService.PosControlException:方法打开引发异常。服务对象不支持其发布所需的一种或多种方法。

4

1 回答 1

0

我终于通过检查和审查代码找到了缺失的方法。事实证明,缺少一个方法,OpenService()Visual Studio 2005 ATL 接口向导没有正确创建该方法,可能是因为它是第一个添加到服务对象接口的方法。

当我尝试使用 Visual Studio 类向导将此方法添加到界面时,在我将方法签名输入到向导对话框并按下“下一步”按钮后,向导会发出错误消息。

使用新的 ATL 项目从头开始重试时,错误对话框具有以下文本:

添加/删除操作是不可能的,因为代码元素“OpenServiceW”是只读的。

当单击该方法时,该方法确实显示在类视图中的 Visual Studio UI 中,但 .idl 文件中的接口定义将其显示为空。

interface IVirtSo : IDispatch{
};

我关闭了 Visual Studio,然后重新打开项目并尝试再次添加它,这次收到错误消息:

未能返回新的代码元素。可能是语法错误。新元素名称:OpenService

进一步调查表明OpenService()Windows API 中有一个方法,可能是 Visual Studio 2005 在我尝试将此方法添加到我的服务对象和它存在于 Windows API 之间发生冲突(实际名称似乎是OpenServiceW())。

我最终做的是添加一个具有相同签名的接口方法,CheckService()使用类向导命名,然后在我生成的代码中存在的任何地方更改接口方法名称,以包括几个作为名称或标签一部分的OpenService()地方CheckService. 出于某种原因,Visual Studio 类向导认为接口方法OpenService()存在,而实际上它并不存在。

但是,在我能够成功执行此操作之前,我必须先退出 Visual Studio,然后删除 Intellisense 文件(.ncb 文件和 .suo 文件),以便使用类视图向导添加新方法可以正常工作。在删除文件之前,即使方法添加失败,向导中的 Add -> Method 的 id 号也会不断增加。删除 Intellisense 文件后,ID 号再次从 1 开始,我可以CheckService()使用向导添加方法,然后OpenService()使用“匹配大小写”打开并打开“匹配整个单词”的“查找”工具手动修改方法名称离开。

到目前为止,我能看到的唯一方法是对照服务对象的源代码实现来查看 OPOS 服务对象规范。

我正在寻找其他可能的解决方案来查找 OPOS 服务对象中缺少的方法。

从文章和我目前的经验来看,以下是 OPOS 服务对象中需要可用的方法的常见子集,以便服务对象正确加载。其中一些仅作为启动和初始化服务对象的一部分被调用一次。作为设置服务对象环境的一部分,可以多次调用其他版本,例如这些版本的 SETGetPropertyNumber()版本。GetPropertyString()对于需要在服务对象中具有相应方法的特定设备类型,特定 OPOS 通用控件对象可能会提供其他入口点。

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);
于 2015-07-14T15:32:53.907 回答