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

如何通过C#代码启用辅助功能中的Mouse Keys(鼠标键)?

解决SPI_SETMOUSEKEYS启用鼠标键无效的问题

你的代码存在几个关键问题导致设置不生效,以下是具体分析和修正方案:

问题分析

  1. 参数传递错误:SPI_SETMOUSEKEYS要求uiParam传入MOUSEKEYS结构体的cbSize值,而非重复调用Marshal.SizeOf(虽然数值一致,但不符合API规范)
  2. 内存操作不当:Marshal.StructureToPtr第三个参数设为true会尝试释放未初始化的内存,可能引发隐性错误
  3. 未保留原有配置:直接覆盖dwFlags会丢失其他鼠标键相关设置,系统可能拒绝这种强制覆盖操作
  4. 权限不足:修改系统辅助功能通常需要管理员权限,普通权限下API会静默失败

修正后的代码

using System;
using System.Runtime.InteropServices;

class Program
{
    const int SPI_GETMOUSEKEYS = 0x0036;
    const int SPI_SETMOUSEKEYS = 0x0037;
    const int SPIF_SENDCHANGE = 0x0002;
    const uint MKF_MOUSEKEYSON = 0x00000001; // 启用鼠标键的标志位

    [DllImport("user32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool SystemParametersInfo(int uiAction, uint uiParam, IntPtr pvParam, int fWinIni);

    [StructLayout(LayoutKind.Sequential)]
    public struct MOUSEKEYS
    {
        public uint cbSize;
        public uint dwFlags;
        public uint iMaxSpeed;
        public uint iTimeToMaxSpeed;
        public uint iCtrlSpeed;
        public uint dwReserved1;
        public uint dwReserved2;
    }

    static void Main()
    {
        try
        {
            if (EnableMouseKeys())
            {
                Console.WriteLine("鼠标键已成功启用");
            }
            else
            {
                int errorCode = Marshal.GetLastWin32Error();
                Console.WriteLine($"启用失败,错误码:{errorCode}");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"发生异常:{ex.Message}");
        }
    }

    public static bool EnableMouseKeys()
    {
        // 先读取当前鼠标键配置,保留原有设置
        MOUSEKEYS currentSettings = new MOUSEKEYS();
        currentSettings.cbSize = (uint)Marshal.SizeOf(typeof(MOUSEKEYS));
        IntPtr ptr = Marshal.AllocHGlobal((int)currentSettings.cbSize);
        
        try
        {
            Marshal.StructureToPtr(currentSettings, ptr, false);
            // 读取当前系统设置
            if (!SystemParametersInfo(SPI_GETMOUSEKEYS, currentSettings.cbSize, ptr, 0))
            {
                return false;
            }
            currentSettings = (MOUSEKEYS)Marshal.PtrToStructure(ptr, typeof(MOUSEKEYS));

            // 启用鼠标键(保留其他原有标志位)
            currentSettings.dwFlags |= MKF_MOUSEKEYSON;

            // 将修改后的配置写回系统
            Marshal.StructureToPtr(currentSettings, ptr, false);
            return SystemParametersInfo(SPI_SETMOUSEKEYS, currentSettings.cbSize, ptr, SPIF_SENDCHANGE);
        }
        finally
        {
            // 释放内存,避免泄漏
            Marshal.FreeHGlobal(ptr);
        }
    }
}

注意事项

  • 必须以管理员身份运行程序:右键程序选择「以管理员身份运行」,否则会因权限不足导致设置失败(错误码通常为5)
  • 检查错误码:调用Marshal.GetLastWin32Error()可获取具体失败原因,便于排查问题
  • 保留原有配置:基于当前系统设置修改标志位,而非直接覆盖,避免破坏其他鼠标键相关功能

内容的提问来源于stack exchange,提问作者Pedro Hunhoff

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 14:03:19