如何弹出USB可移动磁盘/卷,类似于“Eject” Windows资源管理器中的功能

你知道什么是API,或者是用来完成“弹出”功能的API调用序列,它可以在可移动卷的shell上下文菜单中找到? 到目前为止,我尝试了两件事: 使用CM_Request_Device_Eject,我枚举可移动磁盘(使用SetupDiXXX API),找到我感兴趣的那个,走设备管理器层次结构(使用CM_XXX API),最后在我所介入的设备的
devInst
上调用
CM_Request_Device_Eject
这是因为它确实从“我的电脑”中删除了卷并使设备“可以安全删除”(准备删除),但它与shell上下文菜单“弹出”功能不同。我知道这个的方式是因为我试图弹出的设备应该在弹出时执行某些操作,并且当我使用
CM_Request_Device_Eject
进行弹出时不会发生某些事情。 将DeviceIoControl与IOCTL_STORAGE_EJECT_MEDIA控制代码一起使用。事件的顺序是: 根据文档中的建议,使用CreateFile获取我感兴趣的卷的句柄 尝试使用FSCTL_LOCK_VOLUME锁定音量 尝试使用FSCTL_DISMOUNT_VOLUME卸载它 使用IOCTL_STORAGE_MEDIA_REMOVAL禁用阻止存储介质删除 最后执行IOCTL_STORAGE_EJECT_MEDIA函数。 这根本不起作用。每个
DeviceIoControl
调用都以
ERROR_IVALID_FUNCTION
(0x00000001)失败。我不知道为什么呼叫失败了。我已经验证了对DeviceIoControl的其他调用对于相同的文件句柄(例如IOCTL_STORAGE_GET_DEVICE_NUMBER)工作正常 最后,我的开发机器运行的是Windows 7 x64,为了让第二种方法起作用,我尝试使用管理员权限运行我的应用程序并且没有改变任何东西。 编辑 最后,我发现我在方法#2中犯了一个错误。事实证明,由于某些原因,当使用
CreateFile
打开音量控制柄时,我没有正确设置所需的访问权限。正确的访问模式是
GENERIC_READ | GENERIC_WRITE
,我正在通过0.纠正我的错误后,我能够使用
DeviceIoControl - IOCTL_STORAGE_EJECT_MEDIA
成功弹出设备,以及使用
CM_Request_Device_Eject
成功弹出方法#1。 事实证明,方法#2确实是shell上下文菜单的“弹出”功能所使用的方法。使用此方法,设备可以正确反应。     
已邀请:
最后,我发现我在方法#2中犯了一个错误。 事实证明,由于某种原因,我在使用CreateFile打开卷的句柄时没有正确设置所需的访问权限。 正确的访问模式是
GENERIC_READ | GENERIC_WRITE
,我正在通过
0
。纠正错误后,我能够使用DeviceIoControl - IOCTL_STORAGE_EJECT_MEDIA以及方法#1使用CM_Request_Device_Eject成功弹出设备。 最后,事实证明方法#2确实是shell上下文菜单的“弹出”功能所使用的方法。使用此方法,设备可以正确反应。     
尝试按照如何准备安全删除的USB驱动器来说明如何使用CM_Request_Device_Eject功能。     
我在搜索“CM_Request_Device_Eject”时意外地来到这里,看到它类似于我最近通过将类似的解决方案组合在一起所做的解决方案。原谅迟到的答案。 在这个SO答案中,我总结了我在项目中为此做的步骤。     

要回复问题请先登录注册