最近一个项目需要通过代码来弹出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)));

  

源代码下载

C# 弹出USB外接硬盘(U盘)的更多相关文章

  1. vc弹出USB的方法. 附试验通过的代码!

    vc弹出USB的方法. 附试验通过的代码! http://blog.sina.com.cn/s/blog_4fcd1ea30100qrzn.html (2011-04-15 10:09:48) boo ...

  2. 弹出USB大容量存储设备时出问题的解决方法

    我的计算机->管理->系统工具->事件查看器->自定义视图->Kernel-Pnp->详情->进程ID 然后在任务管理器里找到该进程(任务管理器->查看 ...

  3. WPF如何卸载U盘(弹出USB设备)

    应用程序和硬件设备的通信过程是:应用程序使用CreateFile函数打开设备,然后用DeviceIoControl()与硬件设备通信. CreateFile函数: [DllImport("k ...

  4. 【转】弹出USB大容量存储设备时出问题的解决方法

    原文链接 如下图所示,这个问题,相信很多人都有遇到过,而且经常难以解决,试了很多方法都无效.到最后,只能抱着侥幸的心理直接拔出,如果运气好,可能没有事,如果运气不好,你的U盘或者移动硬盘就要从此报废了 ...

  5. usb设备(移动硬盘或U盘),弹出时提示“有进程或程序占用,无法弹出”。解决办法

    测试环境:Win7(其他Windows系统环境,也可参考) 总结办法来源,https://bbs.csdn.net/topics/392297251?page=1文章中热心网友的评论指引 1. 控制面 ...

  6. USB设备的插入和弹出的监听以及软弹出可移动媒体(如Windows的移除USB设备) .

    一.监听USB设备的插入和弹出 当USB设备插入或者弹出时,Windows会产生一条全局消息:WM_DEVICECHANGE 我们需要做的是,获得这条消息的wParam参数,如果为DBT_DEVICE ...

  7. VMware 中如何打开U盘弹出U盘或者移动硬盘的(两种方法)

    1.U盘如下,插入后都是直接在win里面显示的 2.选择连接u盘 3.u盘就可以在虚拟机里面显示了 4.弹出则选择断开连接 扩展:如果无效:请参考这种方法 (给虚拟机分配一个临时硬盘,然后设置这个临时 ...

  8. 修改某个UITextField的键盘的返回键类型以及监听键盘的高度变化,取到键盘动画退出弹出的时间,一起随着键盘顶出来或者压下去,

    1.修改某个UITextField的键盘的返回键类型: [_bottomTextView setReturnKeyType:UIReturnKeyDone]; 1.1.textFied点击return ...

  9. (二十四)监听键盘的通知和键盘弹出隐藏的View移动

    让控制器监听键盘的通知,注意谁监听,谁的dealloc方法中就要remove,如果非ARC还要调用父类的dealloc方法. //监听键盘的操作: [[NSNotificationCenter def ...

随机推荐

  1. Nuxt 2.0 需要将pug-loader改成pug-plain-loader

    Nuxt 2.0 需要将pug-loader改成pug-plain-loader npm i pug-plain-loader -D 解决问题!! 参考链接 https://my.oschina.ne ...

  2. python中的计时器:timeit

    python中的计时器:timeit timeit 通常在一段程序的前后都用上time.time(),然后进行相减就可以得到一段程序的运行时间,不过python提供了更强大的计时库:timeit #导 ...

  3. 尝试php命令行脚本多进程并发执行

    php不支持多线程,但是我们可以把问题转换成“多进程”来解决.由于php中的pcntl_fork只有unix平台才可以使用,所以本文尝试使用popen来替代.  下面是一个例子:  被并行调用的子程序 ...

  4. thinkphp5.0安装

    ThinkPHP5的环境要求如下: PHP >= 5.4.0 PDO PHP Extension MBstring PHP Extension CURL PHP Extension 严格来说,T ...

  5. Kuhn-Munkres算法

    KM算法——二分图最大权匹配 我们前面学过了二分图匹配的匈牙利算法.但这种算法是针对没有权值的图来说的. 肯定有人想问,没有权值的用匈牙利算法,哪有权值的图要求最大权或最小权匹配呢?? 这里就引出了我 ...

  6. 检验Xcode是否被改动过的简单方法,不妨试试!!!

    检验Xcode是否被改动过的简单方法,不妨试试!!!       在终端系统上运行以下命令启用检测: spctl --assess --verbose /Applications/Xcode.app  ...

  7. FastReport.Net使用:[14]文本控件使用

    文本控件(Text)是FastReport中最常用的控件了,它可以是一行\多行文本.数据源的列.报表参数.汇总值.表达式,它还可以是以上任何元素的组合. 如何使用文本编辑器 1.双击文本框进入文本编辑 ...

  8. 【BZOJ 4403】 4403: 序列统计 (卢卡斯定理)

    4403: 序列统计 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 653  Solved: 320 Description 给定三个正整数N.L和R, ...

  9. 【2-SAT】【DFS】【分类讨论】Gym - 101617K - Unsatisfying

    题意:给你一张2-SAT,问你加至少几句a V b(不能用非运算)这样的语句,使得其无法全为真. 如果最开始没有左右两项都含非运算的析取表达式,则无解,因为显然你可以对每一项的不含非的那项规定为真,使 ...

  10. 扩展gcd codevs 1200 同余方程

    codevs 1200 同余方程 2012年NOIP全国联赛提高组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题目描述 Description 求关 ...