Windows CDROM弹出

时间:2008-09-12 10:53:53

标签: windows winapi

有没有人知道在Windows 2000或更高版本上以编程方式关闭CD托盘的方法? 打开CD托盘存在,但我似乎无法让它关闭,尤其是在W2k下。

我正在寻找一种方法,如果可能的话,从批处理文件中执行此操作,但API调用可以。

5 个答案:

答案 0 :(得分:12)

我更喜欢使用DeviceIOControl,因为它可以弹出任何类型的可移动驱动器(例如USB和闪存盘以及CD托盘)。使用DeviceIOControl正确弹出磁盘的Da codez是(只需添加正确的错误处理):

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;
}

答案 1 :(得分:6)

以下是使用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);
    }
}

答案 2 :(得分:3)

我注意到Andreas Magnusson的回答与Explorer的Eject按钮完全不同。具体来说,驱动程序在资源管理器中没有使用安德烈斯的代码显示为灰色,但是如果您使用了弹出命令。所以我做了一些调查。

我从Explorer(Windows 7 SP1 64位)运行Eject命令时运行了API Monitor。我还找到了一篇名为How To Ejecting Removable Media in Windows NT/Windows 2000/Windows XP的MSKB文章165721。 MSKB文章中最有趣的部分引用如下:

  
      
  1. 使用GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE和OPEN_EXISTING调用CreateFile。 lpFileName参数应为\。\ X :(其中X是实际的驱动器号)。所有其他参数可以为零。
  2.   
  3. 通过DeviceIoControl发出FSCTL_LOCK_VOLUME IOCTL来锁定卷。如果任何其他应用程序或系统正在使用该卷,则此IOCTL将失败。一旦此函数成功返回,应用程序将保证系统中的其他任何内容都不会使用该卷。
  4.   
  5. 通过发出FSCTL_DISMOUNT_VOLUME IOCTL来卸载卷。这会导致文件系统删除卷的所有知识,并丢弃它保留的有关卷的任何内部信息。
  6.   
  7. 确保通过发出IOCTL_STORAGE_MEDIA_REMOVAL IOCTL来删除媒体。在调用此IOCTL之前,将PREVENT_MEDIA_REMOVAL结构的PreventMediaRemoval成员设置为FALSE。这会阻止设备阻止移除介质。
  8.   
  9. 使用IOCTL_STORAGE_EJECT_MEDIA IOCTL弹出媒体。如果设备不允许自动弹出,则可以跳过IOCTL_STORAGE_EJECT_MEDIA,并指示用户删除媒体。
  10.   
  11. 关闭第一步中获得的音量控制柄或发出FSCTL_UNLOCK_VOLUME IOCTL。这允许驱动器被其他人使用   流程。
  12.   

Andreas的回答,MSKB文章以及我对Explorer的API嗅探可归纳如下:

  1. CreateFile打电话打开音量。 (所有方法)。
  2. DeviceIoControl使用FSCTL_LOCK_VOLUME进行了调用。 (所有方法)。
  3. DeviceIoControl使用FSCTL_DISMOUNT_VOLUME进行了调用。 (仅限Andreas和MSKB方法。资源管理器由于某种原因不会调用它。这个IOCTL似乎影响驱动程序是否在资源管理器中显示为灰色。我不确定为什么资源管理器不会调用它。)
  4. DeviceIoControl调用了IOCTL_STORAGE_MEDIA_REMOVALPREVENT_MEDIA_REMOVAL成员设置为FALSE(MSKB和资源管理器方法。安德烈亚斯的回答中缺少此步骤。)
  5. DeviceIoControl使用IOCTL_STORAGE_EJECT_MEDIA(Andreas和MSKB文章)或IOCTL_DISK_EJECT_MEDIA(资源管理器)调用;请注意此IOCTL已过时并替换为STORAGE IOCTL。不确定为何Explorer仍使用旧版本一个)。
  6. 总而言之,我决定遵循MSKB文章中概述的程序,因为它似乎是最全面和最完整的程序,并附有MSKB文章。

答案 3 :(得分:1)

Nircmd是一个非常方便的免费软件命令行实用程序,具有各种选项,包括打开和关闭CD托盘。

答案 4 :(得分:1)

要关闭驱动器托盘,请执行here所述操作,但不要将DeviceIoControl与IOCTL_STORAGE_EJECT_MEDIA一起使用,而是需要使用IOCTL_STORAGE_LOAD_MEDIA调用DeviceIoControl。