C# 弹出USB外接硬盘(U盘) - Chris Cheung - 博客园

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

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

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

修改DeviceClass为以下代码:

?

public List<Device> Devices

{

get

{

if (_devices == null`)`

{

_devices = new List<Device>();

int index = 0;

while (`true`)

{

Native.SP_DEVICE_INTERFACE_DATA interfaceData = new Native.SP_DEVICE_INTERFACE_DATA();

interfaceData.cbSize = (UInt32)Marshal.SizeOf(interfaceData);

if (!Native.SetupDiEnumDeviceInterfaces(_deviceInfoSet, IntPtr.Zero, ref _classGuid, (UInt32)index, ref interfaceData))

{

int error = Marshal.GetLastWin32Error();

if (error != Native.ERROR_NO_MORE_ITEMS)

throw new Win32Exception(error);

break`;`

}

Native.SP_DEVINFO_DATA devData = new Native.SP_DEVINFO_DATA();

IntPtr p = Marshal.AllocHGlobal(Marshal.SizeOf(devData));

Marshal.StructureToPtr(devData, p, true`);`

UInt32 size = 0;

if (!Native.SetupDiGetDeviceInterfaceDetail(_deviceInfoSet, ref interfaceData, IntPtr.Zero, 0, ref size, p))

{

int error = Marshal.GetLastWin32Error();

if (error != Native.ERROR_INSUFFICIENT_BUFFER)

throw new Win32Exception(error);

}

Native.SP_DEVICE_INTERFACE_DETAIL_DATA detailDataBuffer = new Native.SP_DEVICE_INTERFACE_DETAIL_DATA();

if (IntPtr.Size == 8) // for 64 bit operating systems

{

detailDataBuffer.cbSize = 8;

}

else

{

detailDataBuffer.cbSize = 4 + Marshal.SystemDefaultCharSize; // for 32 bit systems

}

IntPtr pBuf = Marshal.AllocHGlobal(Marshal.SizeOf(detailDataBuffer));

Marshal.StructureToPtr(detailDataBuffer, pBuf, true`);`

if (!Native.SetupDiGetDeviceInterfaceDetail(_deviceInfoSet, ref interfaceData, pBuf, size, ref size, p))

{

int error = Marshal.GetLastWin32Error();

if (error != Native.ERROR_INSUFFICIENT_BUFFER)

throw new Win32Exception(error);

}

devData = (Native.SP_DEVINFO_DATA)Marshal.PtrToStructure(p, typeof`(Native.SP_DEVINFO_DATA));`

Marshal.FreeHGlobal(p);

detailDataBuffer = (Native.SP_DEVICE_INTERFACE_DETAIL_DATA)Marshal.PtrToStructure(pBuf, typeof`(Native.SP_DEVICE_INTERFACE_DETAIL_DATA));`

Marshal.FreeHGlobal(pBuf);

string devicePath = detailDataBuffer.DevicePath;

Native.STORAGE_DEVICE_NUMBER storageDeviceNumber = GetDeviceNumber(devicePath);

Device device = CreateDevice(`this`, devData, devicePath, storageDeviceNumber.DeviceNumber);

_devices.Add(device);

index++;

}

_devices.Sort();

}

return _devices;

}

}

  添加以下函数到DeviceClass.cs

?

internal Native.STORAGE_DEVICE_NUMBER GetDeviceNumber(`string devicePath)`

{

IntPtr hFile = Native.CreateFile(devicePath.TrimEnd(`'\'`), 0, 0, IntPtr.Zero, Native.OPEN_EXISTING, 0, IntPtr.Zero);

if (hFile.ToInt32() == Native.INVALID_HANDLE_VALUE)

throw new Win32Exception(Marshal.GetLastWin32Error());

int bytesReturned;

Native.STORAGE_DEVICE_NUMBER storageDeviceNumber = new Native.STORAGE_DEVICE_NUMBER();

int size = Marshal.SizeOf(storageDeviceNumber);

IntPtr buffer = Marshal.AllocHGlobal(size);

try

{

if (!Native.DeviceIoControl(hFile, Native.IOCTL_STORAGE_GET_DEVICE_NUMBER, IntPtr.Zero, 0, buffer, size, out bytesReturned, IntPtr.Zero))

{

// do nothing here on purpose

}

}

finally

{

Native.CloseHandle(hFile);

}

if (bytesReturned > 0)

{

storageDeviceNumber = (Native.STORAGE_DEVICE_NUMBER)Marshal.PtrToStructure(buffer, typeof`(Native.STORAGE_DEVICE_NUMBER));`

}

Marshal.FreeHGlobal(buffer);

return storageDeviceNumber;

}

  Native.cs 添加:

?

[StructLayout(LayoutKind.Sequential)]

internal struct STORAGE_DEVICE_NUMBER

{

public int DeviceType;

public int DeviceNumber;

public int PartitionNumber;

}

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

?

[StructLayout(LayoutKind.Sequential)]

internal class SP_DEVINFO_DATA

{

internal int cbSize = Marshal.SizeOf(`typeof`(SP_DEVINFO_DATA));

internal Guid classGuid = Guid.Empty; // temp

internal int devInst = 0; // dumy

internal int reserved = 0;

}

[StructLayout(LayoutKind.Sequential, Pack = 2)]

internal struct SP_DEVICE_INTERFACE_DETAIL_DATA

{

internal int cbSize;

internal short devicePath;

}

[StructLayout(LayoutKind.Sequential)]

internal class SP_DEVICE_INTERFACE_DATA

{

internal int cbSize = Marshal.SizeOf(`typeof`(SP_DEVICE_INTERFACE_DATA));

internal Guid interfaceClassGuid = Guid.Empty; // temp

internal int flags = 0;

internal int reserved = 0;

}

  为:

?

[StructLayout(LayoutKind.Sequential)]

internal class SP_DEVINFO_DATA

{

internal int cbSize = Marshal.SizeOf(`typeof`(SP_DEVINFO_DATA));

internal Guid classGuid = Guid.Empty; // temp

internal int devInst = 0; // dumy

internal IntPtr reserved = IntPtr.Zero;

}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]

internal struct SP_DEVICE_INTERFACE_DETAIL_DATA

{

internal Int32 cbSize;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]

internal string DevicePath;

}

[StructLayout(LayoutKind.Sequential)]

internal struct SP_DEVICE_INTERFACE_DATA

{

internal UInt32 cbSize;

internal Guid interfaceClassGuid;

internal UInt32 flags;

internal UIntPtr reserved;

}

  修改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)));

源代码下载


原网址: 访问
创建于: 2023-04-17 14:32:34
目录: default
标签: 无

请先后发表评论
  • 最新评论
  • 总共0条评论