C# 弹出USB外接硬盘(U盘)
最近一个项目需要通过代码来弹出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盘)的更多相关文章
- vc弹出USB的方法. 附试验通过的代码!
vc弹出USB的方法. 附试验通过的代码! http://blog.sina.com.cn/s/blog_4fcd1ea30100qrzn.html (2011-04-15 10:09:48) boo ...
- 弹出USB大容量存储设备时出问题的解决方法
我的计算机->管理->系统工具->事件查看器->自定义视图->Kernel-Pnp->详情->进程ID 然后在任务管理器里找到该进程(任务管理器->查看 ...
- WPF如何卸载U盘(弹出USB设备)
应用程序和硬件设备的通信过程是:应用程序使用CreateFile函数打开设备,然后用DeviceIoControl()与硬件设备通信. CreateFile函数: [DllImport("k ...
- 【转】弹出USB大容量存储设备时出问题的解决方法
原文链接 如下图所示,这个问题,相信很多人都有遇到过,而且经常难以解决,试了很多方法都无效.到最后,只能抱着侥幸的心理直接拔出,如果运气好,可能没有事,如果运气不好,你的U盘或者移动硬盘就要从此报废了 ...
- usb设备(移动硬盘或U盘),弹出时提示“有进程或程序占用,无法弹出”。解决办法
测试环境:Win7(其他Windows系统环境,也可参考) 总结办法来源,https://bbs.csdn.net/topics/392297251?page=1文章中热心网友的评论指引 1. 控制面 ...
- USB设备的插入和弹出的监听以及软弹出可移动媒体(如Windows的移除USB设备) .
一.监听USB设备的插入和弹出 当USB设备插入或者弹出时,Windows会产生一条全局消息:WM_DEVICECHANGE 我们需要做的是,获得这条消息的wParam参数,如果为DBT_DEVICE ...
- VMware 中如何打开U盘弹出U盘或者移动硬盘的(两种方法)
1.U盘如下,插入后都是直接在win里面显示的 2.选择连接u盘 3.u盘就可以在虚拟机里面显示了 4.弹出则选择断开连接 扩展:如果无效:请参考这种方法 (给虚拟机分配一个临时硬盘,然后设置这个临时 ...
- 修改某个UITextField的键盘的返回键类型以及监听键盘的高度变化,取到键盘动画退出弹出的时间,一起随着键盘顶出来或者压下去,
1.修改某个UITextField的键盘的返回键类型: [_bottomTextView setReturnKeyType:UIReturnKeyDone]; 1.1.textFied点击return ...
- (二十四)监听键盘的通知和键盘弹出隐藏的View移动
让控制器监听键盘的通知,注意谁监听,谁的dealloc方法中就要remove,如果非ARC还要调用父类的dealloc方法. //监听键盘的操作: [[NSNotificationCenter def ...
随机推荐
- 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 ...
- python中的计时器:timeit
python中的计时器:timeit timeit 通常在一段程序的前后都用上time.time(),然后进行相减就可以得到一段程序的运行时间,不过python提供了更强大的计时库:timeit #导 ...
- 尝试php命令行脚本多进程并发执行
php不支持多线程,但是我们可以把问题转换成“多进程”来解决.由于php中的pcntl_fork只有unix平台才可以使用,所以本文尝试使用popen来替代. 下面是一个例子: 被并行调用的子程序 ...
- thinkphp5.0安装
ThinkPHP5的环境要求如下: PHP >= 5.4.0 PDO PHP Extension MBstring PHP Extension CURL PHP Extension 严格来说,T ...
- Kuhn-Munkres算法
KM算法——二分图最大权匹配 我们前面学过了二分图匹配的匈牙利算法.但这种算法是针对没有权值的图来说的. 肯定有人想问,没有权值的用匈牙利算法,哪有权值的图要求最大权或最小权匹配呢?? 这里就引出了我 ...
- 检验Xcode是否被改动过的简单方法,不妨试试!!!
检验Xcode是否被改动过的简单方法,不妨试试!!! 在终端系统上运行以下命令启用检测: spctl --assess --verbose /Applications/Xcode.app ...
- FastReport.Net使用:[14]文本控件使用
文本控件(Text)是FastReport中最常用的控件了,它可以是一行\多行文本.数据源的列.报表参数.汇总值.表达式,它还可以是以上任何元素的组合. 如何使用文本编辑器 1.双击文本框进入文本编辑 ...
- 【BZOJ 4403】 4403: 序列统计 (卢卡斯定理)
4403: 序列统计 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 653 Solved: 320 Description 给定三个正整数N.L和R, ...
- 【2-SAT】【DFS】【分类讨论】Gym - 101617K - Unsatisfying
题意:给你一张2-SAT,问你加至少几句a V b(不能用非运算)这样的语句,使得其无法全为真. 如果最开始没有左右两项都含非运算的析取表达式,则无解,因为显然你可以对每一项的不含非的那项规定为真,使 ...
- 扩展gcd codevs 1200 同余方程
codevs 1200 同余方程 2012年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 求关 ...