以编程方式检测鼠标和键盘是否已插入

Programmatically detect if Mouse and Keyboard are plugged in

我想知道检测鼠标或键盘是否插入计算机的最佳方法是什么?我有一个主要用于独立触摸屏的应用程序,但我想知道是否有插入的键盘不会触发拉起 windows 键盘或包含数字小键盘的表单。如果没有插入鼠标,则更改一些行为。

您可以使用 C# System.ManagementManagementObjectSearcher

这是一个示例代码。根据您的需要进行修改。

    public bool isPointingDeviceAttached()
    {
        ManagementObjectSearcher searcher = 
            new ManagementObjectSearcher("root\CIMV2", "SELECT * FROM Win32_PointingDevice");

        int devCount = 0;

        foreach (ManagementObject obj in searcher.Get()) {
            if(obj["Status"].ToString().Contains("OK")) // if device is ready
            devCount++;
        }
        return devCount>0;
    }

    public bool isKeyboardAttached()
    {
        ManagementObjectSearcher searcher = 
            new ManagementObjectSearcher("root\CIMV2", "SELECT * FROM Win32_Keyboard");

        int devCount = 0;

        foreach (ManagementObject obj in searcher.Get()) {
            if (obj["Status"].ToString().Contains("OK")) // if device is ready
                devCount++;
        }

        return devCount>0;
    }

确保添加 using System.Management; 行并在引用中添加 System.Management。 您可以根据需要使用更多 ManagementObject 属性。这是属性列表和一些其他外部引用。

Pointing device class ref. & attribute list

C#, C++ similar example

使用 VB.Net,我会使用 System.Management(不要忘记在项目 [菜单] -> 添加引用中添加此引用)ManagementObjectSearcherSystem.Linq 找到这样的解决方案,

Imports System
Imports System.Management
Imports System.Linq

Public Module Module1
    Public Sub Main()
        Console.WriteLine(HasDevice("PointingDevice"))
        Console.WriteLine(HasDevice("Keyboard"))
        Console.ReadKey()
    End Sub

    Public Function HasDevice(strtype As String)
        Dim searcher As New ManagementObjectSearcher("root\CIMV2", "SELECT * FROM Win32_" + strtype)
        Dim result = From mobj In searcher.Get()
                     Select mobj Where mobj("Status").ToString() = 0
        Return Not IsNothing(result)
    End Function    
End Module

结果

您也可以hard-coded它来避免像 TRiNE 建议的输入错误(尽管使用 C#)

Public Function HasPointingDevice()
    Dim searcher As New ManagementObjectSearcher("root\CIMV2", "SELECT * FROM Win32_PointingDevice")
    Dim result = From mobj In searcher.Get()
                 Select mobj Where mobj("Status").ToString() = 0
    Return Not IsNothing(result)
End Function

Public Function HasKeyboard()
    Dim searcher As New ManagementObjectSearcher("root\CIMV2", "SELECT * FROM Win32_Keyboard")
    Dim result = From mobj In searcher.Get()
                 Select mobj Where mobj("Status").ToString() = 0
    Return Not IsNothing(result)
End Function

然后这样称呼他们

Public Sub Main()
    Console.WriteLine(HasPointingDevice())
    Console.WriteLine(HasKeyboard())
    Console.ReadKey()
End Sub

它们会产生相同的结果

我花了几天时间解决这个问题,但没有发现任何表明键盘已分离的信息。只有当前附加的内容。这给了我一个主意!连接键盘后,我检查并列出了三个键盘设备。我取下键盘,一个消失了。现在我只是寻找 obj.tostring.contains("USB") 如果没有,我知道我的平板电脑没有连接键盘。

另外两个是 HID 和 ACPI,我猜是触摸屏和鼠标垫。

当然,其他平板电脑可能会有所不同,因此它不是一个强大的 编辑:为了清楚起见,使用之前答案的代码 foreach (ManagementObject obj in searcher.Get()) { if (obj["Status"].ToString().Contains("OK")) // if device is ready devCount++; 我使用 obj.tostring.contains("USB") 而不是 (obj["Status"]xxxx 如果平板电脑已插入,我将列出三个键盘并且所有“状态”变量报告正常。如果我在那里拔下键盘只有两个条目都具有 OK 状态,而 USB 键盘状态根本不存在。所以我只是在对象中查找 USB 字符串,如果它不存在,那么我知道它没有插入.