最近一个项目需要通过代码来弹出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. intellij自动生成java代码注释(java文件注释和方法注释)

    1定义java文件头部的注释 2给java类中的方法添加上注释 2.1第一步勾选Enable Live  Templates 2.2第二步新建一个Group 2.3第三步新建一个Template 2. ...

  2. list 移除值

    1. 移除基本类型值时,传入int 会以下标为依据移除 , 但传入Integer 对象时,则是移除对象为依据移除(即不受此对象代表的值相等的下标的影响) 都是只能移除一个值,(list 中有多个1时, ...

  3. ul>li中自定义属性后取值的问题

    动态赋值的li: $.ajax({ type: "POST", url: "${base}/before/subDemand/listType", succes ...

  4. 用Redis Desktop Manager连接Redis(CentOS)

    Redis Desktop Manager是Redis图形化管理工具,方便管理人员更方便直观地管理Redis数据. 然而在使用Redis Desktop Manager之前,有几个要素需要注意: 一. ...

  5. Python爬虫笔记(一)

    个人笔记,仅适合个人使用(大部分摘抄自python修行路) 1.爬虫Response的内容 便是所要获取的页面内容,类型可能是HTML,Json(json数据处理链接)字符串,二进制数据(图片或者视频 ...

  6. Host aggregate分区

    问题描述:生产区一期环境增加4台计算结点,希望被大数据租户独占1. 该大数据用户创建的虚拟机必须被调度到这4个计算结点2. 其他租户创建虚拟机禁止调度到这4台机器 标黄的需要自行根据情况修改解决方案: ...

  7. RxSwift 系列(七)

    前言 本篇文章将要学习RxSwift中连接操作符.Connectable Observable在订阅时不发射事件消息,而是仅当调用它们的connect()方法时才发射消息,这样就可以等待所有我们想要的 ...

  8. android studio 目录 文件 解读

  9. editplus运行php 配置

    工具->配置用户工具->添加工具:Menu Text 改成runphp或者其他任名称.Command 安装的php.exe的地址.如D:\ wamp\php\php5.4.3\php.ex ...

  10. 【BZOJ】2002: [Hnoi2010]Bounce 弹飞绵羊

    2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 14802  Solved: 7507[Subm ...