C# - 使用DeviceIoControl命令弹出USB驱动器 - 在某些情况下失败

时间:2017-01-10 10:35:58

标签: .net usb

我正在开发一种工具,可以弹出不符合某些内部政策的USB驱动器。我检查了很多方法来进行弹射

https://www.codeproject.com/Articles/13530/Eject-USB-disks-using-C

Safely remove a USB drive using the Win32 API?

但所有这些都不适用于我测试的所有USB。经过大量的研究和测试,我发现StackOverflow的代码似乎运行正常(最后的回复) Eject USB device via C#

但是最近我拿到了一个没有弹出的USB记忆棒。

令人惊讶的是我调试了执行,我意识到如果我在DeviceIOControl行中放置一个断点并且我只是等待几秒钟而只是恢复执行,那么弹出就完美了。如果我删除了断点并插入相同的USB,则弹出失败。在这两种情况下,DeviceIOControl的返回码始终为TRUE。 所以,最后,我测试只是在DeviceIOControl命令之后添加 [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] private static extern IntPtr CreateFile( string lpFileName, uint dwDesiredAccess, uint dwShareMode, IntPtr SecurityAttributes, uint dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile ); [DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)] private static extern bool DeviceIoControl( IntPtr hDevice, uint dwIoControlCode, IntPtr lpInBuffer, uint nInBufferSize, IntPtr lpOutBuffer, uint nOutBufferSize, out uint lpBytesReturned, IntPtr lpOverlapped ); [DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)] private static extern bool DeviceIoControl( IntPtr hDevice, uint dwIoControlCode, byte[] lpInBuffer, uint nInBufferSize, IntPtr lpOutBuffer, uint nOutBufferSize, out uint lpBytesReturned, IntPtr lpOverlapped ); [DllImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool CloseHandle(IntPtr hObject); private IntPtr handle = IntPtr.Zero; const uint GENERIC_READ = 0x80000000; const uint GENERIC_WRITE = 0x40000000; const int FILE_SHARE_READ = 0x1; const int FILE_SHARE_WRITE = 0x2; const int FSCTL_LOCK_VOLUME = 0x00090018; const int FSCTL_DISMOUNT_VOLUME = 0x00090020; const int IOCTL_STORAGE_EJECT_MEDIA = 0x2D4808; const int IOCTL_STORAGE_MEDIA_REMOVAL = 0x002D4804; public void EjectDrive(string driveLetter) { string path = @"\\.\" + driveLetter + @":"; IntPtr handle = CreateFile(path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, 0x3, 0, IntPtr.Zero); if ((long)handle == -1) { // MessageBox.Show("Unable to open drive " + driveLetter); return; } uint dummy = 0; bool returnvalue = DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, IntPtr.Zero, 0, IntPtr.Zero, 0, out dummy, IntPtr.Zero); Thread.Sleep(3000); CloseHandle(handle); // MessageBox.Show("OK to remove drive."); } 并且USB被弹出。

任何人都可以解释可能发生的事情吗?

我还检测到有几个类似的解决方案,其中不同的参数传递给DeviceIOControl函数。任何人都可以向我解释我应该使用哪一个以及为什么?

非常感谢。

我的代码:

{{1}}

0 个答案:

没有答案