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

Winapi 如何弹出USB可移动磁盘/卷,类似于;“弹出”;Windows资源管理器中的函数?,winapi,usb,removable-storage,Winapi,Usb,Removable Storage,您知道windows用于完成“弹出”功能的API或API调用序列是什么吗?可移动卷的shell上下文菜单中提供了该函数 到目前为止,我尝试了两件事: 使用,我枚举可移动磁盘(使用),找到我感兴趣的磁盘,遍历设备管理器层次结构(使用),最后在我感兴趣的设备的devInst上调用CM\u Request\u device\u Eject。这样做的意义是,它确实可以从我的计算机中删除卷,并使设备“安全地删除”(准备删除),但它与shell上下文菜单“弹出”功能不同。我之所以知道这一点,是因为我试图弹出

您知道windows用于完成“弹出”功能的API或API调用序列是什么吗?可移动卷的shell上下文菜单中提供了该函数

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

  • 使用,我枚举可移动磁盘(使用),找到我感兴趣的磁盘,遍历设备管理器层次结构(使用),最后在我感兴趣的设备的
    devInst
    上调用
    CM\u Request\u device\u Eject
    。这样做的意义是,它确实可以从我的计算机中删除卷,并使设备“安全地删除”(准备删除),但它与shell上下文菜单“弹出”功能不同。我之所以知道这一点,是因为我试图弹出的设备应该在弹出时执行某些操作,而当我使用
    CM\u Request\u device\u eject
    进行弹出时,某些操作没有发生

  • 与控制代码一起使用。事件的顺序是:

    • 按照文档中的建议获取我感兴趣的卷的句柄
    • 尝试使用锁定卷
    • 尝试使用以下工具将其卸下:
    • 使用禁用“防止删除存储介质”
    • 最后执行该函数
    这根本不起作用。每个
    DeviceIoControl
    调用都会失败,并出现
    ERROR\u IVALID\u函数(0x00000001)。我不知道为什么电话打不通。我已经验证了对DeviceIoControl的其他调用对于相同的文件句柄(例如)工作正常

  • 最后,我的开发机器运行的是Windows7x64,为了让第二种方法发挥作用,我尝试使用管理员权限运行我的应用程序,但这并没有改变任何事情

    编辑


    最终,我发现我在方法2上犯了一个错误。事实证明,由于某种原因,在使用
    CreateFile
    打开卷句柄时,我没有正确设置所需的访问权限。正确的访问模式是
    GENERIC_READ | GENERIC_WRITE
    ,我通过了0。更正错误后,我能够使用
    DeviceIoControl-IOCTL\u STORAGE\u eject\u MEDIA
    以及方法1,使用
    CM\u Request\u device\u eject
    成功弹出设备


    结果证明,方法#2确实是shell上下文菜单的“弹出”函数所使用的方法。使用此方法,设备反应正常。

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


    我总结了我在项目中为此所做的步骤。

    最终,我发现我在方法2上犯了错误

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

    正确的访问模式是
    GENERIC\u READ | GENERIC\u WRITE
    ,我通过了
    0
    。更正错误后,我能够使用DeviceIoControl-IOCTL_STORAGE_eject_介质以及使用CM_Request_device_eject方法1成功弹出设备


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

    您的方法2应该有效。安德烈亚斯·马格努森(Andreas Magnusson)的回答对我有效,他弹出了一个U盘。唯一的改变是纠正了他对
    DeviceIoControl
    的拼写。此外,
    DeviceIoControl
    成功返回
    1
    。当您报告获取
    ERROR\u INVALID\u FUNCTION
    时,这是
    DeviceIoControl
    的返回值,还是返回
    0
    ,并且您正在调用
    GetLastError
    ?请尝试按照说明如何使用该函数的步骤进行操作。谢谢@Oleg,但这种方法正是我所描述的解决方案#1,其工作原理是它弹出USB,但当您单击Shell上下文菜单中的“弹出”时,它不会执行windows所做的任何其他操作。这就是我需要的。@Nate:DeviceIoControl在我使用我提到的任何一个控制代码调用它时都返回0。然后当我调用GetLastError()时,它返回1,这是ERROR\u INVALID\u函数。不过谢谢你的来电。