代码之家  ›  专栏  ›  技术社区  ›  Mike Dinescu

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

  •  13
  • Mike Dinescu  · 技术社区  · 14 年前

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

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

    1. 使用 CM_Request_Device_Eject ,我枚举可移动磁盘(使用 SetupDiXXX APIs ,找到我感兴趣的,浏览设备管理器层次结构(使用 CM_XXX APIs )最后打电话 CM_Request_Device_Eject devInst 我对这个设备感兴趣。这个 作品 从某种意义上说,它确实从我的计算机中删除了卷,并使设备“安全删除”(准备删除),但它与shell上下文菜单“弹出”功能不同。我知道这是因为我试图弹出的设备应该在弹出时执行某些操作 某物 当我使用 请求设备弹出 .

    2. 使用 DeviceIoControl IOCTL_STORAGE_EJECT_MEDIA 控制代码。事件顺序为:

      这根本不起作用。每一个 DeviceIoControl 呼叫失败 ERROR_IVALID_FUNCTION (0x000 000 01)。我不知道电话为什么会失败。我已经验证了对于同一个文件句柄(例如 IOCTL_STORAGE_GET_DEVICE_NUMBER )

    最后,我的开发机器正在运行Windows7x64,为了让第二个方法工作,我尝试使用管理员权限运行我的应用程序,但没有改变任何东西。

    编辑

    最后,我发现我在方法2上犯了一个错误。结果是,由于某种原因,我在打开音量手柄时没有正确设置所需的访问权限,使用 CreateFile . 正确的访问模式是 GENERIC_READ | GENERIC_WRITE 我刚好路过0。更正错误后,我可以使用 DeviceIoControl - IOCTL_STORAGE_EJECT_MEDIA 以及方法1,使用 请求设备弹出 .

    事实证明,方法2确实是shell上下文菜单的“eject”函数所使用的方法。使用这种方法,设备会正确反应。

    3 回复  |  直到 9 年前
        1
  •  2
  •   Mike Dinescu    9 年前

    最后,我发现我在方法2上犯了一个错误。

    结果发现,由于某种原因,在使用createfile打开卷的句柄时,我没有正确设置所需的访问权限。

    正确的访问模式是 GENERIC_READ | GENERIC_WRITE 我路过 0 . 更正错误后,我可以使用deviceiocontrol-ioctl_storage_eject_media以及方法1(使用cm_request_device_eject)成功弹出设备。

    最后,结果证明方法2确实是shell上下文菜单的“eject”函数所使用的方法。使用这种方法,设备会正确反应。

        2
  •  0
  •   Oleg    14 年前

    试着跟随 How to Prepare a USB Drive for Safe Removal 它显示了如何使用 CM_Request_Device_Eject 功能。

        3
  •  0
  •   Community T.Woody    7 年前

    我在搜索“cm请求设备弹出”时无意中来到这里,发现它与我最近通过将类似的解决方案片段拉在一起所做的解决方案类似。原谅迟来的回答。

    我总结了我在项目中为此所做的步骤 in this SO answer .