Есть ли способ перечислить все доступные буквы дисков в Python? - PullRequest
40 голосов
/ 06 мая 2009

Более или менее то, что написано на банке: есть ли (простой) способ перечислить все используемые в настоящий момент буквы дисков в системе Windows?

(Кажется, мой гугл-фу подвел меня к этому.)

Связанный:

Ответы [ 14 ]

56 голосов
/ 06 мая 2009

Без использования каких-либо внешних библиотек, если это важно для вас:

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']
54 голосов
/ 06 мая 2009
import win32api

drives = win32api.GetLogicalDriveStrings()
drives = drives.split('\000')[:-1]
print drives

Адаптировано из: http://www.faqts.com/knowledge_base/view.phtml/aid/4670

9 голосов
/ 06 мая 2009

Это похоже на лучшие ответы. Вот мой взломанный хрюк

import os, re
re.findall(r"[A-Z]+:.*$",os.popen("mountvol /").read(),re.MULTILINE)

Немного понюхав ответ RichieHindle ; на самом деле это не лучше, но вы можете заставить Windows работать с реальными буквами алфавита

>>> 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:\\']
8 голосов
/ 06 мая 2009

Репозиторий Microsoft Script включает этот рецепт , который может помочь. У меня нет компьютера с Windows для его тестирования, поэтому я не уверен, что вам нужны «Имя», «Имя системы», «Имя тома» или что-то еще.

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 
7 голосов
/ 09 декабря 2015

Нашел это решение в гугле, слегка доработанное от оригинала. Кажется довольно питоническим и не нуждается в "экзотическом" импорте

import os, string
available_drives = ['%s:' % d for d in string.ascii_uppercase if os.path.exists('%s:' % d)]
4 голосов
/ 11 июня 2016

Я написал этот кусок кода:

import os
drives = [ chr(x) + ":" for x in range(65,90) if os.path.exists(chr(x) + ":") ]

Он основан на ответе @ Barmaley, но имеет преимущество в том, что не использует string модуль, если вы не хотите его использовать. Это также работает в моей системе, в отличие от ответа @ SingleNegationElimination.

3 голосов
/ 08 сентября 2017

В Windows вы можете сделать os.popen

import os
print os.popen("fsutil fsinfo drives").readlines()
3 голосов
/ 26 июля 2016

Более оптимальное решение на основе @ RichieHindle

def get_drives():
    drives = []
    bitmask = windll.kernel32.GetLogicalDrives()
    letter = ord('A')
    while bitmask > 0:
        if bitmask & 1:
            drives.append(chr(letter) + ':\\')
        bitmask >>= 1
        letter += 1

    return drives
1 голос
/ 04 июня 2019

Этот код вернет список названий и букв, например:

['Шлюз (C :)', 'EOS_DIGITAL (L :)', 'Музыкальный архив (O:)']

Используется только стандартная библиотека. Он основан на нескольких идеях, которые я нашел выше. windll.kernel32.GetVolumeInformationW () возвращает 0, если диск пуст, например, CD без диска. Этот код не перечисляет эти пустые диски.

Эти две строки фиксируют буквы всех дисков:

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']

Вот полная процедура:

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
1 голос
/ 04 декабря 2018

Вот еще одно отличное решение, если вы хотите перечислить только диски на вашем диске и не подключенные сетевые диски. Если вы хотите фильтровать по другим атрибутам, просто напечатайте drps.

import psutil
drps = psutil.disk_partitions()
drives = [dp.device for dp in drps if dp.fstype == 'NTFS']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...