2015-11-18 144 views
2

我正在嘗試編寫能夠讀取有關REMOVEABLE_DEVICE(USB)的一些信息的小程序。我試過pyusb,但我無法提取我需要的數據。Python:獲取USB閃存驅動器設備的名稱[windows]

我想從系統中讀取USB設備的名稱。

在這種格式:

USB Flash Memory - this is the model information 
Removable Disk (H:) - this is the name of device 

Generic Flash Disk 
USB DISK (F:) 

Lexar USB Flash Drive 
Lexar (I:) 

我能夠與win32com.client庫,從here啓發,得到模型的信息,但我沒能獲得在Windows資源管理器顯示的設備名稱。

也許我正在使用錯誤的庫?

這裏是我的代碼:

import win32com.client 
strComputer = "." 
objWMIService = win32com.client.Dispatch("WbemScripting.SWbemLocator") 
objSWbemServices = objWMIService.ConnectServer(strComputer,"root\cimv2") 
colItems = objSWbemServices.ExecQuery("SELECT * FROM Win32_DiskDrive WHERE InterfaceType = \"USB\"") 
for objItem in colItems: 
    if objItem.Caption != None: 
     print "Caption:" + ` objItem.Caption[:-11]` 

這裏是鏈接的Windows Win32_DiskDrive類:link

預先感謝您的幫助。

回答

2

免責聲明:我還沒有真正得到任何經驗與win32com.client庫。

通過與Win32_DiskDrive開始像你這樣,我走過去Win32_DiskDriveToDiskPartitionWin32_LogicalDiskToPartition,然後Win32_LogicalDisk得到VolumeName這似乎是你想要的。

import win32com.client 
strComputer = "." 
objWMIService = win32com.client.Dispatch("WbemScripting.SWbemLocator") 
objSWbemServices = objWMIService.ConnectServer(strComputer,"root\cimv2") 

# 1. Win32_DiskDrive 
colItems = objSWbemServices.ExecQuery("SELECT * FROM Win32_DiskDrive WHERE InterfaceType = \"USB\"") 
DiskDrive_DeviceID = colItems[0].DeviceID.replace('\\', '').replace('.', '') 
DiskDrive_Caption = colItems[0].Caption 

print 'DiskDrive DeviceID:', DiskDrive_DeviceID 

# 2. Win32_DiskDriveToDiskPartition 
colItems = objSWbemServices.ExecQuery("SELECT * from Win32_DiskDriveToDiskPartition") 
for objItem in colItems: 
    if DiskDrive_DeviceID in str(objItem.Antecedent): 
     DiskPartition_DeviceID = objItem.Dependent.split('=')[1].replace('"', '') 

print 'DiskPartition DeviceID:', DiskPartition_DeviceID 

# 3. Win32_LogicalDiskToPartition 
colItems = objSWbemServices.ExecQuery("SELECT * from Win32_LogicalDiskToPartition") 
for objItem in colItems: 
    if DiskPartition_DeviceID in str(objItem.Antecedent): 
     LogicalDisk_DeviceID = objItem.Dependent.split('=')[1].replace('"', '') 

print 'LogicalDisk DeviceID:', LogicalDisk_DeviceID 

# 4. Win32_LogicalDisk 
colItems = objSWbemServices.ExecQuery("SELECT * from Win32_LogicalDisk WHERE DeviceID=\"" + LogicalDisk_DeviceID + "\"") 
print 'LogicalDisk VolumeName:', colItems[0].VolumeName 
print 

# putting it together 
print DiskDrive_Caption 
print colItems[0].VolumeName, '(' + LogicalDisk_DeviceID + ')' 

工作對我來說:

DiskDrive DeviceID: PHYSICALDRIVE1 
DiskPartition DeviceID: Disk #1, Partition #0 
LogicalDisk DeviceID: D: 
LogicalDisk VolumeName: PENDRIVE 

Sony Storage Media USB Device 
PENDRIVE (D:) 

這似乎提供了一個複雜的,但可能的方式,也許可以更加簡化它。我唯一的簡化是已經離開了Win32_DiskPartition因爲我們只需要連接。

請注意:

  • 我不知道什麼是「乾淨」的方式來解壓類似\\.\PHYSICALDRIVE1,但它應該有可能擺脫.replace() - 方法的。
  • 我不確定是否有可能將步驟2和3中的循環集成到查詢中?這也將簡化它很多(也許它可能是JOIN他們像SQL一樣?)。
  • (上面的代碼將僅適用於單個USB驅動器工作)。
+0

非常感謝您的回覆。這正是我期待的!很好的描述你的步驟我真的很感激。 – easy4mer

+0

我採用你的代碼,以允許返回多個USB驅動器,如果他們的名字不是空的。我相信我們的作品可以做得更好,但它對我有用。也許別人可以改進它。 – Hakaishin

2

我會看起來很奇怪,但它會奏效(得到所有可移動的卷的Label's列表)

import os 
os.system('echo list volume > Ravi.txt') 
path1 = os.path.join(os.getcwd(),"Ravi.txt") 
os.system('diskpart /s '+path1+' > logfile.txt') 
path2 = os.path.join(os.getcwd(),"logfile.txt") 

Str = open(path2).read() 
Str = Str.split('\n') 
matching = [s for s in Str if "Removable" in s] 

for i in matching: 
    i = ' '.join(i.split()) 
    i = i.split(" ") 
    print i[3]+"("+i[2]+":)" 

輸出

MYPENDRIVE(D:) 
+0

謝謝你的決定。我更喜歡使用Windows API的解決方案。無論如何,有趣的想法,如果我不會找到其他方式,我一定會使用你的解決方案。 – easy4mer

0

我用@adrianus的方法和改進的在其上的位,以返回多個USB驅動器。對於它如何工作檢查他的答案。爲了快速和骯髒的代碼,希望對你有用請查看下:)

def get_usb_volume_name(): # pragma: no cover 
    str_computer = "." 
    logical_disk_device_ids = [] 
    volumes = [] 
    try: 
     obj_wmi_service = win32com.client.Dispatch("WbemScripting.SWbemLocator") 
     obj_swbem_services = obj_wmi_service.ConnectServer(str_computer, "root\cimv2") 

    # 1. Win32_DiskDrive 
    col_items = obj_swbem_services.ExecQuery("SELECT * FROM Win32_DiskDrive WHERE InterfaceType = \"USB\"") 
    for item in col_items: 
     disk_drive_device_ids = item.DeviceID.replace('\\', '').replace('.', '') 

    # 2. Win32_DiskDriveToDiskPartition 
    col_items = obj_swbem_services.ExecQuery("SELECT * from Win32_DiskDriveToDiskPartition") 
    disk_partition_device_ids = [] 
    for obj_item in col_items: 
     for disk_drive_device_id in disk_drive_device_ids: 
      if disk_drive_device_id in str(obj_item.Antecedent): 
       disk_partition_device_ids.append(obj_item.Dependent.split('=')[1].replace('"', '')) 
       break 

    # 3. Win32_LogicalDiskToPartition 
    col_items = obj_swbem_services.ExecQuery("SELECT * from Win32_LogicalDiskToPartition") 
    for objItem in col_items: 
     for disk_partition_device_id in disk_partition_device_ids: 

      if disk_partition_device_id in str(objItem.Antecedent): 
       logical_disk_device_ids.append(objItem.Dependent.split('=')[1].replace('"', '')) 
       break 

    # 4. Win32_LogicalDisk 
    col_items = [] 
    for logical_disk_device_id in logical_disk_device_ids: 
     col_items.append(obj_swbem_services.ExecQuery("SELECT * from Win32_LogicalDisk WHERE DeviceID=\"" + 
                 logical_disk_device_id + "\"")) 

    for col_item in col_items: 
     volumes.append(col_item[0].VolumeName) 
except IndexError: 
    pass 
volumes_result = [] 
logical_disk_device_ids_result = [] 
for i in range(len(volumes)): 
    if volumes[i] != "": 
     volumes_result.append(volumes[i]) 
     logical_disk_device_ids_result.append(logical_disk_device_ids[i]) 

return logical_disk_device_ids_result, volumes_result 

的intendation在這個搞砸了,因此不提供對所有這些線路一個簡單的方法來解決它,然後按空間太繁瑣。願你的編輯幫助你。