分享
 
 
 

.NET – 深入系统编程 - Part 1

王朝c#·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

.NET – 深入系统编程 - Part 1

By Vladimir Afanasyev

介绍

在我以前的文章里面,我举了很多系统编程的例子。很多年前,我特别喜欢琢磨系统表格以及系统工具。当然,那时我还没有一个真正PC,只是类似于IBM360、PDP11或者microVAX,但是那种感觉不错。这些年我依然喜欢在COM接口、DLL库和硬盘配置上作些研究。啊哈,我一直喜欢系统编程!

目的

很多人认为C#只是一个 "child language" 。在我看来,这绝对是错误的!为了证明我的观点,我准备编写三个关于硬件设备配置的例子,展现如何使用C#和Win32 API(甚至DDK)一起工作。主要是使用P/Invoke来实现。同时C#非常完美的解决了不同平台数据交流的问题,以及通过Windows Forms ,使我们更容易使用应用程序。

设备类

All devices in the system join in the device classes. As you can see in the below picture, the class has name and Guid (so it can be found in Registry). The class can also have a description. For example, for class "Ports" the description is "Ports (COM & LPT)". Class also has devices that are present in the configuration.

所有的设备信息都存在于设备类中。这个类拥有名字和Guid(因此它可以在注册表中被找到)。这个类还有一些描述,比如类"Ports"的描述是"Ports (COM & LPT)"。

系统设备管理器给出了所有在PC上存在的设备类的信息:

下面,你将看到使用C#遍历所有设备的例子,它使用了P/Invoke、DDK和SDK DLLs。

using System;

using System.Runtime.InteropServices;// P/Invoke 必需

using System.Text;

namespace DevClasses

{

/// <summary>

/// Summary description for Class.

/// </summary>

class DeviceClasses

{

/// <summary>

/// The main entry point for the application.

/// </summary>

public const int MAX_NAME_PORTS=7;

public const int RegDisposition_OpenExisting=(0x00000001);

// open key only if exists

public const int CM_REGISTRY_HARDWARE=(0x00000000);

public const int CR_SUCCESS = (0x00000000);

public const int CR_NO_SUCH_VALUE = (0x00000025);

public const int CR_INVALID_DATA = (0x0000001F);

public const int DIGCF_PRESENT = (0x00000002);

public const int DIOCR_INSTALLER = (0x00000001);

// MaximumAllowed access type to Reg.

public const int MAXIMUM_ALLOWED = (0x02000000);

[StructLayout(LayoutKind.Sequential)] //为了保证数据交流顺利

public class SP_DEVINFO_DATA //struct 也可以

{

public int cbSize;

public Guid ClassGuid;

public int DevInst; // DEVINST handle

public ulong Reserved;

};

//声明函数原型

[DllImport("cfgmgr32.dll")]

public static extern UInt32

CM_Open_DevNode_Key(IntPtr dnDevNode, UInt32 samDesired,

UInt32 ulHardwareProfile,

UInt32 Disposition,IntPtr phkDevice, UInt32 ulFlags);

[DllImport("cfgmgr32.dll")]

public static extern UInt32

CM_Enumerate_Classes(UInt32 ClassIndex,ref Guid ClassGuid, UInt32 Params);

[DllImport("setupapi.dll")]//

public static extern Boolean

SetupDiClassNameFromGuidA(ref Guid ClassGuid,

StringBuilder ClassName, //char * ?

UInt32 ClassNameSize, ref UInt32 RequiredSize);

[DllImport("setupapi.dll")]

public static extern IntPtr

SetupDiGetClassDevsA(ref Guid ClassGuid, UInt32 Enumerator,

IntPtr hwndParent, UInt32 Flags);

[DllImport("setupapi.dll")]

public static extern Boolean

SetupDiEnumDeviceInfo(IntPtr DeviceInfoSet, UInt32 MemberIndex,

ref SP_DEVINFO_DATA DeviceInfoData);

[DllImport("setupapi.dll")]

public static extern Boolean

SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet);

[DllImport("setupapi.dll")]

public static extern IntPtr

SetupDiGetClassDevsA(ref Guid ClassGuid, UInt32 samDesired,

UInt32 Flags, ref string hwndParent, IntPtr Reserved);

[DllImport("setupapi.dll")]

public static extern IntPtr

SetupDiOpenClassRegKeyExA(

ref Guid ClassGuid, UInt32 samDesired, int Flags, IntPtr MachineName,

UInt32 Reserved);

[DllImport("advapi32.dll")]

public static extern UInt32

RegQueryValueA(IntPtr KeyClass,UInt32 SubKey,

StringBuilder ClassDescription,ref UInt32 sizeB);

[DllImport("user32.dll")]

public static extern Boolean

CharToOem(String lpszSrc, StringBuilder lpszDst);

//遍历

public static int EnumerateClasses(UInt32 ClassIndex,

ref StringBuilder ClassName, StringBuilder ClassDescription,

ref bool DevicePresent)

{

Guid ClassGuid=Guid.Empty;

IntPtr NewDeviceInfoSet;

SP_DEVINFO_DATA DeviceInfoData;

UInt32 result;

StringBuilder name=new StringBuilder("");

bool resNam=false;

UInt32 RequiredSize=0;

IntPtr ptr;

result = CM_Enumerate_Classes(ClassIndex, ref ClassGuid,0);

ClassName=new StringBuilder("");

DevicePresent=false;

//incorrect device class:

if(result == CR_INVALID_DATA)

{

return -2;

}

//device class is absent

if(result == CR_NO_SUCH_VALUE)

{

return -1;

}

//bad param. - fatal error

if(result != CR_SUCCESS)

{

return -3;

}

name.Capacity=0;

resNam=SetupDiClassNameFromGuidA(ref ClassGuid,name,RequiredSize,

ref RequiredSize);

if(RequiredSize > 0)

{

name.Capacity=(int)RequiredSize;

resNam=SetupDiClassNameFromGuidA(ref ClassGuid,name,

RequiredSize,ref RequiredSize);

}

NewDeviceInfoSet=SetupDiGetClassDevsA(

ref ClassGuid,

0,

IntPtr.Zero,

DIGCF_PRESENT);

if(NewDeviceInfoSet.ToInt32() == -1)

{ DevicePresent=false;

ClassName=name;

return 0;}

IntPtr KeyClass=SetupDiOpenClassRegKeyExA(

ref ClassGuid, MAXIMUM_ALLOWED, DIOCR_INSTALLER,IntPtr.Zero,0);

if(KeyClass.ToInt32() == -1)

{ DevicePresent=false;

ClassName=name;

return 0;}

UInt32 sizeB=1000;

String abcd="";

StringBuilder CD=new StringBuilder("");

ClassDescription.Capacity=1000;

UInt32 res=RegQueryValueA(KeyClass,0,ClassDescription,ref sizeB);

if(res != 0)ClassDescription=new StringBuilder("");

SetupDiDestroyDeviceInfoList(NewDeviceInfoSet);

ClassName=name;

DevicePresent=true;

return 0;

}

[STAThread]

static void Main(string[] args)

{

StringBuilder classes=new StringBuilder("");

StringBuilder classesDescr=new StringBuilder("");

StringBuilder classesDescrOEM=new StringBuilder("");

classesDescrOEM.Capacity=1000;

Boolean DevExist=false;

UInt32 i=0;

while(true)

{

int res=EnumerateClasses(i,ref classes,classesDescr,ref DevExist);

if(res == -1)

break;

++i;

if(res < -1 || !DevExist)continue;

Console.WriteLine("ClassName={0}, Description={1}",classes,classesDescr);

}

return;

}

}

}

运行这个应用程序之后,你将看到你机器上的所有设备类。

出自:

http://www.codeproject.com/csharp/DivingSysProg1.asp

译者的话:

这只是作者一系列文章中的第一章。没有太多的深入讲解知识,只是举了一个例子而已。

biqiong2004@hotmail.com

PS:

原文有图片,这里可能看不到,可以到我的主页上看这篇文章。

http://home.ripway.com/2004-6/124912/

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有