Windows CDROMpopup

有谁知道在Windows 2000或更高版本上以编程方式closuresCD托盘的方法? 打开CD托盘存在,但我似乎无法使其closures,尤其是在W2K下。

如果可能的话,我特别想从batch file中find一个方法,但是API调用是可以的。

这是一个使用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); } } 

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

 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的回答与Explorer的Eject按钮没有完全一样的功能。 具体来说,使用Andreas代码的驱动器在资源管理器中不会变灰,但是如果使用了Eject命令。 所以我做了一些调查。

我从资源管理器(Windows 7 SP1 64位)运行弹出命令时运行了API监视器。 我还发现一个很好的MSKB文章165721标题为如何在Windows NT / Windows 2000 / Windows XP中弹出可移动媒体 。 MSKB文章最有趣的部分是引用如下:

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

Andreas的回答,MSKB文章,以及我对API的API嗅探可以总结如下:

  1. CreateFile调用来打开卷。 (所有方法)。
  2. DeviceIoControl调用FSCTL_LOCK_VOLUME (所有方法)。
  3. DeviceIoControl调用FSCTL_DISMOUNT_VOLUME (只有Andreas和MSKB的方法,资源管理器不会因为某种原因调用这个方法,这个IOCTL好像是影响到驱动器是否在资源管理器中变灰的原因,我不确定为什么Explorer不调用这个方法)。
  4. DeviceIoControl调用IOCTL_STORAGE_MEDIA_REMOVALPREVENT_MEDIA_REMOVAL成员设置为FALSE (MSKB和资源管理器的方法,这一步从安德烈亚斯的答案丢失)。
  5. DeviceIoControl使用IOCTL_STORAGE_EJECT_MEDIA (Andreas和MSKB文章)或IOCTL_DISK_EJECT_MEDIA (Explorer;请注意,这个IOCTL已经过时,并替换为STORAGE IOCTL,不知道为什么Explorer仍然使用旧的)。

最后,我决定遵循MSKB文章中列出的步骤,因为它似乎是最彻底和最完整的过程,并备有MSKB文章。

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

要关闭驱动器托盘,请按照此处所述进行操作,但不要使用带有IOCTL_STORAGE_EJECT_MEDIA的DeviceIoControl,而需要使用IOCTL_STORAGE_LOAD_MEDIA调用DeviceIoControl。