.net 深入系统编程(二)
2009-11-25 18:29
561 查看
转载自:http://www.codeproject.com/KB/system/divingsysprog2.aspx
/Files/kk1230/.net Diving into System Programming/DevInfo.zipIntroduction
In Part 1, I have demonstrated how to enumerate device classes. Now let us see how to enumerate devices of the class.Device enumeration
First of all, let us look again at the picture with Device Manager information. It is easy - Device Manager enumerate devices when we expand the tree for device class.The idea of device enumeration is not difficult for understanding:
Get class Guid using device class name (
SetupDiClassGuidsFromNameAfunction)
Get device info set for device class (
SetupDiGetClassDevsAfunction)
Get device info data for every device (
SetupDiGetClassDevsAfunction, second parameters for this function is sequential device index in the device class, so call this function in circle with device index = 0, 1, etc.).
Get device name from Registry via
SetupDiGetDeviceRegistryPropertyAfunction.
Below you see code in C# that will enumerate devices for selected device class for PC.
using System; using System.Text; using System.Runtime.InteropServices; namespace DevInfo { class DeviceInfo { public const int DIGCF_PRESENT = (0x00000002); public const int MAX_DEV_LEN = 1000; public const int SPDRP_FRIENDLYNAME = (0x0000000C); // FriendlyName (R/W) public const int SPDRP_DEVICEDESC = (0x00000000); // DeviceDesc (R/W) [StructLayout(LayoutKind.Sequential)] public class SP_DEVINFO_DATA { public int cbSize; public Guid ClassGuid; public int DevInst; // DEVINST handle public ulong Reserved; }; [DllImport("setupapi.dll")]// public static extern Boolean SetupDiClassGuidsFromNameA(string ClassN, ref Guid guids, UInt32 ClassNameSize, ref UInt32 ReqSize); [DllImport("setupapi.dll")] public static extern IntPtr //result HDEVINFO SetupDiGetClassDevsA(ref Guid ClassGuid, UInt32 Enumerator, IntPtr hwndParent, UInt32 Flags); [DllImport("setupapi.dll")] public static extern Boolean SetupDiEnumDeviceInfo(IntPtr DeviceInfoSet, UInt32 MemberIndex, SP_DEVINFO_DATA DeviceInfoData); [DllImport("setupapi.dll")] public static extern Boolean SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet); [DllImport("setupapi.dll")] public static extern Boolean SetupDiGetDeviceRegistryPropertyA(IntPtr DeviceInfoSet, SP_DEVINFO_DATA DeviceInfoData, UInt32 Property, UInt32 PropertyRegDataType, StringBuilder PropertyBuffer, UInt32 PropertyBufferSize, IntPtr RequiredSize); public static int EnumerateDevices(UInt32 DeviceIndex, string ClassName, StringBuilder DeviceName) { UInt32 RequiredSize = 0; Guid guid=Guid.Empty; Guid[] guids=new Guid[1]; IntPtr NewDeviceInfoSet; SP_DEVINFO_DATA DeviceInfoData= new SP_DEVINFO_DATA(); bool res=SetupDiClassGuidsFromNameA(ClassName, ref guids[0],RequiredSize, ref RequiredSize); if(RequiredSize==0) { //incorrect class name: DeviceName=new StringBuilder(""); return -2; } if(!res) { guids=new Guid[RequiredSize]; res=SetupDiClassGuidsFromNameA(ClassName,ref guids[0],RequiredSize, ref RequiredSize); if(!res || RequiredSize==0) { //incorrect class name: DeviceName=new StringBuilder(""); return -2; } } //get device info set for our device class NewDeviceInfoSet=SetupDiGetClassDevsA(ref guids[0],0,IntPtr.Zero, DIGCF_PRESENT); if( NewDeviceInfoSet.ToInt32() == -1 ) if(!res) { //device information is unavailable: DeviceName=new StringBuilder(""); return -3; } DeviceInfoData.cbSize = 28; //is devices exist for class DeviceInfoData.DevInst=0; DeviceInfoData.ClassGuid=System.Guid.Empty; DeviceInfoData.Reserved=0; res=SetupDiEnumDeviceInfo(NewDeviceInfoSet, DeviceIndex,DeviceInfoData); if(!res) { //no such device: SetupDiDestroyDeviceInfoList(NewDeviceInfoSet); DeviceName=new StringBuilder(""); return -1; } DeviceName.Capacity=MAX_DEV_LEN; if(!SetupDiGetDeviceRegistryPropertyA(NewDeviceInfoSet, DeviceInfoData, SPDRP_FRIENDLYNAME,0,DeviceName,MAX_DEV_LEN,IntPtr.Zero) ) { res = SetupDiGetDeviceRegistryPropertyA(NewDeviceInfoSet, DeviceInfoData,SPDRP_DEVICEDESC,0,DeviceName,MAX_DEV_LEN, IntPtr.Zero); if(!res){ //incorrect device name: SetupDiDestroyDeviceInfoList(NewDeviceInfoSet); DeviceName=new StringBuilder(""); return -4; } } return 0; } [STAThread] static void Main(string[] args) { StringBuilder devices=new StringBuilder(""); UInt32 Index=0; int result=0; if(args.Length != 1) { Console.WriteLine("command line format:"); Console.WriteLine("DevInfo <CLASSNAME>"); return; } while(true) { result=EnumerateDevices(Index, args[0], devices); Index++; if(result == -2) { Console.WriteLine("Incorrect name of Class = {0}", args[0]); break; } if(result == -1)break; if(result == 0)Console.WriteLine("Device{0} is {1}", Index, devices); } } } }
The command line for this console application - DevInfo classname
classname- the name of device class. You can use application from previous article to find correct device class name. After running application you can see devices for any device class on your PC.
Summary
Now we can join code from the first article and this article, add information about devices (for example, resources like IRQs, ports, etc) and put it in the Windows Forms application. But it is a subject for Part 3.License
This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)相关文章推荐
- .NET – 深入系统编程 - Part 1
- ACCPS2深入.net和c#编程影院售票系统 购票.打印.持续销售
- .net 深入系统编程 (一)
- .net 深入系统编程(三)
- 深入.NET平台和C#编程 错题录
- .NET学习笔记(3)——深入.net平台和C#编程
- 计算机编程基础之深入理解计算机系统1
- .NET数据库编程求索之路--2.示例系统概览与设计(1)
- 网络编程 客户端 服务端 函数 流程 图示 来自深入理解计算机系统一书 P704
- 深入.NET平台和C#编程 第五章 学习笔记
- S2 深入.NET和C#编程 三:使用集合组织相关数据
- 深入.NET平台和C#编程 第一章 学习笔记
- 深入.NET平台和C#编程的错题
- 在.net 编程环境中,系统的资源分为托管资源和非托管资源。
- 深入理解计算机系统:网络编程
- .NET – 深入系统编程 - Part 1
- .NET数据库编程求索之路--2.示例系统概览与设计(2)
- ubantu 配置<<深入理解计算机系统>>的 C语言编程环境
- 深入.NET平台的软件系统分成开发(1/6)
- 深入.NET平台和C#编程 第二章 学习笔记