简体   繁体   English

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

[英]How to eject a USB removable disk/volume, similar to the “Eject” function in Windows Explorer?

Do you know what is the API, or sequence of API calls that windows uses to accomplish the "Eject" function which is available on the shell context menu for removable volumes? 你知道什么是API,或者是用来完成“弹出”功能的API调用序列,它可以在可移动卷的shell上下文菜单中找到?

So far I've tried two things: 到目前为止,我尝试了两件事:

  1. using CM_Request_Device_Eject , I enumerate the removable disks (using the SetupDiXXX APIs ), find the one that I'm interested in, walk the device manager hierarchy (using CM_XXX APIs ) and finally call CM_Request_Device_Eject on the devInst of the device I'm interesed in. This works in the sense that it does remove the volumes from My Computer and makes the device "safe to remove" (ready to be removed) but it is not the same as the shell context menu "Eject" function. 使用CM_Request_Device_Eject ,我枚举可移动磁盘(使用SetupDiXXX API ),找到我感兴趣的那个,走设备管理器层次结构(使用CM_XXX API ),最后在我所devInst的设备的CM_Request_Device_Eject上调用CM_Request_Device_Eject这个作品在这个意义上,它并删除从我的电脑的体积并让设备“安全删除”(准备移除),但它是不一样的外壳上下文菜单中选择“弹出”功能。 The way I know this is because the device that I'm trying to eject is supposed to do something when it is ejected and that something is not happening when I do the eject using CM_Request_Device_Eject . 我知道这个的方式是因为我试图弹出的设备应该在弹出时执行某些操作,并且在使用CM_Request_Device_Eject进行弹出时不会发生某些事情。

  2. using DeviceIoControl with the IOCTL_STORAGE_EJECT_MEDIA control code. DeviceIoControlIOCTL_STORAGE_EJECT_MEDIA控制代码一起使用。 The sequence of events is: 事件的顺序是:

    This doesn't work at all. 这根本不起作用。 Each one of the DeviceIoControl calls fails with ERROR_IVALID_FUNCTION (0x00000001). 每个DeviceIoControl调用都以ERROR_IVALID_FUNCTION (0x00000001)失败。 I don't know why the calls fail. 我不知道为什么呼叫失败了。 I've verified that other calls to DeviceIoControl work fine for the same file handle (such as IOCTL_STORAGE_GET_DEVICE_NUMBER ) 我已经验证了对DeviceIoControl的其他调用对于相同的文件句柄(例如IOCTL_STORAGE_GET_DEVICE_NUMBER )工作正常

Finally, my development machine is running Windows 7 x64, and in order to get the second method to work I've tried running my application with Administrator privileges and that did not change anything. 最后,我的开发机器运行的是Windows 7 x64,为了让第二种方法起作用,我尝试使用管理员权限运行我的应用程序并且没有改变任何东西。

EDIT 编辑

Eventually, I found out where I was making a mistake with approach #2. 最后,我发现我在方法#2中犯了一个错误。 It turns out that for some reason I was not setting the desired access correctly when opening the handle to the volume using CreateFile . 事实证明,由于某种原因,我在使用CreateFile打开卷的句柄时没有正确设置所需的访问权限。 The correct access mode is GENERIC_READ | GENERIC_WRITE 正确的访问模式是GENERIC_READ | GENERIC_WRITE GENERIC_READ | GENERIC_WRITE and I was passing 0. After correcting my error I was able to successfully eject the device using DeviceIoControl - IOCTL_STORAGE_EJECT_MEDIA , as well as with method #1, using CM_Request_Device_Eject . GENERIC_READ | GENERIC_WRITE和我正在通过0.在纠正我的错误之后,我能够使用DeviceIoControl - IOCTL_STORAGE_EJECT_MEDIA以及使用CM_Request_Device_Eject方法#1成功弹出设备。

And it turns out that method #2 is indeed the method used by the shell context menu's "Eject" function. 事实证明,方法#2确实是shell上下文菜单的“弹出”功能所使用的方法。 Using this method the device reacts correctly. 使用此方法,设备可以正确反应。

Eventually, I found out where I was making a mistake with approach #2. 最后,我发现我在方法#2中犯了一个错误。

It turns out that for some reason I was not setting the desired access correctly when opening the handle to the volume using CreateFile. 事实证明,由于某种原因,我在使用CreateFile打开卷的句柄时没有正确设置所需的访问权限。

The correct access mode is GENERIC_READ | GENERIC_WRITE 正确的访问模式是GENERIC_READ | GENERIC_WRITE GENERIC_READ | GENERIC_WRITE and I was passing 0 . GENERIC_READ | GENERIC_WRITE和我正在通过0 After correcting my error I was able to successfully eject the device using DeviceIoControl - IOCTL_STORAGE_EJECT_MEDIA, as well as with method #1, using CM_Request_Device_Eject. 纠正错误后,我能够使用DeviceIoControl - IOCTL_STORAGE_EJECT_MEDIA以及方法#1使用CM_Request_Device_Eject成功弹出设备。

Finally, it turns out that method #2 is indeed the method used by the shell context menu's "Eject" function. 最后,事实证明方法#2确实是shell上下文菜单的“弹出”功能所使用的方法。 Using this method the device reacts correctly. 使用此方法,设备可以正确反应。

I came here accidentally while doing a search on "CM_Request_Device_Eject", and saw that it was similar to a solution I'd recently done by pulling together similar pieces of a solution. 我在搜索“CM_Request_Device_Eject”时意外地来到这里,看到它类似于我最近通过将类似的解决方案组合在一起所做的解决方案。 Forgive the late answer. 原谅迟到的答案。

I've summarized the steps I've done for this on my project in this SO answer . 在这个SO答案中 ,我总结了我在项目中为此做的步骤。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM