jgrant
jgrant

Reputation: 1423

Identify drive letter of USB device using Python

I have a USB composite device that has an SD card. Using Python, I need a way to find the drive letter of the SD card when the device is connected. Does anyone have experience with this? Initially it needs to work in Windows, but I'll eventually need to port it to Mac and Linux.

Upvotes: 1

Views: 3181

Answers (3)

chad
chad

Reputation: 66

I know it's been 3 years, but I was trying to solve something similar, only I had a known size of compactflash card that I was trying to read, so I had to go backwards from jgrant's final example above. Still, it was extremely helpful (thank you jgrant AND Bill Bell), but I also wanted to do it without the SQL and the wmi package allows for that. I don't personally care much about "pythonic" or "not pythonic", but for those who might like the SQL-syntax-free version (though it's very likely what's done under the hood with wmi), here's a reworked version of the above going from a model name to a drive letter. Note, You could very easily collapse the two if-blocks to just be nested under the conditional above them, but I left them broken out here to better illustrate the connections between wmi objects being made:

import wmi

model = "Generic- USB3.0 CRW-CF/MD USB Device"

disks                      = wmi.WMI().Win32_DiskDrive()
drives_to_partitions       = wmi.WMI().Win32_DiskDriveToDiskPartition()
paritions_to_logical_disks = wmi.WMI().Win32_LogicalDiskToPartition()

drive_letter_name       = None
cf_drive_partition_name = None
drive_device_id         = None

for disk in disks:
    if disk.Model == model:
        drive_device_id = disk.DeviceID

if drive_device_id != None:
    for d_2_p in drives_to_partitions:
        if d_2_p.Antecedent.DeviceID == drive_device_id:
            cf_drive_partition_name = d_2_p.Dependent.DeviceID 
            #different DeviceID, don't let the reuse fool you

if cf_drive_partition_name != None:
    for p_2_ld in paritions_to_logical_disks:
        if p_2_ld.Antecedent.DeviceID == cf_drive_partition_name:
            drive_letter_name = p_2_ld.Dependent.DeviceID
            #yet another reuse of "DeviceID"

print(drive_letter_name)            

Upvotes: 1

jgrant
jgrant

Reputation: 1423

Thanks to Bill's advice, I was able to solve this problem using WMI queries. As he stated in his answer, you need to install Tim Golden's WMI module.

In this example I'll search for the drive letter of a disk with a Model of "WDC WD20EZRX-00D8PB0 ATA Device". To see all the connected drives.

import wmi
c = wmi.WMI ()

for drive in c.Win32_DiskDrive():
    print drive

Once you have the model, you can add it to following query:

import wmi
c = wmi.WMI ()

for disk in c.query('SELECT * FROM Win32_DiskDrive WHERE Model LIKE "WDC WD20EZRX-00D8PB0 ATA Device"'):
    deviceID = disk.DeviceID

    for partition in c.query('ASSOCIATORS OF {Win32_DiskDrive.DeviceID="' + deviceID + '"} WHERE AssocClass = Win32_DiskDriveToDiskPartition'):

        for logical_disk in c.query('ASSOCIATORS OF {Win32_DiskPartition.DeviceID="' + partition.DeviceID + '"} WHERE AssocClass = Win32_LogicalDiskToPartition'):
            print('Drive letter: {}'.format(logical_disk.DeviceID))

which outputs

Drive letter: K:

First the appropriate disk is found, then that disk is searched for partitions, and finally the logical disk volume is found for the partition.

Upvotes: 5

Bill Bell
Bill Bell

Reputation: 21643

I don't have an SD card attached to a USB port. To get you started, you could try this on Windows. Install Golden's WMI. I found that the Windows .zip wouldn't install but the pip version works fine, or at least it does on Win7. Then you can list logical disks with code like this.

>>> import wmi
>>> c=wmi.WMI()
... 
>>> for disk in c.Win32_LogicalDisk():
...     print(disk)

This code provided a listing that included mention of a NAS which is why I have hopes for your SD card. Various refinements are possible.

Upvotes: 4

Related Questions