I have a WinForms application. It's written to disk. I run the application from disk and eject the disk from CD. Then I take the exception: there is no disk in the drive. please insert a disk into drive. How can I catch this exception and correctly close my application?
views:
97answers:
4You can modify your Program.cs like this:
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
try
{
Application.Run(new Form1());
}
catch (Exception ex)
{
// Display the exception to the end user.
}
finally
{
// Do your cleanup here.
}
}
This should catch all exceptions you do not catch otherwise in the application itself.
You should try to detect cd eject. Here is a working sample: publicjoe.f9.co.uk/csharp/snip/snip002.html
you can also check out this: http://stackoverflow.com/questions/1662794/detecting-eject-insert-of-removeable-media
This is a generic problem with any kind of program, not specific to a Winforms app. It is related to the way a process is created. Windows creates a so-called memory mapped file, it maps the bytes in the file into the address space of the process. It is a very efficient way to read data from a file, a disk read only occurs if the data is actually needed. When program execution jumps to a specific chunk of code, or the JIT compiler needs the IL for a method, a page fault is generated when the data hasn't been read yet. The operating system solves it by reading a chunk from the file. You only pay for code that actually runs.
Another major benefit is when the system is under pressure and too much RAM is needed to keep processes running. The memory manager chucks pages out of RAM to make room for the process that needs the CPU. These pages are normally written to the paging file. But that's unnecessary when they came from the EXE file. It can simply discard them and always get them back by re-reading the file.
You can probably see where this leads: loading pages from the EXE file can't work anymore when you popped out the disk. Windows notices this and puts up the dialog. This is a very low level error handling mechanism, you cannot trap it in the process itself. That couldn't work since that would require executing code in your program. Code that cannot be loaded from disk anymore.
You might be able to suppress the error by pinvoking SetErrorMode(). Not sure, never tried it. But that doesn't really solve anything, the next best thing that could happen is that Windows terminates the program with an obscure error. The only reasonable solution is either to let the user put the disk back, as requested by Windows, or to run an installer from your media so that a copy of the program is created on the hard drive.
Use EDITBIN /SWAPRUN to tell Windows that your executable resides on a removable device. It'll copy it to the swap file before running it.
This is what you'd usually do for (e.g.) an installer. I'm not sure if this works if you depend on other DLLs, but I assume it does.
For other resources, you'd want to copy them to a temporary location as soon as possible during initialization.
Alternatively, you can call SetErrorMode to disable the message box and handle the error correctly.