zoukankan      html  css  js  c++  java
  • Python手机开发调用DLL实现部分ADB功能-乾颐堂

    近期学了一点Python,然后正好有一个手机同步工具方面的预研工作要完成。

    要实现PC与手机的通信,首先要找到他们的通信协议,还好的是Android有完善的协议:ADB

    ADB的代码是开源的,而且支持Windows平台,有现成的DLL可以调用:AdbWinApi.dll,AdbWinUsbApi.dll

    好了,可以用VC搞定,但我想用Python试一下,于是开始了苦逼的查资料+实验的过程。

    实验过程就不多说了,由于上面的两个DLL都是用C实现的,提供的头文件也是C语言的,所以有了下面这个python测试程序(Python2.7):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    import ctypes 
        
    #自定义的GUID结构,有兴趣的可以自己研究用uuid模块  
    class GUID(ctypes.Structure): 
        _fields_ = [("Data1", ctypes.c_ulong), 
                    ("Data2", ctypes.c_ushort), 
                    ("Data3", ctypes.c_ushort), 
                    ("Data4", ctypes.c_ubyte*8)] 
        
    #自己定义的一个结构体,便于使用DLL接口  
    class AdbInterfaceInfo(ctypes.Structure): 
        _fields_ = [("class_id", GUID), 
                    ("flags", ctypes.c_ulong), 
                    ("device_name", ctypes.c_wchar*800)] 
        
    def strGUID(GUID): 
        string = '' 
        string = string + '%x' % buff.class_id.Data1 + '-%x' % buff.class_id.Data2 + '-%x' % buff.class_id.Data3 
        string = string + '-%x' % buff.class_id.Data4[0
        string = string + '%x' % buff.class_id.Data4[1
        string = string + '%x' % buff.class_id.Data4[2
        string = string + '%x' % buff.class_id.Data4[3
        string = string + '%x' % buff.class_id.Data4[4
        string = string + '%x' % buff.class_id.Data4[5
        string = string + '%x' % buff.class_id.Data4[6
        string = string + '%x' % buff.class_id.Data4[7
        return string 
        
    dll = ctypes.cdll.LoadLibrary('AdbWinApi.dll'
    usb_class_id = GUID(0xF72FE0D4, 0xCBCB, 0x407d, (0x88, 0x14, 0x9e, 0xd6, 0x73, 0xd0, 0xdd, 0x6b)) 
    enum_handle = dll.AdbEnumInterfaces(usb_class_id, ctypes.c_bool('true'), ctypes.c_bool('true'), ctypes.c_bool('true')) 
        
    while(1): 
        buff = AdbInterfaceInfo() 
        size = ctypes.c_ulong(ctypes.sizeof(buff)) 
        status = dll.AdbNextInterface(enum_handle, ctypes.byref(buff), ctypes.byref(size)) 
        
        if status==1
            #print "GUID = " + strGUID(buff.class_id)  
            #print "status = " + str(status)  
            #print "Name = " + str(buff.device_name)  
            hAdbApi = dll.AdbCreateInterfaceByName(buff.device_name); 
            if hAdbApi == 0
                print 'AdbCreateInterfaceByName Fail'
            else
                serial = ' '*128
                pserial = ctypes.c_char_p() 
                pserial.value = serial 
                serial_len = ctypes.c_ulong(len(serial)) 
                ret = dll.AdbGetSerialNumber(hAdbApi, pserial, ctypes.byref(serial_len), ctypes.c_bool('false')); 
                if ret == 1
                    print 'Device Name: ' + '%s'% serial 
                else
                    print 'Get Device Name Fail'
        else
            print 'Finished'
            break
    import ctypes
    #自定义的GUID结构,有兴趣的可以自己研究用uuid模块
    class GUID(ctypes.Structure):
        _fields_ = [("Data1", ctypes.c_ulong),
                    ("Data2", ctypes.c_ushort),
                    ("Data3", ctypes.c_ushort),
                    ("Data4", ctypes.c_ubyte*8)]
    #自己定义的一个结构体,便于使用DLL接口
    class AdbInterfaceInfo(ctypes.Structure):
        _fields_ = [("class_id", GUID),
                    ("flags", ctypes.c_ulong),
                    ("device_name", ctypes.c_wchar*800)]
    def strGUID(GUID):
        string = ''
        string = string + '%x' % buff.class_id.Data1 + '-%x' % buff.class_id.Data2 + '-%x' % buff.class_id.Data3
        string = string + '-%x' % buff.class_id.Data4[0]
        string = string + '%x' % buff.class_id.Data4[1]
        string = string + '%x' % buff.class_id.Data4[2]
        string = string + '%x' % buff.class_id.Data4[3]
        string = string + '%x' % buff.class_id.Data4[4]
        string = string + '%x' % buff.class_id.Data4[5]
        string = string + '%x' % buff.class_id.Data4[6]
        string = string + '%x' % buff.class_id.Data4[7]
        return string
    dll = ctypes.cdll.LoadLibrary('AdbWinApi.dll')
    usb_class_id = GUID(0xF72FE0D4, 0xCBCB, 0x407d, (0x88, 0x14, 0x9e, 0xd6, 0x73, 0xd0, 0xdd, 0x6b))
    enum_handle = dll.AdbEnumInterfaces(usb_class_id, ctypes.c_bool('true'), ctypes.c_bool('true'), ctypes.c_bool('true'))
    while(1):
        buff = AdbInterfaceInfo()
        size = ctypes.c_ulong(ctypes.sizeof(buff))
        status = dll.AdbNextInterface(enum_handle, ctypes.byref(buff), ctypes.byref(size))
        if status==1:
            #print "GUID = " + strGUID(buff.class_id)
            #print "status = " + str(status)
            #print "Name = " + str(buff.device_name)
            hAdbApi = dll.AdbCreateInterfaceByName(buff.device_name);
            if hAdbApi == 0:
                print 'AdbCreateInterfaceByName Fail'
            else:
                serial = ' '*128
                pserial = ctypes.c_char_p()
                pserial.value = serial
                serial_len = ctypes.c_ulong(len(serial))
                ret = dll.AdbGetSerialNumber(hAdbApi, pserial, ctypes.byref(serial_len), ctypes.c_bool('false'));
                if ret == 1:
                    print 'Device Name: ' + '%s'% serial
                else:
                    print 'Get Device Name Fail'
        else:
            print 'Finished'
            break

    上面这个简单的Python代码,可以通过AdbWinApi.dll和AdbWinUsbApi.dll这两个DLL来找到你PC上正连接着的Android设备。

    只调用了3个DLL接口,但目的已经达到,可以得出下面的结论:

    使用Python调用DLL的方式来实现ADB工具是可行的,当然麻烦是不会少的了。

    写在最后,Python调用C写的DLL还是比较麻烦的,特别是参数传递,尤其是指针的处理,这方面还得依靠ctypes模块。。。

    www.qytang.com/
    http://www.qytang.com/cn/list/29/
    http://www.qytang.com/cn/list/28/610.htm
    http://www.qytang.com/cn/list/28/595.htm
    http://www.qytang.com/cn/list/28/583.htm
    http://www.qytang.com/cn/list/28/582.htm
    http://www.qytang.com/cn/list/28/576.htm
    http://www.qytang.com/cn/list/28/523.htm
    http://www.qytang.com/cn/list/28/499.htm
    http://www.qytang.com/cn/list/28/488.htm
    http://www.qytang.com/cn/list/28/466.htm
    http://www.qytang.com/cn/list/28/463.htm
    http://www.qytang.com/cn/list/28/458.htm
    http://www.qytang.com/cn/list/28/455.htm
    http://www.qytang.com/cn/list/28/447.htm

  • 相关阅读:
    POJ 1811 Prime Test 素性测试 分解素因子
    sysbench的安装与使用
    电脑中已有VS2005和VS2010安装.NET3.5失败的解决方案
    I.MX6 show battery states in commandLine
    RPi 2B Raspbian system install
    I.MX6 bq27441 driver porting
    I.MX6 隐藏电池图标
    I.MX6 Power off register hacking
    I.MX6 Goodix GT9xx touchscreen driver porting
    busybox filesystem httpd php-5.5.31 sqlite3 webserver
  • 原文地址:https://www.cnblogs.com/qytang/p/5584555.html
Copyright © 2011-2022 走看看