下面是我在网上找到的搜索本机上的USB设备后再根据PNPDeceiveId打开USB设备,可是不知道为什么在自己的电脑上找不到相应设备,句柄的返回值总是-1,麻烦大家帮忙看一下哪里错了,
public static IntPtr openDeceive(String PNPDeviceID)
{
//if (String.IsNullOrEmpty(PNPDeviceID)) return null;
// 打开设备
IntPtr hHCDev = Kernel32.CreateFile(
"\\\\.\\" + PNPDeviceID.Replace('\\', '#') + "#{3ABF6F2D-71C4-462A-8A92-1E6861E6AF27}",
NativeFileAccess.GENERIC_WRITE,
NativeFileShare.FILE_SHARE_WRITE,
IntPtr.Zero,
NativeFileMode.OPEN_EXISTING,
IntPtr.Zero,
IntPtr.Zero);
// if (hHCDev == Kernel32.INVALID_HANDLE_VALUE) return null;
return hHCDev;
}
Kernel32.CreateFile方法如下:
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr CreateFile(
String fileName,
[MarshalAs(UnmanagedType.U4)] NativeFileAccess fileAccess,
[MarshalAs(UnmanagedType.U4)] NativeFileShare fileShare,
IntPtr securityAttributes,
[MarshalAs(UnmanagedType.U4)] NativeFileMode creationDisposition,
IntPtr flags,
IntPtr template
);
PNPDeceiveId获得方法如下:
public static PnPEntityInfo[] AllUsbDevices
{
get
{
return WhoUsbDevice(UInt16.MinValue, UInt16.MinValue, Guid.Empty);
}
}
/// <summary>
/// 查询USB设备实体(设备要求有VID和PID)
/// </summary>
/// <param name="VendorID">供应商标识,MinValue忽视</param>
/// <param name="ProductID">产品编号,MinValue忽视</param>
/// <param name="ClassGuid">设备安装类Guid,Empty忽视</param>
/// <returns>设备列表</returns>
public static PnPEntityInfo[] WhoUsbDevice(UInt16 VendorID, UInt16 ProductID, Guid ClassGuid)
{
List<PnPEntityInfo> UsbDevices = new List<PnPEntityInfo>();
// 获取USB控制器及其相关联的设备实体
ManagementObjectCollection USBControllerDeviceCollection = new ManagementObjectSearcher("SELECT * FROM Win32_USBControllerDevice").Get();
if (USBControllerDeviceCollection != null)
{
foreach (ManagementObject USBControllerDevice in USBControllerDeviceCollection)
{ // 获取设备实体的DeviceID
String Dependent = (USBControllerDevice["Dependent"] as String).Split(new Char[] { '=' })[1];
// 过滤掉没有VID和PID的USB设备
Match match = Regex.Match(Dependent, "VID_[0-9|A-F]{4}&PID_[0-9|A-F]{4}");
if (match.Success)
{
UInt16 theVendorID = Convert.ToUInt16(match.Value.Substring(4, 4), 16); // 供应商标识
if (VendorID != UInt16.MinValue && VendorID != theVendorID) continue;
UInt16 theProductID = Convert.ToUInt16(match.Value.Substring(13, 4), 16); // 产品编号
if (ProductID != UInt16.MinValue && ProductID != theProductID) continue;
ManagementObjectCollection PnPEntityCollection = new ManagementObjectSearcher("SELECT * FROM Win32_PnPEntity WHERE DeviceID=" + Dependent).Get();
if (PnPEntityCollection != null)
{
foreach (ManagementObject Entity in PnPEntityCollection)
{
Guid theClassGuid = new Guid(Entity["ClassGuid"] as String); // 设备安装类GUID
if (ClassGuid != Guid.Empty && ClassGuid != theClassGuid) continue;
PnPEntityInfo Element;
Element.PNPDeviceID = Entity["PNPDeviceID"] as String; // 设备ID
Element.Name = Entity["Name"] as String; // 设备名称
Element.Description = Entity["Description"] as String; // 设备描述
Element.Service = Entity["Service"] as String; // 服务
Element.Status = Entity["Status"] as String; // 设备状态
Element.VendorID = theVendorID; // 供应商标识
Element.ProductID = theProductID; // 产品编号
Element.ClassGuid = theClassGuid; // 设备安装类GUID
UsbDevices.Add(Element);
}
}
}
}
}
if (UsbDevices.Count == 0) return null; else return UsbDevices.ToArray();
}
通过 AllUsbDevices得到USB设备列表,之后获得其中一个设备的PNPDeceiveId,然后调用openDeceive方法,可是返回值总是-1,是一个无效值,麻烦大家帮忙找一下错误
我曾经试验过,.net不能访问设备驱动程序,也就是说"\.\xxxx"的文件是打不开的。
NativeFileAccess,NativeFileMode和NativeFileShare的定义如下
internal enum NativeFileAccess : uint
{
GENERIC_READ = (0x80000000),
GENERIC_WRITE = (0x40000000),
GENERIC_EXECUTE = (0x20000000),
GENERIC_ALL = (0x10000000),
FILE_SPECIAL = 0,
FILE_APPEND_DATA = (0x0004), // 文件
FILE_READ_DATA = (0x0001), // 文件和管道
FILE_WRITE_DATA = (0x0002), // 文件和管道
FILE_READ_EA = (0x0008), // 文件和目录
FILE_WRITE_EA = (0x0010), // 文件和目录
FILE_READ_ATTRIBUTES = (0x0080), // 所有
FILE_WRITE_ATTRIBUTES = (0x0100), // 所有
DELETE = 0x00010000,
READ_CONTROL = (0x00020000),
WRITE_DAC = (0x00040000),
WRITE_OWNER = (0x00080000),
SYNCHRONIZE = (0x00100000),
STANDARD_RIGHTS_REQUIRED = (0x000F0000),
STANDARD_RIGHTS_READ = (READ_CONTROL),
STANDARD_RIGHTS_WRITE = (READ_CONTROL),
STANDARD_RIGHTS_EXECUTE = (READ_CONTROL),
STANDARD_RIGHTS_ALL = (0x001F0000),
SPECIFIC_RIGHTS_ALL = (0x0000FFFF),
FILE_GENERIC_READ = (STANDARD_RIGHTS_READ | FILE_READ_DATA | FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE),
FILE_GENERIC_WRITE = (STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA | SYNCHRONIZE),
SPECIAL = 0
}
internal enum NativeFileMode : uint
{
CREATE_NEW = 1,
CREATE_ALWAYS = 2,
OPEN_EXISTING = 3,
OPEN_ALWAYS = 4,
TRUNCATE_EXISTING = 5,
}
[Flags]
internal enum NativeFileShare : uint
{
NONE = 0,
FILE_SHARE_READ = 0x00000001,
FILE_SHARE_WRITE = 0x00000002,
FILE_SHARE_DEELETE = 0x00000004,
}
查看API返回值,是否成功