背景
实现一个获取显卡品牌的接口,由于对硬件不够了解,兜兜转转搞了好几天。刚开始直接从WMI 的 Win32_VideoController 取 AdapterCompatibility 字段数据,后来发现哪个是显卡芯片品牌,不是显卡制作商品牌,只能再从网上去找资料。
期间有人说这个技术是商业机密,不能透露实现方式,还有人报价3000帮我处理这个问题。额,价格太高,网上也到处找不到相关的资料,而且我还尝试了 DX,CUDA,MMIO,等技术都没有成功。令我一度以为这个确实是很有深度的技术。
后来兜兜转转,同事在网上发现了 lspci 这个项目,粗略阅读代码后才发现,其实显卡的制作商,早已包含在硬件ID中,从WMI 就能取到,只是它展示的方式十分隐晦,不容易被发现。
这个问题纠缠了我好几天,网上资料少之又少,所以这里记录一下实现方案,方便一些迷路的同学。
显卡常识
显卡的品牌(即厂商),如果是集成显卡的话,它只有一个品牌,那就是显卡芯片的品牌。显卡芯片有N卡(NVIDIA) 和 A卡(AMD)两种。 一些加工商(比如七彩虹,影驰)拿到这些芯片后,会再加工成独立显卡,这个时候显卡的品牌变成了两个,一个是显卡芯片品牌,一个是加工商品牌。而我实际上要拿的,是显卡加工商的品牌。
而且我们常说的显卡型号,其实说的是显卡芯片的型号,下载的驱动程序,也是根据显卡芯片型号去匹配的,并不是加工商提供的。
实现理论
前面说到过,显卡的加工商,早就包含在硬件ID中,让我们来看看它是怎样展示的:
我的电脑- >> 管理 >> 设备管理器 >> 显示适配器 >> (选中一个子节点右击)属性
弹出的窗口选【详细信息】标签 >> 在从属性中选择 【硬件id】节点
这个我的电脑截图,以硬件 ID 第一行为例,即
#格式规范 : PCI\VEN_xxxx&DEV_xxxx&SUBSYS_xxxxxxxx
PCI\VEN_10DE&DEV_128B&SUBSYS_C30819DA&REV_A1
加工商的信息便放置在里面。
当字符串中存在【SUBSYS】时,下划线后面必然有8位十六进制的数字(这是规范,好比VEN后面有4位,DEV后面也是4位,另外VEN是芯片品牌的id)。
这里我的【SUBSYS】值是【C30819DA】,我们取后面4位,即数字低16位,即【19DA】,便是加工商的ID。
独立显卡内部,只有加工商的ID,是没有加工商的名字,你只能自己建一个字典,根据ID来匹配出加工商的名称。如果你找不到 【SUBSYS】这个字眼,说明你的显卡不是独立显卡。其他一些PCI 硬件的厂商,也可以通过这种方式找出来。
字典怎么来
现在厂商编号有了,对应的厂商名称怎么知道呢?
其实厂商的编号并不是乱来的,正规的厂家,应到PCI-SIG的官网中进行缴费注册,由PCI-SIG协会分配给你一个编号。我们可以从PCI-SIG的官网中,找到对应的厂商名字。
PCI-SIG会员查找网页点这里 (https://pcisig.com/membership/member-companies)
我的显卡厂商编号十六进制是【19DA】(zotac-索泰),在这个网上搜素【Search】不到,不知道是不是杂牌,但是华硕,技嘉这些大牌子确实通通都有。有需要的同学可以写个爬虫把网页上的数据爬下来做字典。我这边只需要对一两个厂商做针对性处理,所以自己做了一个简单的处理,没有爬字典。
另外大家也可以使用 lspci 这个项目提供的 ids文件作为你的字典,不过文本解析可能有点麻烦。因为我也只是看了半天的代码,所以不知道方便不,这里只能给大家提供一下相关地址。
这里贴一些 lspci 的 ids 文件地址: https://pci-ids.ucw.cz/
再贴一下 lspci 项目地址: https://github.com/pciutils/pciutils
实现代码
到这里,有些同学脑海里面已经想到代码怎么实现了,因为知道了理论,实现真的相当简单!所以demo我就不写了,这里主要告诉大家这些数据哪里有。
其实只要用 WMI 到 Win32_VideoController 取 【PNPDeviceID】字段便是硬件id 的字符串。另外Win32_PnPEntity 这表中也有个 【DeviceID】和【PNPDeviceID】字段(Win32_PnPEntity 表我没试过,大家可以试试)。
既然硬件id字段已经取到了,字典也有了,剩下的东西大家肯定可以自己实现了吧。