启用禁用设备

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

想要实现类似设备管理器的功能,其实也不是很难,无非就是调用一些API函数,就像本文描述的,采用的API函数就是SetupDi系列的函数。不过这类函数有很多,具体的请参见MSDN,而实现设备启用、停用仅需要用到的就只有5个函数:
       SetupDiGetClassDevs                  // 获取设备信息集
       SetupDiEnumDeviceInfo                // 从设备信息集中枚举每个设备的具体信息
       SetupDiGetDeviceRegistryProperty     // 从注册表中读取PnP设备的属性
       SetupDiSetClassInstallParams         // 设置(包括取消)设备类的安装参数
       SetupDiCallClassInstaller            // 安装指定设备
以上函数均在setupapi.h头文件中声明,该头文件包含在setupapi.lib函数库中(使用以上函数前需要声明这个头文件)。

接下来就是如何实现设备的启用与停用。
从原理上讲,设备的启用与停用其实就是对该设备进行重安装。

首先,我们需要声明两个变量用来保存指定设备类的属性信息:
    HDEVINFO       m_hDevInfo;             // 类似设备句柄,以下暂且称为设备句柄
    SP_DEVINFO_DATAm_DeviceInfoData;        // 设备详细属性信息

然后调用SetupDiGetClassDevs函数获取设备句柄的值。(在这个函数中,需要指定设备类的GUID,如果不清楚这个GUID,可以在相应的安装文件.inf中查找。注意:是设备类的GUID,不是设备的GUID!)

接着循环使用SetupDiEnumDeviceInfo函数枚举对应设备类中的设备,并使用SetupDiGetDeviceRegistryProperty函数获取得到的设备的详细信息,进行判断是否为所需的设备(判断的方式有多种,具体参考MSDN,本文采用设备描述进行判断)。
一旦枚举结束(即枚举不成功,而且用GetLastError()可以得到错误码259)即可退出循环。当然如果找到设备,即可break退出。

如果找到对应的设备,就调用SetupDiSetClassInstallParams函数设置安装的属性。这里有个注意的地方需要详细说明一下:
SetupDiSetClassInstallParams的函数原型如下:
WINSETUPAPI BOOL WINAPI
  SetupDiSetClassInstallParams(
    IN HDEVINFO  DeviceInfoSet,
    IN PSP_DEVINFO_DATA  DeviceInfoData,  OPTIONAL
    IN PSP_CLASSINSTALL_HEADER  ClassInstallParams, OPTIONAL
    IN DWORD  ClassInstallParamsSize
    );
注意第三个参数PSP_CLASSINSTALL_HEADER ClassInstallParams,
这里我们不采用这个结构,而是采用另外一个结构:SP_PROPCHANGE_PARAMS
并在这个结构中,
设置ClassInstallHeader字段中(我们发现这个字段也是一个结构,就是PSP_CLASSINSTALL_HEADER结构)的InstallFunction字段值为DIF_PROPERTYCHANGE,
设置StateChange值为DICS_ENABLE(该值为启用,若是停用则为DICS_DISABLE)
然后采用强行转换将其转为PSP_CLASSINSTALL_HEADER结构。

最后,调用SetupDiCallClassInstaller函数执行设备的安装(即:启用或者停用),注意该函数第一个参数值应为DIF_PROPERTYCHANGE。
从设备管理器中,可以验证我们的做法。  

int index = 0;

         DWORD DataType, length;

         HDEVINFO hDevInfo;

         SP_DEVINFO_DATA devInfoElem;

         TCHAR szDevDetail[SPDRP_MAXIMUM_PROPERTY][NORMAL_LEN];

         GUIDnguid{0X4D36E96F,0XE325,0X11CE,0XBF,0XC1,0X08,0X00,0X2B,0XE1,0X03,0X18 };

         hDevInfo = SetupDiGetClassDevs((LPGUID)&nguid, NULL, NULL, DIGCF_PRESENT);

 

         if (INVALID_HANDLE_VALUE != hDevInfo)

         {

                   devInfoElem.cbSize = sizeof(SP_DEVINFO_DATA);

                   while (SetupDiEnumDeviceInfo(hDevInfo, index++, &devInfoElem))

                   {

                            memset((TCHAR*)szDevDetail, 0x00, sizeof(szDevDetail) / sizeof(TCHAR));

                            SetupDiGetDeviceRegistryProperty(

                                     hDevInfo,

                                     &devInfoElem,

                                     SPDRP_DEVICEDESC,

                                     &DataType,

                                     (PBYTE)szDevDetail[SPDRP_DEVICEDESC],

                                     NORMAL_LEN,

                                     (LPDWORD)&length);

 

                            strrchr(szDevDetail[SPDRP_DEVICEDESC], _T(' '));

 

                            SetupDiGetDeviceRegistryProperty(

                                     hDevInfo,

                                     &devInfoElem,

                                     SPDRP_HARDWAREID,

                                     &DataType,

                                     (PBYTE)szDevDetail[SPDRP_HARDWAREID],

                                     NORMAL_LEN,

                                     (LPDWORD)&length);

 

                            _strlwr_s(szDevDetail[SPDRP_HARDWAREID]);

                            CString gszHardwareID_PC,gszHardwareID_Phone(szDevDetail[SPDRP_HARDWAREID]);

                           

#if 1

                            CString Outstr;

                            Outstr.Format(_T("\nAct data is %s,Act data is %s"), szDevDetail[SPDRP_DEVICEDESC], szDevDetail[SPDRP_HARDWAREID]);

                            OutputDebugString(Outstr);

#endif

                            SP_PROPCHANGE_PARAMS PropChangeParams;

                            SP_DEVINSTALL_PARAMS devParams;

                            DWORD dwResult;

 

                            //设置设备属性变化参数

                            PropChangeParams.ClassInstallHeader.cbSize= sizeof(SP_CLASSINSTALL_HEADER);

                            PropChangeParams.ClassInstallHeader.InstallFunction= DIF_PROPERTYCHANGE;

                            PropChangeParams.Scope= DICS_FLAG_GLOBAL; //使修改的属性保存在所有的硬件属性文件

                            PropChangeParams.StateChange= DICS_DISABLE;

                            PropChangeParams.HwProfile= 0;

 

                            //改变设备属性

                            if (!SetupDiSetClassInstallParams(hDevInfo,

                                     &devInfoElem,

                                     (SP_CLASSINSTALL_HEADER *)&PropChangeParams,

                                     sizeof(PropChangeParams)))

                            {

                                     dwResult =GetLastError();

                                     Outstr.Format("\nSetupDiSetClassInstallParams1FAILED, Error Code is %d", dwResult);

                                     OutputDebugString(Outstr);

                                     return;

                            }

 

                            PropChangeParams.ClassInstallHeader.cbSize= sizeof(SP_CLASSINSTALL_HEADER);

                            PropChangeParams.ClassInstallHeader.InstallFunction= DIF_PROPERTYCHANGE;

                            PropChangeParams.Scope= DICS_FLAG_CONFIGSPECIFIC;//使修改的属性保存在指定的属性文件

                            PropChangeParams.StateChange= DICS_DISABLE;

                            PropChangeParams.HwProfile= 0;

 

                            //改变设备属性并调用安装服务

                            if (!SetupDiSetClassInstallParams(hDevInfo,&devInfoElem,(SP_CLASSINSTALL_HEADER *)&PropChangeParams,sizeof(PropChangeParams)))

                            {

                                     dwResult =GetLastError();

                                     Outstr.Format("\nSetupDiSetClassInstallParams2FAILED, Error Code is %d", dwResult);

                                     OutputDebugString(Outstr);

                                     return;

                            }

                            if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, hDevInfo, &devInfoElem))

                            {

                                     dwResult =GetLastError();

                                     Outstr.Format("\nSetupDiCallClassInstallerFAILED, Error Code is %d", dwResult);

                                     OutputDebugString(Outstr);

                                     return;

                            }

                            else

                            {

                                     //判断是否需要重新启动

                                     devParams.cbSize= sizeof(devParams);

                                     if (!SetupDiGetDeviceInstallParams(hDevInfo, &devInfoElem, &devParams))

                                     {

Outstr.Format("\nSetupDiGetDeviceInstallParams, Error Code is %d", dwResult);

                                      OutputDebugString(Outstr);


                                               return;

                                     }

 

                                     if (devParams.Flags & (DI_NEEDRESTART | DI_NEEDREBOOT))

                                     {

                                               OutputDebugString("Need Restart Computer");

                                               return;

                                     }

                            }

 

                   } //while

                   SetupDiDestroyDeviceInfoList(hDevInfo);

         }

 

 

通过API实现C#对硬件的控制(二) 通过上一篇“通过API实现C#对硬件的控制(一)” 我们掌握了我们所需要的相关API知识点。为此,我们现在来构建我们自己的外部调用类:Externs。由于有上一篇的详细说明,该处不再一一说明相关的函数知识点。下面是该类的代码:using System;using System.Collections.Generic;using System.Text;using System.Runt 阅读详情

相关推荐

【C#】控制设备管理器中设备启用/禁用_20220506

通过C#代码实现设备管理器的启用/停止 引入Manamger程序集,查找到所需设备,控制启停

weixin_45475139的博客 4501

windows api 控制启用/停用网卡

通过设备启用/停用网卡,我用来控制系统中的虚拟网卡的,使用的是windows的 setupapi ,测试程序使用QT编写

C# 禁用启用设备管理器中的设备

/// <summary> /// 通过设备唯一标识PnpDeviceID,禁用设备,前提设备可被禁用 /// </summary> /// <param name="pnpDeviceId"></param> /// <returns></returns> public static bool DisableDeviceByPnpDeviceId(string pnpDeviceId) { IntPtr info = IntP

LcFireRabbit的博客 2879

修复禁用设备的方法——Windows设备恢复编程指南

综上所述,以上是一种修复在Windows中设备禁用的编程方法。通过检测设备状态并启用禁用设备,我们可以确保设备在Windows操作系统中正常工作。本文将介绍一种编程方法,帮助您恢复被禁用设备,并确保其正常运行。首先,我们需要检测设备是否被禁用。通过Windows的设备管理器可以获取设备的状态信息。这些函数将为设备发送安装参数和命令,以便将其状态更改为启用。一旦我们检测到禁用设备,我们可以使用Windows API函数。函数,我们可以启用设备并更改其状态为启用。来获取设备列表,并逐个检查设备的状态。

DevGOOD的博客 377

VC++实现启用与停用设备

前些日子在研究USB设备,就顺便研究了一些如何在应用程序实现USB设备启用与停用,然后稍微深入,于是有了本文。想要实现类似设备管理器的功能,其实也不是很难,无非就是调用一些API函数,就像本文描述的,采用的API函数就是SetupDi系列的函数。不过这类函数有很多,具体的请参见MSDN,而实现设备启用、停用仅需要用到的就只有5个函数:       SetupDiGetClassDevs   

jiangdf的专栏 6997

用SetupDi* 启用/禁用网卡

#include <windows.h> #include <tchar.h> #include <stdio.h> #include <SetupAPI.h> #include <cfgmgr32.h> // cfgmgr32.h 在Microsoft Windows 2000 DDK 中. #pragma comment(lib...

MA540213的专栏 1849

Windows平台C++ 启用禁用设备

    在windows平台上有一套SetupDi系列API可以获取所有的硬件设备,以及对其进行操作。现在我来主要说一下对指定设备启用禁用操作。 首先说明一下,我的项目是个MFC对话框程序,我自己定义了一个结构体用来存放相关的设备信息 typedef struct tagDeviceInfo { //设备友好名称,很友好…… CString szDeviceName; //设备类 ...

BruceAYG的博客 1万+

批处理禁用启用USB设备如此简单

<br />    之前大家都用devcon find获取硬件ID(Hardware ID)通过for+find筛选来禁用启用设备,但其名称不固定也没规律所以任何代码都不具有相对的通用性,我也一直以来因USB设备标准所困惑,本着不达目的誓不罢休的精神,开始寻求USB设备在Windows中的规律及USB设备标准,打开注册表编辑器开始从硬件相关的键值入手以寻找它们的相似之处及规律,最后定位到HKLM/SYSTEM/CurrentControlSet/Enum/USB,一一对比发现USB/Class_XX&Su

sfx82的专栏 1万+

python--禁用启用串口设备

python禁用并使能串口设备 最近在做一个设备,需要用到单片机的USB虚拟串口,并不是用的CH340之类的转换芯片,而是用的MCU的USB接口与电脑相连。 在调试的过程中,由于要不断的复位和上电,电脑上的串口就总是处于不可用的状态,必须将端口禁用,再启用,才能正常工作。而MCU一旦复位,电脑上又得重来一遍。所以就想着将这个动作集成到我的上位机软件中。 获得设备ID 手动获取可以通过设备管理器,在相应设备上右击,设备属性–详细信息–设备实例路径,USB\VID开头的一整串字符就是ID了。 自动获取的代码如下

深圳五月花--老李的森林 4432

android 设备管理器禁用相机,设备管理器下被禁用设备怎么重新启用

设备管理器里面可以看到电脑所有硬件的驱动安装情况以及启用/禁用状态,有些设备由于某种因素会被暂时禁用,但是过一段时间又需要启用它,有些用户刚接触电脑不久,并不清楚被禁用设备要如何重新开启,其实很简单,下面小编跟大家介绍设备管理器被禁用设备重新启用的步骤。一、xp系统下(以网卡为例):‍1、右键我的电脑--管理--设备管理器,如果设备禁用了,则设备的前面会有一个“红叉”,右击此设备也有“启用”...

weixin_39863741的博客 1465

VC++实现启用禁用设备的例子

VC++实现启用禁用设备的例子 【下载地址】VC实现启用禁用设备的例子 这是一个使用VC++编写的开源示例项目,展示了如何通过编程启用禁用USB设备。代码结构清晰,功能实用,能够帮助开发者快速掌握设备控制的基本操作。通过简单的参数修改,还可以扩展功能,实现禁用软驱和光驱等设备。该项目适合有一定VC++基础的开发者学...

gitblog_06702的博客 308

通过 xinput 禁用/启用输入设备

Table of Contents 前言 方法 通过 xinput list 查看当前的输入设备 通过 xinput --list-props 查看设备的状态 通过 xinput --set-prop 修改设备的状态 整体脚本 前言 Xorg 运行过程中,可以通过 xinput 对输入设备进行管理。这在一些情况下是很有用的,譬如手掌比较大的人,使用笔记本电脑时,可能会误触到触摸板(touchpad)。突然移动的光标让人无法专业工作,同时,还可能导致在不恰当的地方插入了字符。这是令人很烦的事情。

机房看门人的博客 3950

如何使用Windows自带的PnPUtil命令来禁用/停用和启用硬件设备

每个硬件设备在系统中都有一个唯一的标识符,称为“实例 ID”。你需要先找到目标设备的实例 ID,才能用它来执行操作。实例 ID 的格式通常类似于:操作命令示例列出所有设备查找特定设备pnputil /enum-devices | findstr /i "关键词"禁用设备pnputil /disable-device "<实例ID>"启用设备pnputil /enable-device "<实例ID>"希望这个详细的指南能帮助你成功使用PnPUtil管理硬件设备

2140

Delphi禁用启用USB设备资源文件

Delphi禁用启用USB设备资源文件 去发现同类优质开源项目:https://gitcode.com/ 文件介绍 本仓库提供的资源文件为“Delphi禁用启用USB设备.rar”,此压缩文件包含了Delphi环境下用于禁用启用USB设备的源代码及相关文档。 功能概述 此资源主要面向Delphi开发者,提供了在Delphi编程语言中实现对USB设备禁用启用的功能。开发者可以通过此代码,对系...

gitblog_06720的博客 573

win7禁用了播放设备怎么启用

win7在任务栏右边(屏幕右下角) 右键小喇叭图标-->播放设备-->右键禁用设备。 当禁用了之后再想启动发现找不到了,其实只要在对话框空白的地方右键-->显示禁用了的设备,ok,又可以看到刚才禁用设备了,再右键启用就行。 转载于:https://www.cnblogs.com/homg/archive/2013/06/03/3344997.html...

weixin_30907935的博客 566

TIA博途中启用禁用DP从站或PROFINET IO设备的具体方法

TIA博途中启用禁用DP从站或PROFINET IO设备的具体方法

Robot_PLC_HMI_Automation 4455

win下想快捷禁用启用音频设备

win下想快捷禁用启用音频设备,尝试了pnputil,devcon,最后用了soundvolumeview成功

qiaozhangchi的专栏 1455

硬件设备的监控处理之三——(USB设备禁用启用

<br />两种方法,<br />方法一 查找注册表<br /> <br /> <br />思路:首先枚举注册表路径"HKEY_LOCAL_MACHINE//Drivers//Active"下的子键,从子键中查找键项"Key"的值是否包含"Drivers//USB//ClientDrivers//Mass_Storage_Class"字段,如果包含再取该键的键项"Name"的值,获取名字devName后调用如下代码,实现禁用<br /> <br />HANDLE hnd = OpenStore(devNam

Huaerge的专栏 5160

硬件设备的监控处理之四——SD卡的禁用启用

思路:与USB设备禁用启用类似,只是关系的注册表路径不一样,原理是完全一样的 禁用: SD卡是存储设备,如果存储设备被打开其它人就没办法使用即可实现禁用效果,并且将"System//StorageManager//Profiles//SDMemory";中写入键项 MountHidden= 1,dismount掉SD卡 启用: 将"System//StorageManager//Profiles//SDMemory";中写入键项 MountHidden= 0,mountSD卡

Huaerge的专栏 4583
上一篇: Fatal Error C1902:程序数据库管理器不匹配;请检查安装 解决
GALOSS
博客等级 码龄19年 1粉丝 3原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值