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

发布于 2024-09-27 15:20:42 字数 2246 浏览 1 评论 0 原文

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

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

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

  2. DeviceIoControlIOCTL_STORAGE_EJECT_MEDIA 控制代码。事件的顺序是:

This doesn't work at all. Each one of the `DeviceIoControl` calls fails with `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][11])

最后,我的开发计算机运行的是 Windows 7 x64,为了让第二种方法发挥作用,我尝试使用管理员权限运行我的应用程序,但这没有改变任何内容。

欢迎任何信息。甚至可能如何调用 shell“弹出”菜单项作为最后的手段。

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?

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. 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.

  2. using DeviceIoControl with the IOCTL_STORAGE_EJECT_MEDIA control code. The sequence of events is:

This doesn't work at all. Each one of the `DeviceIoControl` calls fails with `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][11])

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.

Any information is welcome. Even maybe how to invoke the shell "Eject" menu item as a last recourse.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

哑剧 2024-10-04 15:20:42

最终,我发现我在方法#2 中犯了错误。

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

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

最后,事实证明方法 #2 确实是 shell 上下文菜单的“Eject”功能所使用的方法。使用此方法,设备可以正确反应。

Eventually, I found out where I was making a mistake with approach #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.

The correct access mode is 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.

Finally, it turns out that method #2 is indeed the method used by the shell context menu's "Eject" function. Using this method the device reacts correctly.

黑色毁心梦 2024-10-04 15:20:42

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

我在这个SO答案中总结了我在项目中为此所做的步骤。

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. Forgive the late answer.

I've summarized the steps I've done for this on my project in this SO answer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文