当前位置:   article > 正文

C# 弹出USB外接硬盘(U盘)

c# 弹出u盘
原文: C# 弹出USB外接硬盘(U盘)

最近一个项目需要通过代码来弹出USB外接硬盘设备,经过google找到了下面这个类库:

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

不过这个类库只能在x86下使用,因此需要修改以下内容,使其适用于x64平台

修改DeviceClass为以下代码:

  1. public List<Device> Devices
  2. {
  3. get
  4. {
  5. if (_devices == null)
  6. {
  7. _devices = new List<Device>();
  8. int index = 0;
  9. while (true)
  10. {
  11. Native.SP_DEVICE_INTERFACE_DATA interfaceData = new Native.SP_DEVICE_INTERFACE_DATA();
  12. interfaceData.cbSize = (UInt32)Marshal.SizeOf(interfaceData);
  13. if (!Native.SetupDiEnumDeviceInterfaces(_deviceInfoSet, IntPtr.Zero, ref _classGuid, (UInt32)index, ref interfaceData))
  14. {
  15. int error = Marshal.GetLastWin32Error();
  16. if (error != Native.ERROR_NO_MORE_ITEMS)
  17. throw new Win32Exception(error);
  18. break;
  19. }
  20. Native.SP_DEVINFO_DATA devData = new Native.SP_DEVINFO_DATA();
  21. IntPtr p = Marshal.AllocHGlobal(Marshal.SizeOf(devData));
  22. Marshal.StructureToPtr(devData, p, true);
  23. UInt32 size = 0;
  24. if (!Native.SetupDiGetDeviceInterfaceDetail(_deviceInfoSet, ref interfaceData, IntPtr.Zero, 0, ref size, p))
  25. {
  26. int error = Marshal.GetLastWin32Error();
  27. if (error != Native.ERROR_INSUFFICIENT_BUFFER)
  28. throw new Win32Exception(error);
  29. }
  30. Native.SP_DEVICE_INTERFACE_DETAIL_DATA detailDataBuffer = new Native.SP_DEVICE_INTERFACE_DETAIL_DATA();
  31. if (IntPtr.Size == 8) // for 64 bit operating systems
  32. {
  33. detailDataBuffer.cbSize = 8;
  34. }
  35. else
  36. {
  37. detailDataBuffer.cbSize = 4 + Marshal.SystemDefaultCharSize; // for 32 bit systems
  38. }
  39. IntPtr pBuf = Marshal.AllocHGlobal(Marshal.SizeOf(detailDataBuffer));
  40. Marshal.StructureToPtr(detailDataBuffer, pBuf, true);
  41. if (!Native.SetupDiGetDeviceInterfaceDetail(_deviceInfoSet, ref interfaceData, pBuf, size, ref size, p))
  42. {
  43. int error = Marshal.GetLastWin32Error();
  44. if (error != Native.ERROR_INSUFFICIENT_BUFFER)
  45. throw new Win32Exception(error);
  46. }
  47. devData = (Native.SP_DEVINFO_DATA)Marshal.PtrToStructure(p, typeof(Native.SP_DEVINFO_DATA));
  48. Marshal.FreeHGlobal(p);
  49. detailDataBuffer = (Native.SP_DEVICE_INTERFACE_DETAIL_DATA)Marshal.PtrToStructure(pBuf, typeof(Native.SP_DEVICE_INTERFACE_DETAIL_DATA));
  50. Marshal.FreeHGlobal(pBuf);
  51. string devicePath = detailDataBuffer.DevicePath;
  52. Native.STORAGE_DEVICE_NUMBER storageDeviceNumber = GetDeviceNumber(devicePath);
  53. Device device = CreateDevice(this, devData, devicePath, storageDeviceNumber.DeviceNumber);
  54. _devices.Add(device);
  55. index++;
  56. }
  57. _devices.Sort();
  58. }
  59. return _devices;
  60. }
  61. }

  添加以下函数到DeviceClass.cs

  1. internal Native.STORAGE_DEVICE_NUMBER GetDeviceNumber(string devicePath)
  2. {
  3. IntPtr hFile = Native.CreateFile(devicePath.TrimEnd('\\'), 0, 0, IntPtr.Zero, Native.OPEN_EXISTING, 0, IntPtr.Zero);
  4. if (hFile.ToInt32() == Native.INVALID_HANDLE_VALUE)
  5. throw new Win32Exception(Marshal.GetLastWin32Error());
  6. int bytesReturned;
  7. Native.STORAGE_DEVICE_NUMBER storageDeviceNumber = new Native.STORAGE_DEVICE_NUMBER();
  8. int size = Marshal.SizeOf(storageDeviceNumber);
  9. IntPtr buffer = Marshal.AllocHGlobal(size);
  10. try
  11. {
  12. if (!Native.DeviceIoControl(hFile, Native.IOCTL_STORAGE_GET_DEVICE_NUMBER, IntPtr.Zero, 0, buffer, size, out bytesReturned, IntPtr.Zero))
  13. {
  14. // do nothing here on purpose
  15. }
  16. }
  17. finally
  18. {
  19. Native.CloseHandle(hFile);
  20. }
  21. if (bytesReturned > 0)
  22. {
  23. storageDeviceNumber = (Native.STORAGE_DEVICE_NUMBER)Marshal.PtrToStructure(buffer, typeof(Native.STORAGE_DEVICE_NUMBER));
  24. }
  25. Marshal.FreeHGlobal(buffer);
  26. return storageDeviceNumber;
  27. }

  Native.cs 添加:

  1. [StructLayout(LayoutKind.Sequential)]
  2. internal struct STORAGE_DEVICE_NUMBER
  3. {
  4. public int DeviceType;
  5. public int DeviceNumber;
  6. public int PartitionNumber;
  7. }
  8. internal const int IOCTL_STORAGE_GET_DEVICE_NUMBER = 0x2D1080;

  修改Volumn.cs

IntPtr hFile = Native.CreateFile(@"\\.\" + LogicalDrive, Native.GENERIC_READ, Native.FILE_SHARE_READ | Native.FILE_SHARE_WRITE, IntPtr.Zero, Native.OPEN_EXISTING, 0, IntPtr.Zero);

  为:

IntPtr hFile = Native.CreateFile(@"\\.\" + LogicalDrive, 0, Native.FILE_SHARE_READ | Native.FILE_SHARE_WRITE, IntPtr.Zero, Native.OPEN_EXISTING, 0, IntPtr.Zero);

  

修改Native.cs

  1. [StructLayout(LayoutKind.Sequential)]
  2. internal class SP_DEVINFO_DATA
  3. {
  4. internal int cbSize = Marshal.SizeOf(typeof(SP_DEVINFO_DATA));
  5. internal Guid classGuid = Guid.Empty; // temp
  6. internal int devInst = 0; // dumy
  7. internal int reserved = 0;
  8. }
  9. [StructLayout(LayoutKind.Sequential, Pack = 2)]
  10. internal struct SP_DEVICE_INTERFACE_DETAIL_DATA
  11. {
  12. internal int cbSize;
  13. internal short devicePath;
  14. }
  15. [StructLayout(LayoutKind.Sequential)]
  16. internal class SP_DEVICE_INTERFACE_DATA
  17. {
  18. internal int cbSize = Marshal.SizeOf(typeof(SP_DEVICE_INTERFACE_DATA));
  19. internal Guid interfaceClassGuid = Guid.Empty; // temp
  20. internal int flags = 0;
  21. internal int reserved = 0;
  22. }

  为:

  1. [StructLayout(LayoutKind.Sequential)]
  2. internal class SP_DEVINFO_DATA
  3. {
  4. internal int cbSize = Marshal.SizeOf(typeof(SP_DEVINFO_DATA));
  5. internal Guid classGuid = Guid.Empty; // temp
  6. internal int devInst = 0; // dumy
  7. internal IntPtr reserved = IntPtr.Zero;
  8. }
  9. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
  10. internal struct SP_DEVICE_INTERFACE_DETAIL_DATA
  11. {
  12. internal Int32 cbSize;
  13. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
  14. internal string DevicePath;
  15. }
  16. [StructLayout(LayoutKind.Sequential)]
  17. internal struct SP_DEVICE_INTERFACE_DATA
  18. {
  19. internal UInt32 cbSize;
  20. internal Guid interfaceClassGuid;
  21. internal UInt32 flags;
  22. internal UIntPtr reserved;
  23. }

  修改Volume.cs 

                                IntPtr extentPtr = new IntPtr(buffer.ToInt32() + Marshal.SizeOf(typeof(long)) + i * Marshal.SizeOf(typeof(Native.DISK_EXTENT)));

  为

                                IntPtr extentPtr = new IntPtr(buffer.ToInt64() + Marshal.SizeOf(typeof(long)) + i * Marshal.SizeOf(typeof(Native.DISK_EXTENT)));

  

源代码下载

posted on 2019-06-29 16:50 NET未来之路 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/lonelyxmas/p/11107083.html

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/846490
推荐阅读
相关标签
  

闽ICP备14008679号