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

UEFI全局按键处理咨询:替代逐个注册RegistryKeyNotify()

解决UEFI中通用按键处理的最优方案

嘿,这个问题我之前在开发UEFI应用时也踩过坑——一个个注册按键确实太繁琐了!其实不用依赖RegistryKeyNotify()的特定按键注册,我们可以用事件驱动的全局按键监听来实现,下面是两种实用方案:

方案1:基于系统文本输入协议的事件驱动监听(推荐)

这个方案利用UEFI系统表提供的EFI_SIMPLE_TEXT_INPUT_PROTOCOL(或扩展版EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL),通过事件回调实现全局按键捕获,不需要为每个按键单独注册:

具体步骤:

  1. 获取输入协议实例:直接从UEFI系统表获取默认的控制台输入协议,扩展版支持更多按键类型(如组合键、功能键):

    EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *ConInEx = NULL;
    EFI_STATUS Status = gBS->HandleProtocol(
      gST->ConsoleInHandle,
      &gEfiSimpleTextInputExProtocolGuid,
      (VOID**)&ConInEx
    );
    // 如果扩展版获取失败, fallback 到基础版
    if (EFI_ERROR(Status)) {
      // 使用 gST->ConIn 即可
    }
    
  2. 创建按键回调事件:创建一个通知事件,当有按键按下时触发回调,在回调中读取所有可用按键并处理:

    EFI_EVENT KeyEvent;
    Status = gBS->CreateEvent(
      EVT_NOTIFY_WAIT,
      TPL_CALLBACK,
      KeyPressCallback,  // 回调函数
      ConInEx,           // 传递给回调的上下文
      &KeyEvent
    );
    
  3. 实现回调函数:在回调中循环读取按键(处理堆积的按键),不管是什么按键都触发你的逻辑:

    EFI_STATUS EFIAPI KeyPressCallback(
      IN EFI_EVENT Event,
      IN VOID *Context
    ) {
      EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *ConInEx = (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL*)Context;
      EFI_KEY_DATA KeyData;
      EFI_STATUS Status;
    
      // 循环读取所有待处理的按键,避免遗漏
      while ((Status = ConInEx->ReadKeyStrokeEx(ConInEx, &KeyData)) == EFI_SUCCESS) {
        // 这里写你的通用按键处理逻辑,比如打印按键信息或触发对应操作
        HandleAnyKey(&KeyData);
      }
    
      return EFI_SUCCESS;
    }
    
  4. 等待事件触发:在主循环中使用WaitForEvent等待按键事件,让系统在空闲时处理其他任务:

    while (TRUE) {
      UINTN Index;
      gBS->WaitForEvent(1, &KeyEvent, &Index);
      // 事件触发后会自动执行回调,这里不需要额外处理
    }
    

方案2:简单轮询(适合轻量场景)

如果你的应用逻辑简单,也可以用轮询方式,虽然效率略低,但实现更快捷:

EFI_INPUT_KEY Key;
while (TRUE) {
  // 等待有按键按下
  gST->ConIn->WaitForKey(gST->ConIn);
  // 读取按键
  if (gST->ConIn->ReadKeyStroke(gST->ConIn, &Key) == EFI_SUCCESS) {
    // 处理任意按键
    HandleAnyKey(&Key);
  }
}

关键注意点

  • 处理按键堆积:一定要用循环读取按键,否则快速连续按键会导致部分按键丢失。
  • 扩展版协议优势:EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL支持读取按键的状态(如Shift/Ctrl是否按下),适合需要处理组合键的场景。
  • 资源清理:退出应用时记得关闭创建的事件,避免资源泄漏:
    gBS->CloseEvent(KeyEvent);
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:08:13