【问题标题】:How to eject a USB removable disk/volume, similar to the "Eject" function in Windows Explorer?如何弹出 USB 可移动磁盘/卷,类似于 Windows 资源管理器中的“弹出”功能?
【发布时间】:2019-05-30 11:47:18
【问题描述】:

您知道 Windows 使用什么 API 或 API 调用序列来完成可移动卷的外壳上下文菜单中可用的“弹出”功能吗?

到目前为止,我已经尝试了两件事:

  1. 使用CM_Request_Device_Eject,枚举可移动磁盘(使用SetupDiXXX APIs),找到我感兴趣的磁盘,遍历设备管理器层次结构(使用CM_XXX APIs),最后调用@987654335 @ 在我感兴趣的设备的devInst 上。这有效,因为它确实从我的电脑中删除了卷并使设备“安全删除”(准备删除) 但它与 shell 上下文菜单中的“弹出”功能不同。我知道这是因为我尝试弹出的设备应该在弹出时执行某些操作,而当我使用 CM_Request_Device_Eject 执行弹出时,something 不会发生。 p>

  2. DeviceIoControlIOCTL_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 以及方法#1 成功弹出设备,使用CM_Request_Device_Eject

事实证明,方法#2 确实是 shell 上下文菜单的“弹出”功能使用的方法。使用这种方法,设备反应正确。

【问题讨论】:

  • 您的方法 #2 应该有效。在stackoverflow.com/questions/58670/windows-cdrom-eject 上,Andreas Magnusson 的回答对我有用,弹出了 U 盘。唯一的变化是更正了他的DeviceIoControl的拼写。
  • 另外,DeviceIoControl 成功返回 1。当您报告收到ERROR_INVALID_FUNCTION 时,是DeviceIoControl 的返回值,还是返回0 并且您正在调用GetLastError
  • 尝试关注How to Prepare a USB Drive for Safe Removal,它展示了如何使用CM_Request_Device_Eject功能。
  • 感谢@Oleg,但这种方法正是我所描述的解决方案#1,它的工作原理是弹出 USB,但当您单击外壳上下文菜单。这就是我需要的..
  • @Nate:当我使用我提到的任一控制代码调用 DeviceIoControl 时,它确实返回 0。然后,当我调用 GetLastError() 时,它返回 1,即 ERROR_INVALID_FUNCTION。

标签: winapi usb removable-storage


【解决方案1】:

最终,我发现了方法 #2 的错误之处。

事实证明,由于某种原因,在使用 CreateFile 打开卷的句柄时,我没有正确设置所需的访问权限。

正确的访问模式是GENERIC_READ | GENERIC_WRITE,而我通过了0。更正我的错误后,我能够使用 DeviceIoControl - IOCTL_STORAGE_EJECT_MEDIA 以及方法 #1 使用 CM_Request_Device_Eject 成功弹出设备。

最后,方法#2 确实是shell 上下文菜单的“弹出”功能使用的方法。使用这种方法,设备反应正确。

【讨论】:

    【解决方案2】:

    我在搜索“CM_Request_Device_Eject”时意外来到这里,发现它与我最近通过将类似的解决方案组合在一起完成的解决方案相似。原谅迟到的答案。

    我已经在我的项目in this SO answer 中总结了我为此完成的步骤。

    【讨论】:

    • 几年前我实际上已经回答了我自己的问题(请参阅问题中的编辑)。不过感谢您的参与。
    猜你喜欢
    • 2011-11-13
    • 2011-01-21
    • 2012-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-02
    相关资源
    最近更新 更多