4

Is there any way to do so? I know its possible to programmatically eject/retract the cd drive SOMEHOW, cause Roxio does that when it prompts me to insert a disk.

Either c# or vb.net is preferable, but c and c++ are okay too as a last resort.

I am nearly positive there is some way to do this, I just don't know the methods to call.

I do understand this is a somewhat unusual request, as Google yielded absolutely nothing when I searched for the methods...

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
Cyclone
  • 17,939
  • 45
  • 124
  • 193

2 Answers2

11

Here's an alternative solution to the accepted one, converted from a VB.NET sample:

using System;
using System.IO;
using System.Runtime.InteropServices;

class Test
{
    const int OPEN_EXISTING = 3;
    const uint GENERIC_READ = 0x80000000;
    const uint GENERIC_WRITE = 0x40000000;
    const uint IOCTL_STORAGE_EJECT_MEDIA = 2967560;

    [DllImport("kernel32")]
    private static extern IntPtr CreateFile
        (string filename, uint desiredAccess, 
         uint shareMode, IntPtr securityAttributes,
         int creationDisposition, int flagsAndAttributes, 
         IntPtr templateFile);

    [DllImport("kernel32")]
    private static extern int DeviceIoControl
        (IntPtr deviceHandle, uint ioControlCode, 
         IntPtr inBuffer, int inBufferSize,
         IntPtr outBuffer, int outBufferSize, 
         ref int bytesReturned, IntPtr overlapped);

    [DllImport("kernel32")]
    private static extern int CloseHandle(IntPtr handle);

    static void EjectMedia(char driveLetter)
    {
        string path = "\\\\.\\" + driveLetter + ":";
        IntPtr handle = CreateFile(path, GENERIC_READ | GENERIC_WRITE, 0, 
                                   IntPtr.Zero, OPEN_EXISTING, 0,
                                   IntPtr.Zero);
        if ((long) handle == -1)
        {
            throw new IOException("Unable to open drive " + driveLetter);
        }
        int dummy = 0;
        DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, IntPtr.Zero, 0, 
                        IntPtr.Zero, 0, ref dummy, IntPtr.Zero);
        CloseHandle(handle);
    }

    static void Main()
    {
        EjectMedia('f');
    }
}
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • That's the best idea. It assumes things on the hardware. What if your hardware has special driver for eject? You'd better use the Shell eject function, which will make your code shorter and more general. – Elazar Leibovich Jun 16 '10 at 15:07
  • 1
    I found this works more reliably than the accepted answer. However according to the docs (https://msdn.microsoft.com/en-us/library/windows/desktop/aa363216.aspx), "You should specify the FILE_SHARE_READ and FILE_SHARE_WRITE access flags when calling CreateFile to open a handle to a device driver." I had to add this before it worked for me. I edited your answer to include these. – stusherwin Apr 13 '15 at 13:26
  • I agree about FILE_SHARE_READ and FILE_SHARE_WRITE. If it's not specified, any other process that try to access the drive at the same time cause the CreateFile to fail. – Filimindji Feb 23 '16 at 09:17
  • Here is a "patch" with the share flags: const uint FILE_SHARE_READ = 0x00000001; const uint FILE_SHARE_WRITE = 0x00000002; (...) IntPtr handle = CreateFile(path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, (...) – Jakub Berezanski Jun 14 '21 at 20:50
10
using System.Runtime.InteropServices;

[DllImport("winmm.dll")]
static extern Int32 mciSendString(String command, StringBuilder buffer, Int32 bufferSize, IntPtr hwndCallback);

// To open the door
mciSendString("set CDAudio door open", null, 0, IntPtr.Zero);

// To close the door
mciSendString("set CDAudio door closed", null, 0, IntPtr.Zero);

http://www.geekpedia.com/tutorial174_Opening-and-closing-the-CD-tray-in-.NET.html

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
  • Work sometimes. Not every times. The alternative solution is more reliable for me. But make sure to read the comment and to use FILE_SHARE_READ and FILE_SHARE_WRITE. – Filimindji Feb 23 '16 at 09:18