zoukankan      html  css  js  c++  java
  • 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)));
    

      

    源代码下载

  • 相关阅读:
    Excel 相关实用计算公式
    C# ThreadState属性分析
    U8 数据库服务器和应用服务器 分离后出现 登陆系统管理 远程组件初始化 失败 解决方案!
    MyEclipse 快捷键
    项目中用到的开源框架
    spring.net nhibernate 不一定是自增变量,也可能是触发器 Batch update returned unexpected row count from update; actual row count: 2; expected: 1
    解决方法: A C3P0Registry mbean is already registered.This probably means that an application using c3p0的警告信息处理
    NHibenate hbm.xml 自动 生成 数据库表的时候 长度为1
    解决方法: Failed to load the sqljdbc_auth.dll
    SQL 中判断 纯数字
  • 原文地址:https://www.cnblogs.com/coolkiss/p/3205124.html
Copyright © 2011-2022 走看看