最近一个项目需要通过代码来弹出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
标签: 无
未标明原创文章均为采集,版权归作者所有,转载无需和我联系,请注明原出处,南摩阿彌陀佛,知识,不只知道,要得到
最新评论