此部分代码请大家给加上注释。

const
  DEV_CLASS_NAME    = 'Net';
  DEM_CLASS_NAME    = 'MEDIA';
  DEC_CLASS_NAME    = 'CDROM';
  DEU_CLASS_NAME    = 'USB';
  DEP_CLASS_NAMW    = 'ports';
  UNKNOWN_DEVICE    = '<未知设备>';

private
    { Private declarations }
    DevState: Array of Boolean;
    procedure RefreshDevState;

procedure EnumNetDevice;   //获得网卡 信息
    function IsClassHidden(const ClassGUID: PGUID): Boolean; //被EnumNetDevice调用
    function ConstructDeviceName(DeviceInfoSet: HDEVINFO;    //被EnumNetDevice调用
        DeviceInfoData: PSP_DEVINFO_DATA; Buffer: PAnsiChar; Length: ULONG): Boolean;
    function GetRegistryProperty(DeviceInfoSet: HDEVINFO;    //被EnumNetDevice调用
        DeviceInfoData: PSP_DEVINFO_DATA; AProperty: ULONG; Buffer: PAnsiChar;
        Length: ULONG): Boolean;
    function IsDevDisable(DevIndex: DWORD; hDevInfo: HDEVINFO): Boolean; //被EnumNetDevice调用
    function ChangeDevState(DevIndex, NewState: DWORD): BOOL;  //改变网卡状态
  public
    { Public declarations }
  end;

var
  DevForm: TDevForm;

implementation

{$R *.dfm}

procedure TDevForm.EnumNetDevice;  //获得网卡信息
var
    DeviceInfoSet: HDEVINFO;
    DeviceInfoData: SP_DEVINFO_DATA;
    i: Integer;
    Status, Problem: DWORD;
    ClassName: PChar;
    ClassSize, ReqClassSize: DWORD;
    DeviceName: PChar;
begin
    clbDevList.Clear;

DeviceInfoSet:=SetupDiGetClassDevs(Nil,Nil,0,DIGCF_ALLCLASSES or DIGCF_PRESENT);
    if DeviceInfoSet = Pointer(INVALID_HANDLE_VALUE) then
      Exit;
    ClassSize:=255;
    GetMem(ClassName,256);
    try
      DeviceInfoData.cbSize := SizeOf(SP_DEVINFO_DATA); //枚举硬件,获得需要的接口

i:=0;
      while SetupDiEnumDeviceInfo(DeviceInfoSet,i,@DeviceInfoData) do
      begin
          Inc(i);

if not SetupDiClassNameFromGuid(@DeviceInfoData.ClassGuid,ClassName,ClassSize,
              @ReqClassSize) then
          begin
              if ReqClassSize>ClassSize then
              begin
                FreeMem(ClassName);
                ClassSize:=ReqClassSize;
                GetMem(ClassName,ClassSize+1);
                if not SetupDiClassNameFromGuid(@DeviceInfoData.ClassGuid,ClassName,ClassSize,
                    @ReqClassSize) then
                  Exit;
            end
            else
                Exit;
        end;

if  not SameText(ClassName,DEV_CLASS_NAME) and  not SameText(ClassName,DEM_CLASS_NAME) and
           not SameText(ClassName,DEC_CLASS_NAME) and not SameText(ClassName,DEU_CLASS_NAME) and
           not SameText(ClassName,DEP_CLASS_NAMW) then
          Continue;

if CM_Get_DevNode_Status(@Status, @Problem, DeviceInfoData.DevInst,0)
            <> CR_SUCCESS then
          Exit;

if ((Status and DN_NO_SHOW_IN_DM)<>0) or
            IsClassHidden(@DeviceInfoData.ClassGuid) then
          Continue;

GetMem(DeviceName,256);  //给DeviceName变量分配 256 的内存
        ZeroMemory(DeviceName,256);   //给DeviceName的每个单元赋值  值为 零
        ConstructDeviceName(DeviceInfoSet,@DeviceInfoData,DeviceName,255); //获得了 DeviceName的值
        if IsDevDisable(i-1,DeviceInfoSet) then
          begin
              clbDevList.Items.AddObject(StrPas(DeviceName)+'-----'+classname,TObject(i-1));  //把DeviceName的值加入到列表中i-1行
              clbDevList.Checked[clbDevList.Count-1]:= IsDevDisable(i-1,DeviceInfoSet); // Checked的值为true
          end;
        FreeMem(DeviceName); //释放DeviceName所占的内存
      end;
    finally
      FreeMem(ClassName);
      SetupDiDestroyDeviceInfoList(DeviceInfoSet);
    end;
end;

function TDevForm.ConstructDeviceName(DeviceInfoSet: HDEVINFO;  //构造 DeviceName 的值
  DeviceInfoData: PSP_DEVINFO_DATA; Buffer: PAnsiChar;
  Length: ULONG): Boolean;
begin
    Result:=True;

if not GetRegistryProperty(DeviceInfoSet,DeviceInfoData,SPDRP_FRIENDLYNAME,
        Buffer,Length) then
    begin
        if not GetRegistryProperty(DeviceInfoSet,DeviceInfoData,SPDRP_DEVICEDESC,
            Buffer,Length) then
        begin
            if not GetRegistryProperty(DeviceInfoSet,DeviceInfoData,SPDRP_CLASS,
                Buffer,Length) then
            begin
                if not GetRegistryProperty(DeviceInfoSet,DeviceInfoData,SPDRP_CLASSGUID,
                    Buffer,Length) then
                begin
                    StrCopy(Buffer,UNKNOWN_DEVICE);   //获得 DeviceName 的值 为‘未知设备’
                end
                else
                    Result:=False;
            end;
        end;
    end;
end;

function TDevForm.GetRegistryProperty(DeviceInfoSet: HDEVINFO;
  DeviceInfoData: PSP_DEVINFO_DATA; AProperty: ULONG; Buffer: PAnsiChar;
  Length: ULONG): Boolean;
var
    ReqLen: DWORD;
begin
    Result:=False;

while not SetupDiGetDeviceRegistryProperty(DeviceInfoSet,DeviceInfoData,
       AProperty,Nil,Buffer,Length,@ReqLen) do
    begin
        if GetLastError() = ERROR_INVALID_DATA then
          break
        else
        if GetLastError() = ERROR_INSUFFICIENT_BUFFER then
        begin
            if Assigned(Buffer) then
              FreeMem(Buffer);
              Length:=ReqLen;
              GetMem(Buffer,Length+1);
        end
        else
            Exit;
    end;
    Result:=Buffer^<>#0;
end;

function TDevForm.IsClassHidden(const ClassGUID: PGUID): Boolean;
var
    hKeyClass: HKEY;
begin
    Result:=False;

hKeyClass := SetupDiOpenClassRegKey(ClassGuid,KEY_READ);  //获得KEY值
    if hKeyClass<>0 then
    begin
        Result:= RegQueryValueEx(hKeyClass,REGSTR_VAL_NODISPLAYCLASS,Nil,Nil,NIl,Nil) = ERROR_SUCCESS; //查找KEY值,返回值为布尔型
        RegCloseKey(hKeyClass);
    end;
end;

function TDevForm.IsDevDisable(DevIndex: DWORD;
  hDevInfo: HDEVINFO): Boolean;
var
    DeviceInfoData: SP_DEVINFO_DATA;
    Status, Problem: DWORD;
begin
    Result:=False;
    DeviceInfoData.cbSize := SizeOf(SP_DEVINFO_DATA);

if not SetupDiEnumDeviceInfo(hDevInfo,DevIndex,@DeviceInfoData) then
      Exit;

if CM_Get_DevNode_Status(@Status, @Problem, DeviceInfoData.DevInst, 0) <> CR_SUCCESS then
      Exit;

Result:=((Status and DN_DISABLEABLE)<>0) and (CM_PROB_HARDWARE_DISABLED <> Problem);
end;

function TDevForm.ChangeDevState(DevIndex, NewState: DWORD): BOOL;  // 改变驱动器的状态
var                        //devindex : 驱动器索引  newstate : 网卡 的新状态 enable ;启用
    DeviceInfoSet: HDEVINFO;                                      // disable ;禁用
    DeviceInfoData: SP_DEVINFO_DATA;
    PropChangeParams: SP_PROPCHANGE_PARAMS;
    Cursor: HCURSOR;
begin
    Result:=False;

DeviceInfoSet:=SetupDiGetClassDevs(Nil,Nil,0,DIGCF_ALLCLASSES or DIGCF_PRESENT);  //获得当前驱动器的指针
    if DeviceInfoSet = Pointer(INVALID_HANDLE_VALUE) then
      Exit;

try
      PropChangeParams.ClassInstallHeader.cbSize:=SizeOf(SP_CLASSINSTALL_HEADER);
      DeviceInfoData.cbSize:=SizeOf(SP_DEVINFO_DATA);

Cursor := SetCursor(LoadCursor(0, IDC_WAIT));

if not SetupDiEnumDeviceInfo(DeviceInfoSet,DevIndex,@DeviceInfoData) then
        Exit;

/可以对设备进行重启,停止,启动等操作
      PropChangeParams.ClassInstallHeader.InstallFunction := DIF_PROPERTYCHANGE;
      PropChangeParams.Scope := DICS_FLAG_GLOBAL;
      PropChangeParams.StateChange := NewState;

if not SetupDiSetClassInstallParams(DeviceInfoSet,@DeviceInfoData,
          @PropChangeParams,Sizeof(PropChangeParams)) then
        Exit;

if not SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,DeviceInfoSet,
          @DeviceInfoData) then
        Exit;

SetCursor(Cursor);
      Result:=True;
    finally
      SetupDiDestroyDeviceInfoList(DeviceInfoSet);
    end;
end;

procedure TDevForm.FormCreate(Sender: TObject);
begin
    btRefresh.Click;
end;

procedure TDevForm.btExitClick(Sender: TObject);
begin
  Close;
end;

procedure TDevForm.btApplyClick(Sender: TObject);    //应用 设置
var
    i: Integer;
begin
    for i:=0 to clbDevList.Count-1 do
    begin
        if clbDevList.Checked[i] <> DevState[i] then  //网卡的新状态和原来不一致就判断网卡的新状态是否被选中
        begin
            if clbDevList.Checked[i] then
              ChangeDevState(Cardinal(clbDevList.Items.Objects[i]),DICS_ENABLE)  //启用网卡(cardinal 32位无符号数)
            else
              ChangeDevState(Cardinal(clbDevList.Items.Objects[i]),DICS_DISABLE);  //禁用网卡
        end;
    end;
    RefreshDevState;
end;

procedure TDevForm.RefreshDevState;
var
    i: Integer;
begin
    SetLength(DevState,clbDevList.Count);
    for i:=0 to clbDevList.Count-1 do
      DevState[i]:=clbDevList.Checked[i];
end;

procedure TDevForm.btRefreshClick(Sender: TObject);     //获得网卡信息并且存入 D E V S T A T E的布尔型数组里
begin
    EnumNetDevice;
    RefreshDevState;
end;

end.

转载于:https://www.cnblogs.com/MaxWoods/archive/2006/07/18/453632.html

程序读取计算机设备管理器中各设备的状态(启用/禁用)?(转自大富翁)相关推荐

  1. 设备管理器其它设备Android叹号,设备管理器中的设备显示感叹号/问号/叉号的解决方法...

    设备管理器是Windows操作系统自带的管理工具,其为用户提供了设置设备.启用/禁用设备.更新设备驱动程序等多种强大的功能,帮助用户能后更好的使用电脑的硬件设备,而部分用户在打开设备管理器时,发现部分 ...

  2. 为什么我的计算机设备管理器中找不到端口选项,Win7系统设备管理器没有端口选项的三大原因及解决措施...

    最近有朋友反应Win7系统中的设备管理器中没有端口选项,也就是COM和LPT都没有,导致一些设备无法连接,这时候该怎么办呢?如何解决Win7没有端口选项的问题?下面小编告诉大家三种导致设备管理器没有端 ...

  3. 计算机设备管理器怎么删鼠标,在电脑的设备管理器中怎么查看鼠标设备

    在电脑的设备管理器中怎么查看鼠标设备 腾讯视频/爱奇艺/优酷/外卖 充值4折起 今天给大家介绍一下在电脑的设备管理器中怎么查看鼠标设备的具体操作步骤. 1. 首先打开电脑,进入桌面,找到桌面上的此电脑 ...

  4. win10计算机设备感叹号,Win10资源管理器无法显示iphone,设备管理器中存在黄色感叹号。...

    1.现象:之前iphone 6s正常连接PC,资源管理器中有盘符,可以查看照片.突然有一天盘符无法显示,设备管理器中"其他设备"中应该是iphone的部分显示"未知设备& ...

  5. Windows设备管理器中的错误代码

    适用于: Windows 10 Pro released in July 2015,Windows 10 Enterprise released in July 2015,Windows 8 概要 本 ...

  6. 计算机管理员已禁用了teredo,Win7提示设备管理器中出现叹号设备“Teredo tunneling pseudo-interface”...

    叹号设备是告诉我们驱动没有安装了或者是驱动不兼容问题了,解决办法也非常的简单下面给各位整理了一些处理办法. 知识点分析: Teredo 是一种地址分配和主机间自动隧道技术,当 IPv6 / IPv4 ...

  7. 计算机设备管理上显示安全设备,在win10设备管理器驱动程序中显示感叹号的解决方案...

    在Windows操作系统中,我们可以通过设备管理器预测硬件是否正常工作. 那么如何在win10系统中打开"设备管理器"呢?打开驱动程序后,如果出现感叹号怎么办?下面的编辑器将介绍如 ...

  8. 设备管理器中的计算机注册表位置,电脑如何修改设备管理器里显示的名称|通过注册表修改设备名称的方法...

    ‍ 我们可以在电脑中通过设备管理器查看配置的硬件设备,以及各自的工作状态,驱动是否正常等,而里面显示的设备名称一般是不可以修改的.因为某些原因,可能会出现设备管理器里的设备出现重名的情况,因此,我们可 ...

  9. 计算机找不到网络设备,解决在设备管理器中找不到网卡的问题

    解决在设备管理器中找不到网卡的问题 |主要症状: 在设备管理中,找不到网卡,并且无法使用驱动程序向导的通用网卡版本安装驱动程序 |解决方案: 1,首先确认是否有网卡 检查计算机设备接口是否具有RJ45 ...

最新文章

  1. 开发者在行动!中国防疫开源项目登上GitHub TOP榜
  2. 独家 | 为什么大多数分析工作都以失败告终
  3. Java-Java I/O流解读之基于字节的I / O和字节流
  4. Android ListViewview入门
  5. QT的QStorageInfo类的使用
  6. 剑指offer之41-45题解
  7. ansible puppet saltstack三款自动化运维工具的对比
  8. python编程基础题答案_大学moocPython编程基础题目及答案
  9. 漫步数理统计二十八——混合分布
  10. MySQl Modify JSON Values
  11. 飞机游戏跟踪导弹的算法[C#源码]
  12. 2017.7.31.生活记录
  13. 编译原理(第3版)第1章引论课后题答案
  14. SDN为何一直热度不减?一文解析SDN的前世今生
  15. wavread被删之后的替代audioread
  16. 机器学习误差计算及评估指标
  17. 12306 验证码验证流程
  18. python实现ks算法_Python计算KS值并绘制KS曲线
  19. urllib3爬取网页源代码(爬虫)
  20. 挑战程序设计竞赛: Subsequence

热门文章

  1. 03-01 appium架构介绍与环境安装
  2. UI设计师一定要懂的专业名词
  3. 你需掌握的CSS知识都在这了(长文建议收藏,文末有福利)
  4. ECC椭圆密码算法c语言实现,深入浅出椭圆加密算法ECC
  5. 如何上好网课 — 老师录课和在线上课教学经验谈
  6. CSS(网页样式语言)基础,网页CSS设计样式基础知识点 小白教程
  7. 宅在家里写数据库中函数应用
  8. 关于Resnet50和ResNeXt50的参数量的简单计算(只考虑卷积层和全连接层)
  9. Focal Loss 分类问题 pytorch实现代码(简单实现)
  10. 【Deep Learning 四】课程一(Neural Networks and Deep Learning),第三周(Shallow neural networks)答案