A couple of people have reported a problem on Windows (7, I believe) when running a new version of our software. When trying to do things (not necessarily on first run) they get an error: ‘There is no disk in the drive. Please insert a disk into drive \Device\Harddisk5\DR5.’
Various blog posts around the net suggest this is a Windows error and not something with our app, but I’d be very interested if anyone has any ideas about it. We’re currently running RS 2012 r2.1, because we need to support Snow Leopard on a Mac.
Its probably not a windows error as such, but it is a nuisance.
It was more common with floppies.
If you simply check for the existence of a file, and the drive is not present, Windows throws up this message.
You might avoid it by iterating through available drives in Xojo before checking that a file exists on one of them?
I assume your software records paths to previous files in a prefs file somewhere?
this way you can disable such dialogs.
This is a continual problem for my apps, I get this complaint from users fairly frequently.
(Christian, I’m not sure SetErrorMode works all the time for things like this. It sure doesn’t work for bad shortcuts. I could be wrong though.)
On REAL/Xojo we usually parse the Volumes() array via VolumeCount. Generally (or absolutely?) this is scanning drive letters A: through Z: and exposes the ones that are “supposed to be” legit. But Windows Life is rarely that simple. (Warning: long explanation)
In a perfect world Windows only exposes drive letters that are fully “connectable” - the easiest example is in Win7, on a common system the D: drive is the CD/DVD Drive, and if there is no media inserted, the D: drive does not come up on the left of a Explorer window. (However it DOES show on the right, which is a characteristic of INTERNAL REMOVABLE DEVICES.) However you will note on XP the drive letter DOES show on the left. Still, when doing an API call like GetLogicalDrives() the D: drive does not appear in the list if no media is inserted.
During a operating systems lifetime, a user inserts a wide variety of removable devices: USB drives, and especially jump drives. Or you have the multi-card reader things. Each of them claim a drive letter on first insertion, so that when they are inserted again they’ll be consistent in the drive letter they get.
Over time this scheme gets confused, and for some reason Windows may put one of these orphaned things on it’s “list”. What this means is that in REAL/Xojo, such a drive will appears in the Volumes() array, which is the one we care about.
What to do about it? I’m not sure at this point, since I can’t replicate it myself and I haven’t gotten to the point where I had a cooperative user and I had the time to nail it. Possible solutions would be using the FileProcessing module in the WFS and check the VolumeName, if it’s blank, discard the drive letter. Or perhaps this all comes from a registry area. Or maybe there’s a MBS function. Try SetErrorMode as Christian suggested - if it works post back.
The whole problem is not knowing what spurs Windows to show that dialog. If your example, whatever drive letter you are checking is mapped to a Harddisk in place “DR5”. The problem in checking this is often that Windows error message is delayed, it’s not synchronous.
I’d like to know a solid solution to this as well; one where we could check Volumes(index) for reliability and wouldn’t wake up Windows to show that message.
For now I advise people to go into Computer Management and clear out the drive letters that may be orphaned. There was a command line utility that helps on this, but I can’t find it now.
Christian: I think that all that would do is hide the error dialog - the error would still occur, it just wouldn’t be reported.
Garth: I’ve tried a few things so far: reinstalling; rebuilding my installer; rebuilding the app and the installer… Bleh.
I have, however, found out how to reproduce it. I put in a USB flash drive, and did something in my application which wrote files to it. Those files are picture files; my application then stores the path, and when I load it, says ‘are these files available?’.
I then disconnected the USB drive by clicking Eject in Windows Explorer, but, crucially, did not unplug the USB drive from the USB slot. Then, reloading my app told me that I needed to insert a disk into the drive that it was in before.
More detective work shortly.
Interesting! Most of the time, people make the mistake of simply removing the jump drive with doing the Eject procedure. This is the other way around.
(The interesting thing also is that some jump drives need you to eject, some don’t.)
Check the WFS for a mechanism to turn this off and back on
To turn what off and on?
OK; further news.
I’ve made a sample project with a pushbutton in it. That has this:
dim f as FolderItem = new FolderItem( "C:\\Users\\Hamish\\Desktop\\Test\" )
MsgBox("Connected to desktop test folder ok")
f = new FolderItem( "E:\\Test\" )
MsgBox("Connected to USB stick folder ok")
in the Action event.
If I have a Test folder on my desktop and on the USB stick which comes up as drive E, then it works fine. If I eject the USB stick via Windows Explorer - i.e. go to the bottom right of the screen, and click ‘eject hardware’ but leave it in the USB slot, I get an unsupportedFormatException - not the same error as I said earlier. .
If I then unplug and replug the USB stick, but then eject it via right-clicking on the USB stick in diskmgmt.msc, then I get the ‘no disk in drive’ error.
Once the USB stick is ejected, via UI or physically, it will no longer appear in the list of drives you can get in XOJO via VolumeCount and Volume(x).Name, so if you check the drive letter exists there before using it in a folderitem you can avoid the error.
If you want to
undo the soft ejection ( that sounds a bit weired ) there should be a system call of some kind to do this, but I have not found out how after a quick search for suitable API calls.
As before, if I eject via Windows Explorer, the drive letter is removed from Volumes(x).Name.
If I eject via diskmgmt.msc, then the drive letter remains in Volumes(x).Name. So, checking the drive letter exists in there won’t help me…
[quote=148396:@Hamish Symington]Hi Norman,
To turn what off and on?
The error windows throws up
You can tell Windows to ignore errors (via set error mode)
[code] Declare Function SetErrorMode Lib “Kernel32” ( mode as Integer ) as Integer
// Turn off the error dialog Const SEM_FAILCRITICALERRORS = &h1 dim oldMode as Integer = SetErrorMode( SEM_FAILCRITICALERRORS )
Do your attempt to open the file, check the volume etc
This will no longer throw up a system dialog about the error
Reset the error mode back to normal
// Set the error mode back so that the application behaves as normal
Call SetErrorMode( oldMode )
Now check & see if you got the file etc you expected
With a bit of tweaking, that helps: if I check for folderitem.exists before setting the error mode back to normal then I can bomb out of the method before anything bad happens. I don’t understand why it’s happening on this version of our software, though, but not previous ones.
MAKE 100% sure you ALWAYS ALWAYS ALWAYS set the error mode back regardless of what you do or you’re app will stay in a state where other errors will not be reported
Did I mention to ALWAYS ALWAYS ALWAYS set the error mode back ?
Just out of curiosity - should you be setting the error mode back on afterwards?
Can’t seem to find any reference to that.
[quote=148459:@Norman Palardy]Did I mention to ALWAYS ALWAYS ALWAYS set the error mode back ?
Ah, you should have said …
Just following this up. By putting logging code between every single line of code in our app startup event - which is six or seven hundred lines - I found it was caused by the line
dim curlInstance as new ourCurl
where ourCurl is a subclass of CURLSMBS.
Christian’s provided us with a new version of that plugin with a call to reading some config files, and the problem’s gone away.