JeffLIrion / adb_shell

A Python implementation of ADB with shell and FileSync functionality.
Apache License 2.0
546 stars 60 forks source link

No UsbTransport detected. #114

Closed ajuancer closed 4 years ago

ajuancer commented 4 years ago

Hi! I want to try the USB experimental mode, but I have some issues when installing the optional module. I have a script that uses this amazing 😎 library, and I want to upgrade it by implementing the USB mode. As it is written, before any attempt, I ran the command install adb-shell[usb]. Then, just copy-pasted the test code:

from adb_shell.adb_device import AdbDeviceUsb
from adb_shell.auth.sign_pythonrsa import PythonRSASigner

with open('path/to/the/adbkey') as f:
    priv = f.read()
signer = PythonRSASigner('', priv)
device = AdbDeviceUsb('ab78c6ef')
print(device.connect(rsa_keys=[signer], auth_timeout_s=0.1))

But the following error raises:

adb_shell.exceptions.InvalidTransportError: To enable USB support you must install this package via `pip install adb-shell[usb]`

So I tried again uninstalling the module (completely) and installing it again. Note that I invalidated the cache before reinstalling, so no residual files should be stored. But this error raised again. If I run install adb-shell[usb] again, I get:

Requirement already satisfied: adb-shell[usb] in path\site-packages (0.2.0)
Requirement already satisfied: cryptography in path\site-packages (from adb-shell[usb]) (3.0)
Requirement already satisfied: pyasn1 in path\site-packages (from adb-shell[usb]) (0.4.8)
Requirement already satisfied: rsa in path\site-packages (from adb-shell[usb]) (4.6)
Requirement already satisfied: libusb1>=1.0.16; extra == "usb" in path\site-packages (from adb-shell[usb]) (1.8)
Requirement already satisfied: cffi!=1.11.3,>=1.8 in path\site-packages (from cryptography->adb-shell[usb]) (1.14.1)
Requirement already satisfied: six>=1.4.1 in path\site-packages (from cryptography->adb-shell[usb]) (1.15.0)
Requirement already satisfied: pycparser in path\site-packages (from cffi!=1.11.3,>=1.8->cryptography->adb-shell[usb]) (2.20)

I don't understand what causes the error to be raised, especially after searching what the brackets in adb-shell[usb] means and getting this already satisfied requirements. Sorry if it's a stupid question, but I don't know what is wrong. Thanks!

JeffLIrion commented 4 years ago

Are you using Windows? This pull request suggests that there could be issues with USB support on Windows: https://github.com/JeffLIrion/adb_shell/pull/106

Try this and post the error that you get:

from adb_shell.transport.usb_transport import UsbTransport
ajuancer commented 4 years ago

By importing UsbTransport, I get:

Traceback (most recent call last):
  File "path/test.py", line 6, in <module>
    from adb_shell.transport.usb_transport import UsbTransport
  File "path\usb_transport.py", line 59, in <module>
    import usb1
  File "path\usb1\__init__.py", line 61, in <module>
    from . import libusb1
  File "path\usb1\libusb1.py", line 192, in <module>
    libusb = _loadLibrary()
  File "path\usb1\libusb1.py", line 166, in _loadLibrary
    return dll_loader('libusb-1.0' + suffix, **loader_kw)
  File "path\ctypes\__init__.py", line 373, in __init__
    self._handle = _dlopen(self._name, mode)
FileNotFoundError: Could not find module 'libusb-1.0.dll' (or one of its dependencies). Try using the full path with constructor syntax.

So I downloaded the Windows binary from the official site. I placed the libusb-1.0.dll file in the site-packages dir. Also tried with the file placed in the same python.exe dir (/Scripts). Neither of them worked for me, although, after a quick search, looks like this worked here.

JeffLIrion commented 4 years ago

It looks like if you can get Python to find that dll file, it would work. I tried googling "Python ctypes filenotfounderror" and got some promising results. Apparently, this is handled differently for Python 3.8 vs. earlier versions.

Also, I think the ab78c6ef that you copied from the README example will need to be updated. If you get the import issue fixed, try transport = UsbTransport.find_adb() instead. And then device = AdbDevice(transport).

You'll also need to update path/to/the/adbkey.

ajuancer commented 4 years ago

Adding the specific path where the libusb-1.0.dll is located resolves FileNotFoundError: Could not find module 'libusb-1.0.dll' (or one of its dependencies). Try using the full path with constructor syntax.. This can be done with (more info here):

os.add_dll_directory("path_to_working_dlls_directoy")

Now, I get:

Traceback (most recent call last):
  File "path\test.py", line 4, in <module>
    from adb_shell.transport.usb_transport import UsbTransport
  File "path\transport\usb_transport.py", line 59, in <module>
    import usb1
  File "path\usb1\__init__.py", line 61, in <module>
    from . import libusb1
  File "path\usb1\libusb1.py", line 192, in <module>
    libusb = _loadLibrary()
  File "path\usb1\libusb1.py", line 166, in _loadLibrary
    return dll_loader('libusb-1.0' + suffix, **loader_kw)
  File "path\ctypes\__init__.py", line 373, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: [WinError 193] %1 is not a valid Win32 application

The fourth line of my test.py file corresponds to the first change we do to the initial problem:

from adb_shell.transport.usb_transport import UsbTransport

This error was my mistake: as this well-documented answer suggests, architecture problem! (just a slip copying the DLL) With that, all problems fixed!


Also, I think the ab78c6ef that you copied from the README example will need to be updated. If you get the import issue fixed, try transport = UsbTransport.find_adb() instead. And then device = AdbDevice(transport).

You'll also need to update path/to/the/adbkey.

The other suggestions aren't related, but thanks anyway. As I said, this isn't the first time I use the library (it's too helpful that I even tried to implement this experimental mode, but it was too much for me). I'm going to add a simple solution to a problem that could appear in transport = UsbTransport.find_adb():

adb_shell.exceptions.UsbDeviceNotFoundError: No device available, or it is in the wrong configuration.

This error appears when the server is still running. Just kill the server with adb kill-server and ready to go.

Thanks, Jeff for your time😁

ajuancer commented 4 years ago

No UsbTransport detected error ToDo list:

Quick list of the process in order to fix the issue on Windows.

  1. Import UsbTransport: from adb_shell.transport.usb_transport import UsbTransport
  2. Download the libusb binary from the official page.
  3. Extract corresponding libusb-1.0.dll DLL file:
    • either from MinGW32/dll or MS32/dll for 32bits, or
    • from MinGW64/dll or MS64/dll for 64bits.
  4. Add the dir where you have placed libusb-1.0.dll with: os.add_dll_directory("path_to_working_dlls_directoy")