在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
近日在工作中需要根据设备的HardwareID来获取设备的驱动程序信息,比如驱动程序版本等。经过摸索,得到了两种不同的解决办法,两种办法各有千秋,写出来给大家分享。
private string GetDriverVersion( string hardwareID )
{ string queryString = "SELECT HardwareID, DriverVersion FROM Win32_PnPSignedDriver"; SelectQuery selectQuery = new SelectQuery( queryString ); ManagementObjectSearcher searcher = new ManagementObjectSearcher(selectQuery); foreach (ManagementObject mo in searcher.Get()) { object tempID = mo["HardwareID"]; if( tempID!=null && tempID.ToString().ToUpper() == hardwareID.Trim().ToUpper() ) { return mo["DriverVersion"].ToString(); } } return "UnknownVersion"; } 这样取得驱动程序的方式是非常简洁的,但是有一个非常严重的问题就是效率问题。平均说来,每执行一次查询,得到一个DriverVersion需要大约3秒的时间。对于我们的应用来说,这个时间是不可以接受的。也许你会说,为什么不用更多的限定符号来进一步减少查询的次数呢?
string queryString = "SELECT HardwareID, DriverVersion FROM Win32_PnPSignedDriver WHERE HardwareID='somehardware'";
程序的效率并没有明显的改进。而且还发现一个问题,如果我们somehardware里面含有一个'\'(也就是HardwareID='some\\hardware'),那么一定会得到一个“Invalid Query”异常。但是在WMITOOLS里面查询又是正常的,希望达人出来指点一下。最后根据MSDN的描述,只有Windows Vista,Windows XP和Windows 2003支持这个类。由于我们的程序需要跑在2000下,因此这种方法是行不通的了。 2 使用PInvoke
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Auto)]
public struct SP_DEVINFO_DATA { public int cbSize; public Guid ClassGuid; public IntPtr DevInst; public IntPtr Reserved; } 要注意的是LayoutKind.Sequential, Pack = 4 和 public IntPtr Reserved。如果不按照这样声明,无法调用成功。
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Auto)]
public struct SP_DRVINFO_DATA { public int cbSize; public int DriverType; public IntPtr Reserved; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string Description; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string MfgName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string ProviderName; public FILETIME DriverDate; public ulong DriverVersion; } 对于最后的从DWORDLONG转换成x.x.x.x的版本,可以按照下面的方式转换。DWORDLONG是8字节的无符号整数,x.x.x.x中的x是从0到65536的无符号整数,占2个字节。因此可以直接把8字节的整数分成4个2字节的整数,最后合起来就是版本号了。假设版本version = 1407379348914176,将version转换成2进制数为:
//version = 1407379348914176,转换后的版本为5.1.2600.0
private string GetVersionFromLong( ulong version ) { ulong baseNumber = 0xFFFF; StringBuilder sb = new StringBuilder(); ulong temp = 0L; for( int offset = 48; offset >= 0; offset -= 16 ) { temp = (version >> offset) & baseNumber; sb.Append( temp.ToString() + "." ); } return sb.ToString(); } 通过调用API这种方式,速度得到了很大的提高,1秒之内就可以完成一次查询。而且适合于Win2000,Win XP,Win2003和Vista。 |
请发表评论