我正在开发一种工具,可以弹出不符合某些内部政策的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}}