Is there a way in Python to list all the currently in-use drive letters in a Windows system?
(My Google-fu seems to have let me down on this one)
A C++ equivalent: Enumerating all available drive letters in Windows
Is there a way in Python to list all the currently in-use drive letters in a Windows system?
(My Google-fu seems to have let me down on this one)
A C++ equivalent: Enumerating all available drive letters in Windows
import win32api
drives = win32api.GetLogicalDriveStrings()
drives = drives.split('\000')[:-1]
print drives
Adapted from: http://www.faqts.com/knowledge_base/view.phtml/aid/4670
Without using any external libraries, if that matters to you:
import string
from ctypes import windll
def get_drives():
drives = []
bitmask = windll.kernel32.GetLogicalDrives()
for letter in string.uppercase:
if bitmask & 1:
drives.append(letter)
bitmask >>= 1
return drives
if __name__ == '__main__':
print get_drives() # On my PC, this prints ['A', 'C', 'D', 'F', 'H']
Those look like better answers. Here's my hackish cruft
import os, re
re.findall(r"[A-Z]+:.*$",os.popen("mountvol /").read(),re.MULTILINE)
Riffing a bit on RichieHindle's answer; it's not really better, but you can get windows to do the work of coming up with actual letters of the alphabet
>>> import ctypes
>>> buff_size = ctypes.windll.kernel32.GetLogicalDriveStringsW(0,None)
>>> buff = ctypes.create_string_buffer(buff_size*2)
>>> ctypes.windll.kernel32.GetLogicalDriveStringsW(buff_size,buff)
8
>>> filter(None, buff.raw.decode('utf-16-le').split(u'\0'))
[u'C:\\', u'D:\\']
The Microsoft Script Repository includes this recipe which might help. I don't have a windows machine to test it, though, so I'm not sure if you want "Name", "System Name", "Volume Name", or maybe something else.
import win32com.client
strComputer = "."
objWMIService = win32com.client.Dispatch("WbemScripting.SWbemLocator")
objSWbemServices = objWMIService.ConnectServer(strComputer,"root\cimv2")
colItems = objSWbemServices.ExecQuery("Select * from Win32_LogicalDisk")
for objItem in colItems:
print "Access: ", objItem.Access
print "Availability: ", objItem.Availability
print "Block Size: ", objItem.BlockSize
print "Caption: ", objItem.Caption
print "Compressed: ", objItem.Compressed
print "Config Manager Error Code: ", objItem.ConfigManagerErrorCode
print "Config Manager User Config: ", objItem.ConfigManagerUserConfig
print "Creation Class Name: ", objItem.CreationClassName
print "Description: ", objItem.Description
print "Device ID: ", objItem.DeviceID
print "Drive Type: ", objItem.DriveType
print "Error Cleared: ", objItem.ErrorCleared
print "Error Description: ", objItem.ErrorDescription
print "Error Methodology: ", objItem.ErrorMethodology
print "File System: ", objItem.FileSystem
print "Free Space: ", objItem.FreeSpace
print "Install Date: ", objItem.InstallDate
print "Last Error Code: ", objItem.LastErrorCode
print "Maximum Component Length: ", objItem.MaximumComponentLength
print "Media Type: ", objItem.MediaType
print "Name: ", objItem.Name
print "Number Of Blocks: ", objItem.NumberOfBlocks
print "PNP Device ID: ", objItem.PNPDeviceID
z = objItem.PowerManagementCapabilities
if z is None:
a = 1
else:
for x in z:
print "Power Management Capabilities: ", x
print "Power Management Supported: ", objItem.PowerManagementSupported
print "Provider Name: ", objItem.ProviderName
print "Purpose: ", objItem.Purpose
print "Quotas Disabled: ", objItem.QuotasDisabled
print "Quotas Incomplete: ", objItem.QuotasIncomplete
print "Quotas Rebuilding: ", objItem.QuotasRebuilding
print "Size: ", objItem.Size
print "Status: ", objItem.Status
print "Status Info: ", objItem.StatusInfo
print "Supports Disk Quotas: ", objItem.SupportsDiskQuotas
print "Supports File-Based Compression: ", objItem.SupportsFileBasedCompression
print "System Creation Class Name: ", objItem.SystemCreationClassName
print "System Name: ", objItem.SystemName
print "Volume Dirty: ", objItem.VolumeDirty
print "Volume Name: ", objItem.VolumeName
print "Volume Serial Number: ", objItem.VolumeSerialNumber
Here is another great solution if you want to list only drives on your disc and not mapped network drives. If you want to filter by different attributes just print drps.
import psutil
drps = psutil.disk_partitions()
drives = [dp.device for dp in drps if dp.fstype == 'NTFS']
here's a simpler version, without installing any additional modules or any functions. Since drive letters can't go beyond A and Z, you can search if there is path available for each alphabet, like below:
>>> import os
>>> for drive_letter in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ':
if os.path.exists(f'{drive_letter}:'):
print(f'{drive_letter}:')
else:
pass
the one-liner:
>>> import os
>>> [f'{d}:' for d in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' if os.path.exists(f'{d}:')]
['C:', 'D:']
This code will return of list of drivenames and letters, for example:
['Gateway(C:)', 'EOS_DIGITAL(L:)', 'Music Archive(O:)']
It only uses the standard library. It builds on a few ideas I found above. windll.kernel32.GetVolumeInformationW() returns 0 if the disk drive is empty, a CD rom without a disk for example. This code does not list these empty drives.
These 2 lines capture the letters of all of the drives:
bitmask = (bin(windll.kernel32.GetLogicalDrives())[2:])[::-1] # strip off leading 0b and reverse
drive_letters = [ascii_uppercase[i] + ':/' for i, v in enumerate(bitmask) if v == '1']
Here is the full routine:
from ctypes import windll, create_unicode_buffer, c_wchar_p, sizeof
from string import ascii_uppercase
def get_win_drive_names():
volumeNameBuffer = create_unicode_buffer(1024)
fileSystemNameBuffer = create_unicode_buffer(1024)
serial_number = None
max_component_length = None
file_system_flags = None
drive_names = []
# Get the drive letters, then use the letters to get the drive names
bitmask = (bin(windll.kernel32.GetLogicalDrives())[2:])[::-1] # strip off leading 0b and reverse
drive_letters = [ascii_uppercase[i] + ':/' for i, v in enumerate(bitmask) if v == '1']
for d in drive_letters:
rc = windll.kernel32.GetVolumeInformationW(c_wchar_p(d), volumeNameBuffer, sizeof(volumeNameBuffer),
serial_number, max_component_length, file_system_flags,
fileSystemNameBuffer, sizeof(fileSystemNameBuffer))
if rc:
drive_names.append(f'{volumeNameBuffer.value}({d[:2]})') # disk_name(C:)
return drive_names
This will help to find valid drives in windows os
import os
import string
drive = string.ascii_uppercase
valid_drives = []
for each_drive in drive:
if os.path.exist(each_drive+":\\"):
print(each_drive)
valid_drives.append(each_drive+":\\")
print(valid_drives)
The output will be
C
D
E
['C:\\','D:\\','E:\\']
If you want only the letters for each drive, you can just:
from win32.win32api import GetLogicalDriveStrings
drives = [drive for drive in GetLogicalDriveStrings()[0]]