В Python, как проверить, существует ли диск без ошибки для съемных дисков?

вот что у меня пока есть:

import os.path as op
for d in map(chr, range(98, 123)): #drives b-z
    if not op.isdir(d + ':/'): continue

проблема в том, что в Windows появляется окно ошибки "нет диска":

Майя.exe - нет диска: нет диска в привод. Вставьте диск в drive DeviceHarddisk1DR1 [отмена, повторная попытка, продолжить]

Я не могу поймать исключение, потому что оно фактически не выдает ошибку Python.

видимо, это происходит только на съемных дисках, где есть буква назначено, но диск не вставлен.

есть ли способ обойти эту проблему без конкретного указания скрипта, который диски пропустить?

в моем сценарии я нахожусь в школьных лабораториях, где буквы дисков меняются в зависимости от того, на каком лабораторном компьютере я нахожусь. Кроме того, у меня нет прав доступа к управлению дисками.

5 ответов


использовать ctypes пакет для доступа к GetLogicalDrives


Если у вас win32file модуль, вы можете позвонить GetLogicalDrives():

def does_drive_exist(letter):
    import win32file
    return (win32file.GetLogicalDrives() >> (ord(letter.upper()) - 65) & 1) != 0

чтобы отключить всплывающее окно ошибки, вам нужно установить SEM_FAILCRITICALERRORS флаг ошибки Windows с помощью pywin:

old_mode = win32api.SetErrorMode(0)
SEM_FAILCRITICALERRORS = 1 # not provided by PyWin, last I checked
win32api.SetErrorMode(old_mode & 1)

Это говорит Win32 не показывать диалог повтора; когда происходит ошибка, она немедленно возвращается в приложение.

обратите внимание, что это то, что Python звонки должно сделать. В принципе, Python должен устанавливать этот флаг для вас. К сожалению, поскольку Python может быть встроен в другую программу, он не может изменять флаги процесса, такие как что и Win32 не имеет возможности указать этот флаг влияет только на Python, а не остальной код.


вот способ, который работает как на Windows, так и на Linux, как для Python 2 и 3:

import platform,os
def hasdrive(letter):
    return "Windows" in platform.system() and os.system("vol %s: 2>nul>nul" % (letter)) == 0

пока небольшой разбор допустим, это один из способов сделать это без установки win32api и без итерации всех возможных букв диска.

from subprocess import check_output
def getDriveLetters():
    args = [
        'wmic',
        'logicaldisk',
        'get',
        'caption,description,providername',
        '/format:csv'
    ]
    output = check_output(args)
    results = list()
    for line in  output.split('\n'):
        if line:
            lineSplit = line.split(',')
            if len(lineSplit) == 4 and lineSplit[1][1] == ':':
                results.append(lineSplit[1][0])
    return results

вы также можете проанализировать для определенных типов дисков, таких как" сетевое подключение", чтобы получить список всех подключенных к сети букв дисков, добавив and lineSplit[2] == 'Network Connection' например.

альтернативно, вместо того, чтобы возвращать список, вы можете вернуть словарь, где ключи являются буквами диска, а значения - UNC-путями (lineSplit[3]). Или любую другую информацию, которую вы хотите вытащить из wmic. Чтобы увидеть больше вариантов: wmic logicaldisk get /?