关于VSCode Git GPG签名开机第一次提交失败的探究
关于VSCode Git GPG签名开机第一次提交失败的探究
前言
在VSCode中配置了GPG签名后,每次开机第一次提交代码时GPG都会报错,第二次提交才能正常弹出密码输入框。这种状况我凑合用了几个月, 今天上Bing搜索了下基本上看不到有相关的文章来解决该问题。于是我就开启了长达4小时的扮演AI测试工具的工具人, 从中摸索出来一点内容。
问题现象
- 开机后第一次在VSCode中提交代码,GPG签名报错(
Git: gpg failed to sign the data) - 第二次提交就能正常弹出
pinentry-qt密码输入框 - 之后只要不重启/注销电脑,提交都是正常的


原因分析
根本原因:gpg-agent 后台守护进程没有开机自启。
- 首次提交
调用 gpg签名,gpg尝试连接gpg-agent发现未运行,会尝试启动它。但启动过程(进程创建、IPC通道建立)需要时间,导致VSCode/Git等待超时报错。 - 第二次提交:此时
gpg-agent已经被第一次失败的请求”意外”拉起来了,连接瞬间建立,故能正常弹出密码框。
Windows下的GPG4win默认不会在开机时自动启动 gpg-agent 守护进程,所以每次开机都会遇到这个问题。

(也存在VScode修改延长超时时间解决该问题的可能性, 未验证)
认识GPG的相关进程
- gpg-agent: 核心签名代理, 负责与GPG服务器交互, 签名验证等操作。(后台守护进程,需常驻)
- scdaemon: 智能卡/硬件密钥加速, 用于加速GPG操作, 提供硬件支持。(智能卡守护进程,按需启动)
- keyboxd: 密钥库缓存加速, 用于缓存密钥, 提高签名速度。(密钥库守护进程,按需启动)
- gpg-connect-agent: 与运行的 gpg-agent 通信的实用程序。
实测下来, 只需要 gpg-agent 在后台常驻就能解决这个问题, 但是 VScode中点击提交需要等1-2s才能正常弹出密码框。
如果另外两个进程( scdaemon keyboxd )也在后台常驻, 则可以大大降低弹出密码框所需的时间。
keyboxd 启动后会退出常驻, 推测是scdaemon属于按需服务。它负责与硬件(如 YubiKey)通信,当没有程序访问硬件时,它会为了节省资源而自动退出。推测归推测, 还需进一步验证。
方法目录
方法一: shell:startup目录开机自启运行vbs脚本(首选)
- 优点: 开机无感自启动(无CMD黑窗口弹出), 系统资源占用最小
- 缺点: 无
第一步: 确认GPG已被加入环境变量
Win + R 输入 CMD 回车,打开CMD窗口, 输入 where gpg 能查看到GPG的路径就说明GPG已被加入环境变量。反之需要使用完整路径调用。
C:\Users\jacksen168>where gpgC:\Program Files\GnuPG\bin\gpg.exe第二步: 在shell:startup目录创建启动脚本
Win+R输入shell:startup回车,打开启动文件夹。- 创建一个
gpg-agent.vbs文件,内容如下:
' 启动 GPG 核心后台服务全家桶(完全隐藏窗口)Set WshShell = CreateObject("Wscript.Shell")
' 1. 启动 gpg-agent(核心签名代理)WshShell.Run "gpg-connect-agent.exe /bye", 0, False' 2. 启动 scdaemon(智能卡/硬件密钥加速)' WshShell.Run "scdaemon.exe --daemon", 0, False' 3. 启动 keyboxd(密钥库缓存加速)WshShell.Run "keyboxd.exe --daemon", 0, False- 保存文件。
兼容方法: 完整路径调用启动
第一步: 确认GPG路径在何处
查找路径, 通常GPG会被安装以下的地方:
C:\Program Files (x86)\GnuPG\bin\C:\Program Files\GnuPG\bin\不在以上两个位置则需要各位凭借自身经验自行找出它的位置了, 我在此不一一展开说明。
顺着目录找过去, 一般能有这个目录就说明GPG就在这了, 随之也能见到 gpg-agent.exe ' ' scdaemon.exe ' 'keyboxd.exe 这三个可执行文件的了。
第二步: 第二步: 在shell:startup目录创建启动脚本
Win+R输入shell:startup回车,打开启动文件夹。- 创建一个
gpg-agent.vbs文件,内容如下(GpgPath为刚刚确认的GPG路径,按实际情况修改):
' 启动 GPG 核心后台服务全家桶(完全隐藏窗口)Set WshShell = CreateObject("Wscript.Shell")GpgPath = "C:\Program Files\GnuPG\bin\"
' 1. 启动 gpg-agent(核心签名代理)WshShell.Run """" & GpgPath & "gpg-connect-agent.exe"" /bye", 0, False' 2. 启动 scdaemon(智能卡/硬件密钥加速)WshShell.Run """" & GpgPath & "scdaemon.exe"" --daemon", 0, False' 3. 启动 keyboxd(密钥库缓存加速)WshShell.Run """" & GpgPath & "keyboxd.exe"" --daemon", 0, False- 保存文件。
完成, 验证是否成功
可自行重启或注销, 打开VSCode, 尝试提交代码验证。弹出密码输入框,则说明配置成功。
方法二: Windows计划任务
- 优点: 无
- 缺点: 一次只能启动一个
gpg-connect-agent, 其他两个需要再单独创建计划任务。
第一步: 确认GPG已被加入环境变量/查找GPG安装路径
Win + R, 输入 cmd 回车,打开CMD窗口, 输入 where gpg-connect-agent.exe 能查看到gpg-connect-agent.exe的路径就说明已被加入环境变量。
C:\Users\jacksen168>where gpg-connect-agent.exeC:\Program Files\GnuPG\bin\gpg-connect-agent.exe如果没有,则需要查找路径。
Win + R, 输入 cmd 回车,打开CMD窗口, 依次尝试以下命令(根据你的GPG4win版本二选一):
"C:\Program Files (x86)\GnuPG\bin\gpg-connect-agent.exe" /bye"C:\Program Files\GnuPG\bin\gpg-connect-agent.exe" /bye如果命令执行后无任何输出且直接返回新命令行,说明路径正确且进程启动成功。记住这个路径,后面要用。
如果报错”找不到文件”,去 C:\Program Files\ 目录下确认 GnuPG 或 Gpg4win 文件夹的实际名称, 再或者自行寻找。根据实际情况修正路径。
第二步:创建Windows计划任务
- 按
Win + R,输入taskschd.msc回车 - 右侧点击 “创建任务”(注意不是”创建基本任务”)
- 常规选项卡:
- 名称:
Start GPG Agent - 勾选 “仅在用户登录时运行”
- 不要勾选 “使用最高权限运行”
- 名称:
- 触发器选项卡 → 新建 → 选择 “登录时”(延迟任务10秒,避免开机卡顿)
- 操作选项卡 → 新建 → 操作选 “启动程序”:
- 程序/脚本:填入第一步验证成功的完整路径(如
C:\Program Files\GnuPG\bin\gpg-connect-agent.exe) - 参数:
/bye
- 程序/脚本:填入第一步验证成功的完整路径(如
- 条件选项卡:取消勾选”只有在计算机使用交流电源时才启动”(避免笔记本电池模式下不启动)
- 确定保存
方法三: 以任何方式的自启动 Kleopatra
- 优点: 简单
- 缺点: 开机资源占用稍大, 且启动时不能实现无感,必定弹出GUI页面
做法
- 注册表: 通过添加注册表项,将 Kleopatra 路径加入开机启动
shell:startup: 通过创建快捷方式,将 Kleopatra 放入shell:startup目录,实现开机自启。
失败路线总结
路线一: 脚本通过注册表开机自启(VBS/CMD/PS1)
做法: 创建脚本,加入注册表开机自启。
失败原因:
- 推测 会话隔离(Session 0 Isolation) ,导致脚本无法正常运行。 Windows 为了安全,将后台服务(Services)与用户交互界面(UI)进行了隔离。gpg-agent需要与你的桌面交互(弹出密码框、访问你的证书存储),但默认的计划任务或启动项可能把它丢进了没有界面的“后台沙箱”(Session 0),导致它无法弹窗或存活。
- 注册位置不正确: 能实现开机自启的注册表位置较多, 可能存在不同位置权限类的问题。我没逐一尝试, 可能就是失败的原因呢? 嘛~我也不得而知了。注册表位置大赏:
注册表:Local Machine...Run注册表:Local Machine...RunOnce注册表:Local Machine...RunOnceEx注册表:Local Machine...RunServices注册表:Local Machine...RunServicesOnce注册表:Local Machine...Policies\Explorer\Run注册表:Default_User...Run注册表:Current_User...Run注册表:Current_User...RunOnce注册表:Current_User...RunOnceEx注册表:Current_User...RunServices注册表:Current_User...RunServicesOnce注册表:Current_User...Policies\Explorer\Run路线二: Kleopatra --daemon 后台运行
做法:将 kleopatra.exe --daemon 加入开机启动, 以实现后台运行。
失败原因:
- 推测
--daemon模式在Windows下支持不完善, 因为听说 Kleopatra 是”Linux 原住民”,后来才被移植到 Windows 的, 所以--daemon模式在Windows下可能不支持。
总结
shell:startup目录开机自启运行vbs脚本, 是最简单, 且无感的解决方案。
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!