And the answer, as with many things, is in an article on C ++ / Win32 programming from decades ago .
In short, the problem is that Windows handles floppy disk errors somewhat differently than other disk errors. By default, no matter what you do, or think it does, Windows intercepts any errors created by the device and provides the user with a dialog box rather than letting the program handle it - the exact problem I had.
But, as it turned out, to solve this problem there is a call to the Win32 API, primarily SetErrorMode()
In a nutshell (and I detail the details here), we can use SetErrorMode() to make Windows stop being so paranoid, do something and let the program handle the situation and then reset the Windows error mode back to what it was before as if we had never been there. (There is probably a Keyser Soze joke here, but today I had the wrong amount of caffeine to find.)
Adapting the C ++ example code from a related article that looks something like this:
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
In C ++, when detecting errors, the correct path needs the GetLastError () function, which, fortunately, we do not need to worry about, because this is a Python issue. In our case, Python exception handling works fine. Thus, this is a function that I knocked together to check the drive letter for “ready”, all ready for copying, if anyone else needs it:
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
I have been using this quite a bit in the last few days, and it works great for both floppy disks and USB card readers.
A few notes: almost any function that requires access to the disk will work in the try block - everything that we look for in the exception due to the lack of media.
Also, although the python win32api package provides all the functions we need, it does not seem to have any flag constants. After a trip to the ancient bowels of MSDN, it turns out that SEM_FAILCRITICALERRORS is 1, which makes our life terribly easy.
I hope this helps someone else with a similar problem!