Как я могу проверить, находится ли диск в приводе с использованием Python? - PullRequest
4 голосов
/ 12 мая 2009

Скажем, я хочу манипулировать некоторыми файлами на флоппи-дисководе или устройстве чтения карт USB. Как проверить, готов ли рассматриваемый диск? (То есть физически вставлен диск.)

Буква диска существует , поэтому os.exists () всегда будет возвращать True в этом случае. Кроме того, на данный момент в процессе я еще не знаю имен файлов, поэтому проверка, существует ли данный файл, также не будет работать.

Некоторые уточнения: проблема здесь в обработке исключений. Большинство запросов Win32 API просто вызывают исключение, когда вы пытаетесь получить доступ к диску, который не готов. Обычно это будет работать нормально - найдите что-то вроде свободного места, а затем перехватите возбужденное исключение и предположите, что это означает, что диска нет. Тем не менее, даже когда я перехватываю все без исключения исключения, я все равно получаю диалоговое окно сердитого исключения из Windows, в котором говорится, что устройство чтения гибких дисков и карт не готово. Итак, я думаю, что реальный вопрос - как я могу подавить окно ошибки Windows?

Ответы [ 5 ]

7 голосов
/ 20 июня 2009

И ответ, как и во многих других вещах, оказывается в статье о программировании на C ++ / Win32 десятилетия назад .

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

Но, как выясняется, существует вызов Win32 API для решения этой проблемы, в первую очередь SetErrorMode()

В двух словах (и я подробно описываю здесь много деталей), мы можем использовать SetErrorMode(), чтобы заставить Windows перестать быть настолько параноиком, сделаем свое дело и позволим программе справиться с ситуацией, и затем сбросьте режим ошибок Windows обратно к тому, что был раньше, как будто мы никогда там не были. (Возможно, здесь есть шутка с Кайзером Созе, но сегодня у меня было неправильное количество кофеина, чтобы найти его.)

Адаптация примера кода C ++ из связанной статьи, которая выглядит примерно так:

int OldMode; //a place to store the old error mode
//save the old error mode and set the new mode to let us do the work:
OldMode = SetErrorMode(SEM_FAILCRITICALERRORS); 
// Do whatever we need to do that might cause an error
SetErrorMode(OldMode); //put things back the way they were

В C ++ для правильного обнаружения ошибок требуется функция `GetLastError () ', о которой, к счастью, нам не нужно беспокоиться, поскольку это вопрос Python. В нашем случае обработка исключений в Python работает нормально. Это функция, которую я собрал вместе, чтобы проверить букву диска на «готовность», и все готово для вставки копии, если кому-то еще это понадобится:

import win32api
def testDrive( currentLetter ):
    """
    Tests a given drive letter to see if the drive is question is ready for 
    access. This is to handle things like floppy drives and USB card readers
    which have to have physical media inserted in order to be accessed.
    Returns true if the drive is ready, false if not.
    """
    returnValue = False
    #This prevents Windows from showing an error to the user, and allows python 
    #to handle the exception on its own.
    oldError = win32api.SetErrorMode( 1 ) #note that SEM_FAILCRITICALERRORS = 1
    try:
        freeSpace = win32file.GetDiskFreeSpaceEx( letter )
    except:
        returnValue = False
    else:
        returnValue = True
    #restore the Windows error handling state to whatever it was before we
    #started messing with it:
    win32api.SetErrorMode( oldError )
    return returnValue

В последние несколько дней я довольно часто этим пользуюсь, и он прекрасно работает как для дискет, так и для устройств чтения карт USB.

Несколько замечаний: практически любая функция, нуждающаяся в доступе к диску, будет работать в блоке try - все, что мы ищем, исключение из-за отсутствия носителя.

Кроме того, хотя пакет python win32api предоставляет все необходимые функции, он, похоже, не имеет каких-либо констант флагов. После поездки в древние недра MSDN оказалось, что SEM_FAILCRITICALERRORS равен 1, что делает нашу жизнь ужасно легкой.

Надеюсь, это поможет кому-то еще с подобной проблемой!

4 голосов
/ 12 мая 2009

Вы можете сравнить len(os.listdir("path")) с нулем, чтобы увидеть, есть ли какие-либо файлы в каталоге.

1 голос
/ 12 мая 2009

Вы можете использовать функции win32 через отличный pywin32 (http://sourceforge.net/projects/pywin32/) для этой цели.

Предлагаю посмотреть на функцию GetDiskFreeSpace. Вы можете проверить свободное место на целевом диске и продолжить на основе этой информации.

В качестве альтернативы вы можете наблюдать за изменениями каталога или файла с помощью функции ReadDirectoryChangesW. Вы будете получать уведомления об изменениях файлов и т. Д. Но вы должны проверить, работает ли это для вас или нет. Вы можете посмотреть на этот пример для себя: http://timgolden.me.uk/python/downloads/watch_directory.py

1 голос
/ 12 мая 2009

Если у вас есть pythonwin, поможет ли какая-либо информация из этого рецепта ?

По-видимому, стоит обратить внимание на "Доступность" и "Статус". Или вы можете проверить имя тома, которое, я думаю, будет либо «X:», либо «», если на диске ничего нет. Или, чёрт возьми, ищите свободное место или общее количество блоков.

0 голосов
/ 12 мая 2009

Не уверен насчет вашей платформы, но SNMP может быть решением для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...