Introduction
This tip shows you how to open and close the CD or DVD drive tray programmatically.
Background
There are tools that allow you to do this (like NirSoft's NirCmd), but I wrote this out of curiosity, to find out how it is done. The close command is particularly useful, since Windows doesn't provide that feature.
Disclaimer
This is merely one method of controlling the drive tray, and may not work in all instances. I am sure there are other methods too.
The code provided merely illustrates the method, and is by no means production-ready.
Code
We use the Media Control Interface (MCI) function mciSendCommand
to open and close the tray. Specifying MCI_SET_DOOR_OPEN
ejects the tray, and MCI_SET_DOOR_CLOSED
retracts it. Example:
mciSendCommand(deviceId, MCI_SET, MCI_SET_DOOR_CLOSED, NULL);
Refer to the MSDN documentation for details of mciSendCommand
and its arguments.
Demo Program
The following demo opens and closes the CD drive door. The drive letter is hardcoded for simplicity.
#include <tchar.h>
#include <windows.h>
#include <mmsystem.h> // for MCI functions
#pragma comment(lib, "winmm")
void ControlCdTray(TCHAR drive, DWORD command)
{
MCIERROR mciError = 0;
DWORD mciFlags = MCI_WAIT | MCI_OPEN_SHAREABLE |
MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID | MCI_OPEN_ELEMENT;
TCHAR elementName[] = { drive };
MCI_OPEN_PARMS mciOpenParms = { 0 };
mciOpenParms.lpstrDeviceType = (LPCTSTR)MCI_DEVTYPE_CD_AUDIO;
mciOpenParms.lpstrElementName = elementName;
mciError = mciSendCommand(0,
MCI_OPEN, mciFlags, (DWORD_PTR)&mciOpenParms);
MCI_SET_PARMS mciSetParms = { 0 };
mciFlags = MCI_WAIT | command; mciError = mciSendCommand(mciOpenParms.wDeviceID,
MCI_SET, mciFlags, (DWORD_PTR)&mciSetParms);
mciFlags = MCI_WAIT;
MCI_GENERIC_PARMS mciGenericParms = { 0 };
mciError = mciSendCommand(mciOpenParms.wDeviceID,
MCI_CLOSE, mciFlags, (DWORD_PTR)&mciGenericParms);
}
void EjectCdTray(TCHAR drive)
{
ControlCdTray(drive, MCI_SET_DOOR_OPEN);
}
void CloseCdTray(TCHAR drive)
{
ControlCdTray(drive, MCI_SET_DOOR_CLOSED);
}
int _tmain(int argc, _TCHAR* argv[])
{
EjectCdTray(TEXT('E')); CloseCdTray(TEXT('E'));
return 0;
}
Conclusion
That's it. Let me know if you discover any bugs.