当前位置: 首页 > news >正文

Qt案例 通过调用Setupapi.h库实现对设备管理器中设备默认驱动的备份

参考腾讯电脑管家-软件市场中的驱动备份专家写的一个驱动备份软件案例,学习Setupapi.h库中的函数使用.通过Setupapi.h库读取设备管理器中安装的设备获取安装的驱动列表,通过bit7z库备份驱动目录下的所有文件.

目录导读

    • 实现效果
    • 相关内容示例
      • 获取SP_DRVINFO_DETAIL_DATA结构数据
      • 相关函数
        • SetupDiBuildDriverInfoList 函数
        • SetupDiEnumDriverInfo函数
        • SetupDiGetDriverInfoDetail 函数
      • 相关实现
        • 获取所有驱动列表
        • 获取驱动SP_DRVINFO_DETAIL_DATA结构数据
        • qDebug打印输出 SP_DRVINFO_DETAIL_DATA 结构数据

实现效果

参考腾讯电脑管家-软件市场中的驱动备份专家软件
在这里插入图片描述
实现对设备管理器中的驱动信息的读取和备份:
在这里插入图片描述
其中的驱动名称,版本信息和驱动目录都是通过设备管理器的属性获取,
详情参考以下文章内容:
Qt案例 调用WINDOWS API中的SETUPAPI.H库获取设备管理器中设备的详细信息中的属性值(一)
Qt案例 调用WINDOWS API中的SETUPAPI.H库获取设备管理器中设备的详细信息中的属性值(二)
驱动备份使用bit7z调用7z.exe实现相关功能,参考:
Qt 编译使用Bit7z库接口调用7z.dll、7-Zip.dll解压压缩常用Zip、ISO9660、Wim、Esd、7z等格式文件(一)

相关内容示例

遍历设备管理器中驱动程序的相关信息:

  • 获取SP_DRVINFO_DETAIL_DATA结构数据

SP_DRVINFO_DETAIL_DATA结构包含有关特定驱动程序信息结构的详细信息。
语法

typedef struct _SP_DRVINFO_DETAIL_DATA_W {DWORD     cbSize;  //SP_DRVINFO_DETAIL_DATA结构的大小(以字节为单位)。FILETIME  InfDate; //此驱动程序的 INF 文件的日期。DWORD     CompatIDsOffset; //此值还可用于确定 CompatID 列表之前是否有 硬件 ID 。 如果此值大于 1,则 HardwareID 缓冲区中的第一个字符串是硬件 ID。 如果此值小于或等于 1,则没有硬件 ID。DWORD     CompatIDsLength; //CompatID 列表的长度(以字符为单位),从 HardwareID 缓冲区的开头偏移 CompatIDsOffset 开始。ULONG_PTR Reserved; //保留。 仅限内部使用。WCHAR     SectionName[LINE_LEN]; //一个以 NULL 结尾的字符串,包含此驱动程序的 INF DDInstall 节 的名称。 这必须是基本 DDInstall 节名称(如 InstallSec),没有任何特定于 OS/体系结构的扩展。WCHAR     InfFileName[MAX_PATH]; //一个以 NULL 结尾的字符串,其中包含此驱动程序的 INF 文件的完整限定名称。WCHAR     DrvDescription[LINE_LEN]; //一个以 NULL 结尾的字符串,用于描述驱动程序。WCHAR     HardwareID[ANYSIZE_ARRAY]; //包含 ID 列表的缓冲区 (单个 硬件 ID ,后跟 兼容 ID 列表) 。 这些 ID 对应于 INF 模型部分中的硬件 ID 和兼容 ID。列表中的每个 ID 都是以 NULL 结尾的字符串。
} SP_DRVINFO_DETAIL_DATA_W, *PSP_DRVINFO_DETAIL_DATA_W;

相关函数

  • SetupDiBuildDriverInfoList 函数

SetupDiBuildDriverInfoList 函数生成与特定设备关联的驱动程序列表,或与设备信息集的全局类驱动程序列表相关联。
语法

//! 如果成功,该函数将返回 TRUE 。 否则,它将返回 FALSE ,并且可以通过调用 GetLastError 来检索记录的错误。
WINSETUPAPI BOOL SetupDiBuildDriverInfoList([in]      HDEVINFO         DeviceInfoSet,  //设备信息设置为包含驱动程序列表的设备信息的句柄,可以是全局所有设备信息元素,也可以是专用于单个设备信息元素。 设备信息集不得包含远程设备信息元素[in, out] PSP_DEVINFO_DATA DeviceInfoData,//指向 DeviceInfoSet 中设备信息元素的SP_DEVINFO_DATA结构的指针,该元素表示要为其生成驱动程序列表的设备。 此参数是可选的,可以为 NULL。 如果指定此参数,则列表与指定的设备相关联。 如果此参数为 NULL,则列表与 DeviceInfoSet 的全局类驱动程序列表相关联。[in]      DWORD            DriverType //要生成的驱动程序列表的类型
);
  • SetupDiEnumDriverInfo函数

SetupDiEnumDriverInfo 函数枚举驱动程序列表的成员。
语法

//! 如果成功,该函数将返回 TRUE 。 否则,它将返回 FALSE ,并且可以通过调用 GetLastError 来检索记录的错误。
WINSETUPAPI BOOL SetupDiEnumDriverInfoA([in]           HDEVINFO           DeviceInfoSet, //包含要枚举的驱动程序列表 的设备信息集 的句柄。[in, optional] PSP_DEVINFO_DATA   DeviceInfoData, //指向 SP_DEVINFO_DATA 结构的指针,该结构指定 DeviceInfoSet 中的设备信息元素。 此参数是可选的,可以为 NULL。 如果指定此参数, SetupDiEnumDriverInfo 将枚举指定设备的驱动程序列表。 如果此参数为 NULL, 则 SetupDiEnumDriverInfo 枚举与 DeviceInfoSet 关联的全局类驱动程序列表, (此列表的类型为 SPDIT_CLASSDRIVER) 。[in]           DWORD              DriverType, //要枚举的驱动程序列表的类型[in]           DWORD              MemberIndex, //要检索的驱动程序信息成员的从零开始的索引。[out]          PSP_DRVINFO_DATA_A DriverInfoData //指向调用方初始化 的SP_DRVINFO_DATA 结构的指针,该结构接收有关枚举驱动程序的信息。 调用方必须设置 DriverInfoData。在调用 SetupDiEnumDriverInfo 之前,cbSize 为 sizeof ( SP_DRVINFO_DATA) 。 如果未正确设置 cbSize 成员, 则 SetupDiEnumDriverInfo 将返回 FALSE。
);
  • SetupDiGetDriverInfoDetail 函数

SetupDiGetDriverInfoDetail 函数检索设备信息集或设备信息集中特定设备信息元素的驱动程序信息详细信息。
语法

//! 如果成功,该函数将返回 TRUE 。 否则,它将返回 FALSE 
WINSETUPAPI BOOL SetupDiGetDriverInfoDetailW([in]            HDEVINFO                  DeviceInfoSet, //包含要为其检索驱动程序信息的驱动程序信息元素 的设备信息集 的句柄。[in, optional]  PSP_DEVINFO_DATA          DeviceInfoData, //指向 SP_DEVINFO_DATA 结构的指针,该结构指定表示要为其检索驱动程序信息的设备的设备信息元素。 此参数是可选的,可以为 NULL。 如果指定此参数, SetupDiGetDriverInfoDetail 将检索指定设备的驱动程序列表中有关驱动程序的信息。 如果此参数为 NULL, 则 SetupDiGetDriverInfoDetail 将检索有关作为 DeviceInfoSet 全局类驱动程序列表成员的驱动程序的信息。[in]            PSP_DRVINFO_DATA_W        DriverInfoData, //指向 SP_DRVINFO_DATA 结构的指针,该结构指定要为其检索详细信息的驱动程序信息元素。 如果指定 了 DeviceInfoData ,则驱动程序必须是 DeviceInfoData 指定的设备的驱动程序列表的成员。 否则,驱动程序必须是 DeviceInfoSet 的全局类驱动程序列表的成员。[in, out]       PSP_DRVINFO_DETAIL_DATA_W DriverInfoDetailData, //指向 SP_DRVINFO_DETAIL_DATA 结构的指针,该结构接收有关指定驱动程序的详细信息。 如果未指定此参数, DriverInfoDetailDataSize 必须为零。 如果指定此参数,则 DriverInfoDetailData。在调用 SetupDiGetDriverInfoDetail 之前,cbSize 必须设置为 size of ( SP_DRVINFO_DETAIL_DATA) 的值。[in]            DWORD                     DriverInfoDetailDataSize, //DriverInfoDetailData 缓冲区的大小(以字节为单位)。[out, optional] PDWORD                    RequiredSize //向变量的指针,该变量接收存储详细驱动程序信息所需的字节数。 此值包括结构的大小,以及包含硬件 ID 列表和兼容 ID 列表的末尾的可变长度字符缓冲区所需的其他字节。
);

相关实现

获取所有驱动列表
//! QList<CONST GUID*> GUID_DEVCLASS_LIST 设备标识
for(int t=0;t<GUID_DEVCLASS_LIST.count();t++){QString IconPath=Lib_ExtrationDrives::getInstance().GeticonPath(GUID_DEVCLASS_LIST[t]);HDEVINFO deviceInfoSet = SetupDiGetClassDevs(GUID_DEVCLASS_LIST[t], NULL, NULL, DIGCF_PRESENT);if (deviceInfoSet == INVALID_HANDLE_VALUE) {printf("Failed to get device information set. Error code: %d\n", GetLastError());return ;}SP_DEVINFO_DATA deviceInfoData;deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);for (DWORD i = 0; SetupDiEnumDeviceInfo(deviceInfoSet, i, &deviceInfoData); i++) {//SetupDiBuildDriverInfoList 函数生成与特定设备关联的驱动程序列表,或与设备信息集的全局类驱动程序列表相关联。bool ret = SetupDiBuildDriverInfoList(deviceInfoSet, &deviceInfoData, SPDIT_CLASSDRIVER);if(!ret){qDebug("Error enumerating driver info. Error code: %d\n", GetLastError());continue ;}SP_DRVINFO_DATA  rDriverInfoData;rDriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA);//SetupDiEnumDriverInfo 函数枚举驱动程序列表的成员for(int j=0;SetupDiEnumDriverInfo(deviceInfoSet, &deviceInfoData, SPDIT_CLASSDRIVER, j, &rDriverInfoData);j++){PSP_DRVINFO_DETAIL_DATA rDriverInfoDetail=new SP_DRVINFO_DETAIL_DATA() ;rDriverInfoDetail->cbSize=sizeof(SP_DRVINFO_DETAIL_DATA);if(Lib_ExtrationDrives::getInstance().GetSetupDiGetDriverInfoDetail(deviceInfoSet,&deviceInfoData, &rDriverInfoData,rDriverInfoDetail)){qDebug()<<"-----"<<i<<" - "<<j;
//                    Print_DriverInfoDetail(rDriverInfoDetail);qDebug()<<"[cbSize] :"<<rDriverInfoDetail->cbSize;qDebug()<<"[SectionName] :"<<QString::fromWCharArray(rDriverInfoDetail->SectionName);//! SetupOpenInfFile 函数打开一个 INF 文件并返回它的句柄。qDebug()<<"[InfFileName] :"<<QString::fromWCharArray(rDriverInfoDetail->InfFileName);qDebug()<<"[DrvDescription] :"<<QString::fromWCharArray(rDriverInfoDetail->DrvDescription);qDebug()<<"[CompatIDsOffset] :"<<rDriverInfoDetail->CompatIDsOffset;qDebug()<<"[CompatIDsLength] :"<<rDriverInfoDetail->CompatIDsLength;}free(rDriverInfoDetail);}}SetupDiDestroyDeviceInfoList(deviceInfoSet);}
获取驱动SP_DRVINFO_DETAIL_DATA结构数据

通过SetupDiGetDriverInfoDetail函数检索SP_DRVINFO_DETAIL_DATA包含有关特定驱动程序信息结构的详细信息,预防ERROR_INSUFFICIENT_BUFFER异常

bool Lib_ExtrationDrives::GetSetupDiGetDriverInfoDetail(HDEVINFO infoset,PSP_DEVINFO_DATA device,PSP_DRVINFO_DATA  rDriver,PSP_DRVINFO_DETAIL_DATA& rDriverInfoDetail) const
{bool isSuccess=true;DWORD needSize=0;if(!SetupDiGetDriverInfoDetail(infoset,device,rDriver,rDriverInfoDetail,sizeof(SP_DRVINFO_DETAIL_DATA),&needSize)){if((GetLastError()== ERROR_INSUFFICIENT_BUFFER)){//                qDebug()<<"cbSize : "<<rDriverInfoDetail->cbSize<<" needSize : "<<needSize;rDriverInfoDetail=(SP_DRVINFO_DETAIL_DATA*)malloc(needSize);rDriverInfoDetail->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA)  ;if (!SetupDiGetDriverInfoDetail(infoset, device, rDriver, rDriverInfoDetail, needSize, NULL)){isSuccess=false;qDebug()<<"Error getting detailed driver info . because needSize:"<<needSize;}}else{isSuccess=false;qDebug()<<"Error getting detailed driver info !";}}return isSuccess;
}
qDebug打印输出 SP_DRVINFO_DETAIL_DATA 结构数据

注:根据硬件 ID 和 兼容 ID 列表在 INF 模型部分中的指定方式, HardwareID 缓冲区可以类似于以下任何一种:

  • \0
  • <HWID>\0
  • <HWID>\0<COMPATID_1>\0…<COMPATID_N>\0\0
  • \0<COMPATID_1>\0…<>COMPATID_N\0\0
void Print_DriverInfoDetail(PSP_DRVINFO_DETAIL_DATA rDriverInfoDetail) 
{qDebug()<<"[cbSize] :"<<rDriverInfoDetail->cbSize;qDebug()<<"[SectionName] :"<<QString::fromWCharArray(rDriverInfoDetail->SectionName);//! SetupOpenInfFile 函数打开一个 INF 文件并返回它的句柄。qDebug()<<"[InfFileName] :"<<QString::fromWCharArray(rDriverInfoDetail->InfFileName);qDebug()<<"[DrvDescription] :"<<QString::fromWCharArray(rDriverInfoDetail->DrvDescription);qDebug()<<"[CompatIDsOffset] :"<<rDriverInfoDetail->CompatIDsOffset;qDebug()<<"[CompatIDsLength] :"<<rDriverInfoDetail->CompatIDsLength;// parse the hardware ID, if it existsif (rDriverInfoDetail->CompatIDsOffset > 1){// Parse for hardware ID from index 0.// This is a single NULL-terminated stringqDebug()<<"设备的硬件 id:";//            qDebug()<<QString::fromWCharArray(rDriverInfoDetail->HardwareID);wchar_t* hardwareid=new wchar_t[MAX_PATH];int col=0;for(int i=0;i<rDriverInfoDetail->CompatIDsOffset;i++){if(rDriverInfoDetail->HardwareID[i]!='\0'){hardwareid[col]=rDriverInfoDetail->HardwareID[i];col++;}else{hardwareid[col]='\0';qDebug()<<QString::fromWCharArray(hardwareid);free(hardwareid);hardwareid=new wchar_t[MAX_PATH];col=0;}}}// Parse the compatible IDs, if they existif (rDriverInfoDetail->CompatIDsLength > 0){qDebug()<<"设备的兼容 id:";// Parse for list of compatible IDs from CompatIDsOffset.// This is a double NULL-terminated list of strings (i.e. MULTI-SZ)wchar_t* compatibleid=new wchar_t[MAX_PATH];int col=0;int lengths=rDriverInfoDetail->CompatIDsOffset+rDriverInfoDetail->CompatIDsLength;for(int i=rDriverInfoDetail->CompatIDsOffset;i<lengths;i++){if(rDriverInfoDetail->HardwareID[i]!='\0'){compatibleid[col]=rDriverInfoDetail->HardwareID[i];col++;}else{compatibleid[col]='\0';qDebug()<<QString::fromWCharArray(compatibleid);free(compatibleid);if(i+1<lengths &&(rDriverInfoDetail->HardwareID[i+1]=='\0')) //结束break;compatibleid=new wchar_t[MAX_PATH];col=0;}}}qDebug()<<endl;}

相关文章:

Qt案例 通过调用Setupapi.h库实现对设备管理器中设备默认驱动的备份

参考腾讯电脑管家-软件市场中的驱动备份专家写的一个驱动备份软件案例&#xff0c;学习Setupapi.h库中的函数使用.通过Setupapi.h库读取设备管理器中安装的设备获取安装的驱动列表&#xff0c;通过bit7z库备份驱动目录下的所有文件. 目录导读 实现效果相关内容示例获取SP_DRVIN…...

如何理解JVM

JVM&#xff08;Java虚拟机&#xff09;是Java程序的运行环境&#xff0c;它是Java技术的核心组成部分之一。理解JVM涉及到以下几个方面的内容&#xff1a; 1. **虚拟机概念**&#xff1a;虚拟机是一种软件实体&#xff0c;它在物理计算机上模拟出一个计算机系统&#xff0c;使…...

第十四讲:C语言字符函数和字符串函数

目录 1. 字符分类函数 2、字符转换函数 3. strlen的使⽤和模拟实现 4. strcpy 的使⽤和模拟实现 5. strcat 的使⽤和模拟实现 6. strcmp 的使⽤和模拟实现 7. strncpy 函数的使⽤ 8. strncat 函数的使⽤ 9. strncmp函数的使⽤ 10. strstr 的使⽤和模拟实现 11. strt…...

华为海思2024春招数字芯片岗机试题(共9套)

huawei海思2024春招数字芯片岗机试题(共9套&#xff0c;有答案和解析&#xff0c;答案非官方&#xff0c;未仔细校正&#xff0c;仅供参考&#xff09;&#xff08;WX:didadidadidida313&#xff0c;加我备注&#xff1a;CSDN huawei数字题目&#xff0c;谢绝白嫖哈&#xff09…...

分类预测 | Matlab实现KPCA-IDBO-LSSVM基于核主成分分析和改进蜣螂优化算法优化最小二乘支持向量机分类预测

分类预测 | Matlab实现KPCA-IDBO-LSSVM基于核主成分分析和改进蜣螂优化算法优化最小二乘支持向量机分类预测 目录 分类预测 | Matlab实现KPCA-IDBO-LSSVM基于核主成分分析和改进蜣螂优化算法优化最小二乘支持向量机分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述…...

与机器对话:ChatGPT 和 AI 语言模型的奇妙故事

原文&#xff1a;Talking to Machines: The Fascinating Story of ChatGPT and AI Language Models 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 从 ELIZA 到 ChatGPT&#xff1a;会话式人工智能的简史 会话式人工智能是人工智能&#xff08;AI&#xff09;的一个分…...

概率论基础——拉格朗日乘数法

概率论基础——拉格朗日乘数法 概率论是机器学习和优化领域的重要基础之一&#xff0c;而拉格朗日乘数法与KKT条件是解决优化问题中约束条件的重要工具。本文将简单介绍拉格朗日乘数法的基本概念、应用以及如何用Python实现算法。 1. 基本概念 拉格朗日乘数法是一种用来求解…...

[xboard]real6410-6.2 移植kernel网络驱动

文章目录 硬件电路软件配置问题1问题2问题3问题4功能测试硬件电路 核心板,使用DM9000A [图片] 软件配置 问题1 / # / # ifconfig ifconfig: /proc/net/dev: No such file or directory ifconfig: socket: Fun...

Quarkus初探

Quarkus初探 背景安装Quarkus安装Quarkus CLI 创建Quarkus项目运行Quarkus初探代码修改一下代码 数据持久化创建PanacheEntiry写入数据读取数据 Dev Service使用外部数据库区分dev和prod 构建native应用&#xff08;依赖Graalvm&#xff09; 背景 最早是在Infoq上了解到Quarku…...

90天玩转Python-02-基础知识篇:初识Python与PyCharm

90天玩转Python系列文章目录 90天玩转Python—01—基础知识篇&#xff1a;C站最全Python标准库总结 90天玩转Python--02--基础知识篇&#xff1a;初识Python与PyCharm 90天玩转Python—03—基础知识篇&#xff1a;Python和PyCharm&#xff08;语言特点、学习方法、工具安装&…...

List操作的一些常见问题

1. Arrays.asList转换基本类型数组 在实际的业务开发中&#xff0c;我们通常会进行数组转List的操作&#xff0c;通常我们会使用Arrays.asList来进行转换&#xff0c;但是在转换基本类型的数组的时候&#xff0c;却出现转换的结果和我们想象的不一致。 import java.util.Arra…...

如何使用Java和RabbitMQ实现延迟队列?

前言 今天我们使用Java和RabbitMQ实现消息队列的延迟功能。 前期准备&#xff0c;需要安装好docker、docker-compose的运行环境。 需要安装RabbitMQ的可以看下面这篇文章。 如何使用PHP和RabbitMQ实现消息队列&#xff1f;-CSDN博客 今天讲的是依赖RabbitMQ的延迟插件实现…...

AI论文速读 | TF-LLM:基于大语言模型可解释性的交通预测

论文标题&#xff1a; Explainable Traffic Flow Prediction with Large Language Models 作者&#xff1a;Xusen Guo, Qiming Zhang, Mingxing Peng, Meixin Zhu(朱美新)*, Hao (Frank)Yang(杨昊) 机构&#xff1a;香港科技大学&#xff08;广州&#xff09;&#xff0c;约翰…...

智慧矿山视频智能监控与安全监管方案

一、行业背景 随着全球能源需求的日益增长&#xff0c;矿业行业作为国民经济的重要支柱&#xff0c;其发展日益受到广泛关注。然而&#xff0c;传统矿山管理模式的局限性逐渐显现&#xff0c;如生产安全、人员监管、风险预警等方面的问题日益突出。因此&#xff0c;智慧矿山智…...

2024春算法训练4——函数与递归题解

一、前言 感觉这次的题目都很好&#xff0c;但是E题....&#xff08;我太菜了想不到&#xff09;&#xff0c;别人的题解都上百行了&#xff0c;晕&#xff1b; 二、题解 A-[NOIP2010]数字统计_2024春算法训练4——函数与递归 (nowcoder.com) 这种题目有两种做法&#xff1a;…...

【C++】C++知识点复习

牛客cpp&#xff1a;牛客网在线编程 2024年4月10日:BC1—>BC8 BC4&#xff1a;浮点数精度保留 问题&#xff1a;不加入fixed输入0.359813&#xff0c;最后得到0.36&#xff0c;并不是强制保留0.360。这种写法会保留小数点后三位精度&#xff0c;但是最后输出会省略掉最后…...

SpringBoot+Vue,轻松实现网页版人脸登录与精准识别

目录 1、技术介绍 2、技术原理 2.1、人脸检测 ①参考模板法 ②人脸规则法 2.2、人脸跟踪 2.3、人脸比对 ①特征向量法 ②面纹模板法 识别过程 案例 一、springboot后端项目 1&#xff0c;拉取项目后&#xff0c;导入相关依赖jar包 2&#xff0c;执行sql文件夹下面…...

深入浅出 -- 系统架构之垂直架构

当业务复杂度增加、访问量逐渐增大出现高并发时&#xff0c;单体架构无法满足需求&#xff0c;可以根据业务功能对系统进行拆分&#xff0c;以提高访问效率。 垂直架构介绍 1.垂直架构一般是因为单体架构太过于庞大而进行的拆分&#xff0c;拆分后各个系统应满足独立运行互相不…...

深入浅出 -- 系统架构之微服务架构选型参考图

技术选型架构图 是一个用于展示项目中所采用的各种技术和组件之间关系的图表。 它通常包括以下几个部分&#xff1a; 1. 项目名称和描述&#xff1a;简要介绍项目的背景和目标。 2. 技术栈&#xff1a;列出项目中使用的主要技术和工具&#xff0c;如编程语言、框架、数据库…...

Java 使用 ant.jar 执行 SQL 脚本文件

Java 使用 ant.jar 执行 SQL 脚本文件&#xff0c;很简单。 在 pom.xml 中导入 ant 依赖 <dependency><groupId>org.apache.ant</groupId><artifactId>ant</artifactId><version>1.10.11</version> </dependency>sql 脚本文件…...

逻辑回归:给不确定性划界的分类大师

想象你是一名医生。面对患者的检查报告&#xff08;肿瘤大小、血液指标&#xff09;&#xff0c;你需要做出一个**决定性判断**&#xff1a;恶性还是良性&#xff1f;这种“非黑即白”的抉择&#xff0c;正是**逻辑回归&#xff08;Logistic Regression&#xff09;** 的战场&a…...

Go 语言接口详解

Go 语言接口详解 核心概念 接口定义 在 Go 语言中&#xff0c;接口是一种抽象类型&#xff0c;它定义了一组方法的集合&#xff1a; // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的&#xff1a; // 矩形结构体…...

NFT模式:数字资产确权与链游经济系统构建

NFT模式&#xff1a;数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新&#xff1a;构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议&#xff1a;基于LayerZero协议实现以太坊、Solana等公链资产互通&#xff0c;通过零知…...

QT: `long long` 类型转换为 `QString` 2025.6.5

在 Qt 中&#xff0c;将 long long 类型转换为 QString 可以通过以下两种常用方法实现&#xff1a; 方法 1&#xff1a;使用 QString::number() 直接调用 QString 的静态方法 number()&#xff0c;将数值转换为字符串&#xff1a; long long value 1234567890123456789LL; …...

Go 语言并发编程基础:无缓冲与有缓冲通道

在上一章节中&#xff0c;我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道&#xff0c;它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好&#xff0…...

JS手写代码篇----使用Promise封装AJAX请求

15、使用Promise封装AJAX请求 promise就有reject和resolve了&#xff0c;就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...

Python 实现 Web 静态服务器(HTTP 协议)

目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1&#xff09;下载安装包2&#xff09;配置环境变量3&#xff09;安装镜像4&#xff09;node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1&#xff09;使用 http-server2&#xff09;详解 …...

通过 Ansible 在 Windows 2022 上安装 IIS Web 服务器

拓扑结构 这是一个用于通过 Ansible 部署 IIS Web 服务器的实验室拓扑。 前提条件&#xff1a; 在被管理的节点上安装WinRm 准备一张自签名的证书 开放防火墙入站tcp 5985 5986端口 准备自签名证书 PS C:\Users\azureuser> $cert New-SelfSignedCertificate -DnsName &…...

DeepSeek源码深度解析 × 华为仓颉语言编程精粹——从MoE架构到全场景开发生态

前言 在人工智能技术飞速发展的今天&#xff0c;深度学习与大模型技术已成为推动行业变革的核心驱动力&#xff0c;而高效、灵活的开发工具与编程语言则为技术创新提供了重要支撑。本书以两大前沿技术领域为核心&#xff0c;系统性地呈现了两部深度技术著作的精华&#xff1a;…...

自然语言处理——文本分类

文本分类 传统机器学习方法文本表示向量空间模型 特征选择文档频率互信息信息增益&#xff08;IG&#xff09; 分类器设计贝叶斯理论&#xff1a;线性判别函数 文本分类性能评估P-R曲线ROC曲线 将文本文档或句子分类为预定义的类或类别&#xff0c; 有单标签多类别文本分类和多…...