You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 21:22:01