有谁知道在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文章最有趣的部分是引用如下:
- 使用GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE和OPEN_EXISTING调用CreateFile。 lpFileName参数应该是\。\ X:(其中X是实际的驱动器号)。 所有其他参数可以是零。
- 通过DeviceIoControl发出FSCTL_LOCK_VOLUME IOCTL来锁定音量。 如果有任何其他应用程序或系统正在使用该卷,则此IOCTL将失败。 一旦这个函数成功返回,应用程序就可以保证这个卷不被系统中的其他任何东西使用。
- 通过发出FSCTL_DISMOUNT_VOLUME IOCTL来卸除卷。 这会导致文件系统删除有关卷的所有知识,并丢弃有关卷的所有内部信息。
- 确保可以通过发布IOCTL_STORAGE_MEDIA_REMOVAL IOCTL来删除媒体。 在调用此IOCTL之前,将PREVENT_MEDIA_REMOVAL结构的PreventMediaRemoval成员设置为FALSE。 这会阻止设备阻止媒体的移除。
- 使用IOCTL_STORAGE_EJECT_MEDIA IOCTL弹出媒体。 如果设备不允许自动弹出,则可跳过IOCTL_STORAGE_EJECT_MEDIA,并指示用户移除媒体。
- 关闭第一步中获得的卷处理或发出FSCTL_UNLOCK_VOLUME IOCTL。 这允许驱动器被其他进程使用。
Andreas的回答,MSKB文章,以及我对API的API嗅探可以总结如下:
CreateFile
调用来打开卷。 (所有方法)。 DeviceIoControl
调用FSCTL_LOCK_VOLUME
。 (所有方法)。 DeviceIoControl
调用FSCTL_DISMOUNT_VOLUME
。 (只有Andreas和MSKB的方法,资源管理器不会因为某种原因调用这个方法,这个IOCTL好像是影响到驱动器是否在资源管理器中变灰的原因,我不确定为什么Explorer不调用这个方法)。 DeviceIoControl
调用IOCTL_STORAGE_MEDIA_REMOVAL
和PREVENT_MEDIA_REMOVAL
成员设置为FALSE
(MSKB和资源管理器的方法,这一步从安德烈亚斯的答案丢失)。 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。