This module provides easy control of cd drives on Win32 machines. Using the Python Win32 Extensions, the module automatically detects all cd drives and defaults to the first drive found or to a programmer specified drive. Methods include eject() to open the drive door, close() to close the drive door, and load() which tries to close the drive door and then make the drive available to the file system.
To test either import the WinCDRom module and create an instance of the Cdrom class:
import WinCDRom cd = WinCDRom.Cdrom() cd.eject() cd.close() cd.load()
Or just run the script from a DOS prompt to use the test function:
C:\python WinCDRom.py
Listing drives: ['D:'] Default drive: D: Opening drive door... Closing cd drive door... (CD read attempt will time out at 5 seconds.) Loaded cd successfully in drive D: WinCDRom Tests completed.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | '''
Python Module: WinCDROM
Purpose: Loads or unloads a cd-rom drive on Windows. Only
tested on Windows 2000 and XP.
'''
import os, time
try:
import win32file, win32api
from win32con import *
except ImportError:
print "The WinCDROM module requires the Python Win32 extensions."
raise
class Cdrom:
'''Controls for loading,ejecting, and reading cds on Win32 platforms.'''
def __init__(self, drive=None, timeout=20):
'''Accepts a cd drive letter. For example 'E:' or 'e'.'''
self.drives = []
try:
self.drive = drive[:1].upper()
except TypeError:
self.drive = ''
self.getDrives()
self.timeout = timeout
def __getDeviceHandle(self, drive=''):
'''Returns a properly formatted device handle for DeviceIOControl call.'''
drive = drive[:1]
return "\\\\.\\%s:" % drive.upper()
def __is_cd_inserted(self, drive=''):
try:
x = win32api.GetVolumeInformation(drive)
#print "CD is inserted in drive %s" % drive
return 1
except:
#print "no CD inserted in drive %s" % drive
return 0
def getDrives(self):
'''Assign all available cd drives to self.drives. If CdRom.drive
is not already set the first drive returned becomes the default.
'''
letters = [l.upper() + ':' for l in 'abcdefghijklmnopqrstuvwxyz']
for drive in letters:
if win32file.GetDriveType(drive)==5:
self.drives.append(drive)
if not self.drive:
self.drive = self.drives[0]
def load(self, drive=''):
'''Closes cd drive door and waits until cd is readable.'''
drive = drive or self.drive
device = self.__getDeviceHandle(drive)
hdevice = win32file.CreateFile(device, GENERIC_READ,
FILE_SHARE_READ, None, OPEN_EXISTING, 0, 0)
win32file.DeviceIoControl(hdevice,2967564,"", 0, None)
win32file.CloseHandle(hdevice)
# Poll drive for loaded and give up after timeout period
i=0
while i < 20:
if self.__is_cd_inserted(drive) == 1:
return 1
else:
time.sleep(1)
i = i+1
return 0
def eject(self, drive=''):
'''Opens the cd drive door.'''
drive = drive or self.drive
device = self.__getDeviceHandle(drive)
hdevice = win32file.CreateFile(device, GENERIC_READ,
FILE_SHARE_READ, None, OPEN_EXISTING, 0, 0)
win32file.DeviceIoControl(hdevice,2967560,"", 0, None)
win32file.CloseHandle(hdevice)
def close(self, drive=''):
'''Closes the cd drive door.'''
drive = drive or self.drive
device = self.__getDeviceHandle(drive)
hdevice = win32file.CreateFile(device, GENERIC_READ,
FILE_SHARE_READ, None, OPEN_EXISTING, 0, 0)
win32file.DeviceIoControl(hdevice,2967564,"", 0, None)
win32file.CloseHandle(hdevice)
if __name__ == '__main__':
cd = Cdrom(timeout=5)
print "Running WinCDRom tests"; print
print "Listing drives:"; print
print cd.drives; print
print "Default drive: %s" % cd.drive; print
print "Opening drive door..."
cd.eject(); print
import time; time.sleep(2)
print "Closing cd drive door... (CD read attempt will time out at %s seconds.)" % cd.timeout
print
if cd.load() == 1:
print "Loaded cd successfully in drive %s" % cd.drive
print
else:
print "Unable to load cd."
print "If you have a slower drive try increasing the 'timeout' parameter."
print
print "WinCDRom Tests completed."
|
If you're writing an application which processes data on a set of cds then opening the drive door is an easy way for users to know the application has processed the cd or maybe found an error.
My company uses this module in an application to extract thumbnails and metadata from regularly-received satellite image cds for automatic inclusion in a Web searchable database. We have the application running on several peripheral computers and everyone in the office knows to swap in another cd for processing if they walk by and the drive door is open.
Any idea how to detect blank CDs or DVDs? I tried your module but I think it didn't detect a blank DVD. That's what I need. Do you have any advice?