如何通过OSHI获取主显卡?多显卡识别异常问题咨询
问题
我正在使用OSHI将设备信息写入游戏日志,但调用new SystemInfo().getHardware().getGraphicsCards()会返回所有显卡。实际我仅配备Intel(R) HD Graphics 4000核显与NVIDIA GeForce GT 640独显,却识别出4个显卡。我已知自己的主显卡为NVIDIA GeForce GT 640,但需要通用方法获取其他用户的主显卡,而非依赖已知信息。
可复现问题的MRE代码:
import java.util.List; import oshi.SystemInfo; import oshi.hardware.GraphicsCard; public class Main { public static void main(String[] args) { List<GraphicsCard> graphcisCards = new SystemInfo().getHardware().getGraphicsCards(); int graphicsCardNumber = 1; for(GraphicsCard graphicsCard : graphcisCards) { System.out.println("Graphics Card " + graphicsCardNumber + ":\n" + format(graphicsCard)); graphicsCardNumber++; } } private static String format(GraphicsCard graphicsCard) { double memoryAsGB = graphicsCard.getVRam() / 1073741824; String string = ""; string += " Graphics Card Name:" + graphicsCard.getName() + ", " + graphicsCard.getDeviceId() + "\n"; string += " Graphics Card Vendor: " + graphicsCard.getVendor() + "\n"; string += " Graphics Card VRAM: " + memoryAsGB + " GB\n"; string += " Graphics Card Version Info: " + graphicsCard.getVersionInfo() + "\n"; return string; } }
解答
为什么识别出额外的显卡?
OSHI通过读取系统底层硬件信息枚举显卡,出现4个条目主要有这些原因:
- 核显的多输出逻辑设备:Intel核显会为每个物理显示接口(比如HDMI、VGA、DP)创建独立的逻辑设备,系统层面会将其识别为多个显卡实例。
- 双显卡切换的虚拟设备:带NVIDIA Optimus或AMD Switchable Graphics的设备,驱动会创建虚拟中间设备负责显卡切换,这类虚拟设备也会被OSHI统计到列表中。
- 驱动拆分的功能组件:显卡驱动可能会把视频解码、3D渲染等功能拆分为独立的逻辑设备,这些组件也会被当作显卡条目返回。
如何通用获取主显卡?
没有跨平台的绝对统一方案,但可以结合以下策略实现通用判断:
1. 按显存大小筛选
通常主显卡(独显)的显存远大于核显,直接取显存最大的显卡是最通用的兜底方案:
public static GraphicsCard getPrimaryGraphicsCard(List<GraphicsCard> cards) { if (cards == null || cards.isEmpty()) return null; return cards.stream() .max((card1, card2) -> Long.compare(card1.getVRam(), card2.getVRam())) .orElse(null); }
2. 结合厂商和设备名称过滤
根据主流显卡厂商的命名规则,优先筛选非虚拟的独显或高性能核显:
public static GraphicsCard getPrimaryGraphicsCard(List<GraphicsCard> cards) { if (cards == null || cards.isEmpty()) return null; // 优先匹配主流独显或高性能核显的命名 for (GraphicsCard card : cards) { String cardName = card.getName().toLowerCase(); // 匹配NVIDIA GeForce、AMD Radeon、Intel Iris系列 boolean isMainCard = cardName.contains("nvidia") && cardName.contains("geforce") || cardName.contains("amd") && cardName.contains("radeon") || cardName.contains("intel") && cardName.contains("iris"); // 排除虚拟设备(名称通常带virtual、display adapter等关键词) boolean isNotVirtual = !cardName.contains("virtual") && !cardName.contains("display adapter"); if (isMainCard && isNotVirtual) { return card; } } // 兜底返回显存最大的显卡 return cards.stream() .max((card1, card2) -> Long.compare(card1.getVRam(), card2.getVRam())) .orElse(null); }
3. Windows平台结合WMI查询主显卡
在Windows系统中,可以通过WMI查询系统标记的主显示适配器,再和OSHI的结果匹配:
// 示例:通过WMI获取主显卡的DeviceID,再匹配OSHI的显卡列表 public static String getPrimaryDeviceIdViaWmi() { try { // 执行WMI查询,筛选PrimaryAdapter为TRUE的显卡设备ID String wmiQuery = "SELECT DeviceID FROM Win32_VideoController WHERE PrimaryAdapter = TRUE"; // 这里需要引入JNA或WMI相关库实现查询逻辑,例如使用com4j或JNA的WMI绑定 // 示例返回查询到的DeviceID字符串 } catch (Exception e) { e.printStackTrace(); } return null; }
拿到DeviceID后,遍历OSHI返回的显卡列表,找到对应DeviceID的显卡即可确定为主显卡。
内容的提问来源于stack exchange,提问作者user23787503
相关产品推荐
相关产品推荐

