【问题标题】:WinCE: Failed to open the created bluetooth virtual com portWinCE: 无法打开创建的蓝牙虚拟 com 端口
【发布时间】:2018-04-15 00:43:26
【问题描述】:

我正在尝试让蓝牙打印机在 WinCE 手持设备上工作。设备已在Control Panel\Bluetooth Device Property 中设置为受信任,已通过 PIN 验证。

RegisterDevice 调用返回设备句柄,没有错误,但是当我尝试使用 OPEN_EXISTING 通过CreateFileW 打开端口时,我得到了INVALID_HANDLE_VALUE,系统错误代码为 55 ERROR_DEV_NOT_EXIST

我对 WinCE API 很陌生,对 C++ 也很陌生。我看不出问题出在哪里。

我的设置有什么问题?在我可以通过这个 bt-vcom 与打印机通话之前,是否需要采取任何额外的步骤?

我的设备是 WM5 HTC Diamond Phone。在其Communication Manager>Bluetooth>COM Port 部分中,我看不到我创建的任何端口(但它们似乎确实已创建:列在第 3 方应用程序中,例如 TerminalCE,并在尝试使用这些端口在系统 GUI 中创建虚拟 com 端口。)。如果我在此处的系统 GUI 中创建不同的Outgoing Port,Python 可以通过新端口以编程方式与打印机通信。 毕竟我不是在使用相同的 API...为什么我的不工作?

我的代码改编自https://msdn.microsoft.com/en-us/library/ms881004.aspx如下:

# -*- coding: utf-8 -*-
from time import sleep
import ctypes
from ctypes import POINTER, Structure
from ctypes import c_ulonglong, c_int, pointer, c_ulong, c_wchar, c_char, c_ushort
from ctypes import windll, cdll
from ctypes import memset, addressof, sizeof, byref
from comtypes import GUID
from ceserial import Serial

import wintypex as w

# in wintypex
# ULONGLONG = c_ulonglong
# bt_addr = ULONGLONG
# BT_ADDR = POINTER(bt_addr)
# BT_ADDR_PTR = POINTER(BT_ADDR)

# uiportflags 
RFCOMM_PORT_FLAGS_REMOTE_DCB = 0x00000001 
RFCOMM_PORT_FLAGS_KEEP_DCD = 0x00000002 
RFCOMM_PORT_FLAGS_AUTHENTICATE = 0x00000004 
RFCOMM_PORT_FLAGS_ENCRYPT = 0x00000008 

core = windll.coredll # windll.kernel32

RegisterDevice = core.RegisterDevice # HANDLE RegisterDevice(   LPCWSTR lpszType,   DWORD dwIndex, LPCWSTR lpszLib,   DWORD dwInfo );
RegisterDevice.restype = w.HANDLE
RegisterDevice.argtypes = [ w.LPCWSTR, w.DWORD, w.LPCWSTR, w.DWORD ]
DeregisterDevice = core.DeregisterDevice

GetLastError = core.GetLastError
SetLastError = core.SetLastError

# For BT_COM support.
class PORTEMUPortParams(Structure):
    _fields_=[
        ( 'channel', w.INT),
        ( 'flocal', w.INT ),
        ( 'device', w.BT_ADDR),
        ( 'imtu', w.INT ),
        ( 'iminmtu', w.INT ),
        ( 'imaxmtu', w.INT ),
        ( 'isendquota', w.INT ),
        ( 'irecvquota', w.INT ),
        ( 'uuidService', GUID ),
        ( 'uiportflags', w.UINT)
    ]
    def __init__( self, device_str=None, 
                    flocal=False, 
                    channel = None,
                    uuidService=None, 
                    uiportflags=None ):
        if device_str is None and not flocal:
            raise Exception( 'device address missing in client mode.' ) 
        memset( addressof(self), 0, sizeof(self) ) # memset (&pp, 0, sizeof(pp));
        if not flocal:
            bta = c_ulonglong( int(device_str, 16) )
            print(bta)
            bta_p = w.BT_ADDR( bta )
            self.deivce = bta_p
        self.flocal = w.INT( flocal )
        # https://stackoverflow.com/questions/27302060/how-to-check-if-an-paired-bluetooth-device-is-a-printer-or-a-scanner-android
        # " Note: most common UUID (scanners, printers, Mice) 
        # have the generic UUID 0001101-0000-1000-8000-00805F9B34FB "
        if uuidService:
            self.uuidService = uuidService
        else:
            self.uuidService = GUID("{00001101-0000-1000-8000-00805F9B34FB}")
        if uiportflags:
            self.uiportflags = uiportflags
        if channel:
            self.channel = channel & 0xff   # pp.channel = channel & 0xff;

print('class defined.')
print( "try uuidService" )
pp = PORTEMUPortParams('dc1d30428b19')      # PORTEMUPortParams pp;
# pp.uiportflags = RFCOMM_PORT_FLAGS_AUTHENTICATE
# pp.uiportflags = RFCOMM_PORT_FLAGS_REMOTE_DCB
pp.uiportflags = RFCOMM_PORT_FLAGS_REMOTE_DCB | RFCOMM_PORT_FLAGS_AUTHENTICATE

#HANDLE h = RegisterDevice ("COM", index, "btd.dll", (DWORD)&pp );
for i in range (1,10):
    index = i
    SetLastError( w.DWORD(0) )
    h = RegisterDevice(u"COM", index, u"btd.dll", w.DWORD( addressof(pp) ) )
    if h :
        try:
            print( 'handle=', h )
            print( "COM%s" % index )
            s = Serial( port="COM%s:" % index, open_existing=True )
            s.open()
            s.write(u'HELLO\r\n')
            s.flushOutput()
    #                s.write(u'HI\r\n')
    #                s.flushOutput()
            s.close()
        except:
            pass
    #            sleep(2)
        DeregisterDevice( h )
        break
    else:
        print('failed', GetLastError())
    sleep(1)

【问题讨论】:

    标签: bluetooth windows-ce ctypes python-2.5 pythonce


    【解决方案1】:

    在 Windows Mobile 上,库中存在两种创建端口的方法, 第一个是 BluetoothSerialPort 类,这会创建一个连接 _但是它使用的底层 API 相当不可靠,并且 它似乎根本不适用于各种设备类型。_第二个是 BluetoothDeviceInfo.SetServiceState 对于 Win32,这个手动 配置必要的注册表设置并且可靠但可能 需要在端口可用之前重新启动,然后再次命名 不返回新端口。

    https://github.com/inthehand/32feet/wiki/Bluetooth-Serial-Ports

    完全是浪费时间......

    PS:为了控制蓝牙打印机,将winsock函数封装在ctypes中并通过蓝牙套接字与打印机通信,经过一些试验和错误后完美运行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-12
      • 1970-01-01
      • 2012-07-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多