tags:

views:

1062

answers:

5

Does anyone know a method to programmatically close the CD tray on Windows 2000 or higher? Open CD tray exists, but I can't seem to make it close especially under W2k.

I am especially looking for a method to do this from a batch file, if possible, but API calls would be OK.

A: 

Nircmd is a very handy freeware command line utility with various options, including opening and closing the CD tray.

Dave Webb
FYI: www.nirsoft.net is blocked by my company and I found this about the program.http://spywarefiles.prevx.com/RRIDCH001610050/NIRCMD.EXE.html
kenny
Reading that description doesn't worry me - it seems like they're worried Nircmd because it's a utility that can do things. Neither Sophos, Avast nor ESET block nircmd on any of my systems, at home or at work. On the other hand I've never heard of Prevx.
Dave Webb
A: 

I believe this article on code project solves your needs.

VanOrman
+1  A: 

Here is an easy way using the Win32 API:


[DllImport("winmm.dll", EntryPoint = "mciSendStringA", CharSet = CharSet.Ansi)]
        protected static extern int mciSendString(string lpstrCommand,StringBuilder lpstrReturnString,int uReturnLength,IntPtr hwndCallback);

 public void OpenCloseCD(bool Open)
 {
    if (Open)
    {
        mciSendString("set cdaudio door open", null, 0, IntPtr.Zero);
    }
    else
    {
        mciSendString("set cdaudio door closed", null, 0, IntPtr.Zero);
    }
}

DaveK
How does this work on a system with multiple drives? I don't see anything to specify a drive.
OwenP
A: 

mciSendString

MCIERROR mciSendString(
  LPCTSTR lpszCommand,  
  LPTSTR lpszReturnString,  
  UINT cchReturn,       
  HANDLE hwndCallback
Prakash
+5  A: 

I kind of like to use DeviceIOControl as it gives me the possibility to eject any kind of removable drive (such as USB and flash-disks as well as CD trays). Da codez to properly eject a disk using DeviceIOControl is (just add proper error-handling):

bool ejectDisk(TCHAR driveLetter)
{
  TCHAR tmp[10];
  _stprintf(tmp, _T("\\\\.\\%c:"), driveLetter);
  HANDLE handle = ::CreateFile(tmp, GENERIC_READ, FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
  DWORD bytes = 0;
  DeviceIoControl(handle, FSCTL_LOCK_VOLUME, 0, 0, 0, 0, &bytes, 0);
  DeviceIoControl(handle, FSCTL_DISMOUNT_VOLUME, 0, 0, 0, 0, &bytes, 0);
  DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, 0, 0, 0, 0, &bytes, 0);
  CloseHandle(handle);
  return true;
}
Andreas Magnusson
This works great, but note the correct spelling `DeviceIoControl` (no capital `O`).
Nate
@Nate: Thanks, fixed it!
Andreas Magnusson