使用SendInput开发Discord自动删除脚本二次运行异常问题
Discord SendInput自动删消息脚本二次运行异常排查与解决
问题描述
用SendInput开发的Discord自动删除消息脚本,首次运行完全正常,但二次运行时操作无响应。脚本原本逻辑是调用DelDiscordMsg执行↑、Ctrl+A、Backspace、Enter、Enter的删除序列,再用NextMsg定位下一条消息,但二次运行时这些操作全部失效。
异常原因
- 按键未完整释放:原代码中
A、Backspace、Enter等按键只发送了按下事件,未添加对应的抬起事件。系统会判定这些键一直处于按下状态,二次运行时输入队列混乱,导致操作无效。 - Sleep位置错误:
NextMsg里的Sleep放在SendInput调用之外,打断了输入序列的连续性,同时Return、Back按键也存在只按下未抬起的问题。 - 时序逻辑不合理:未给Discord足够的UI响应时间,部分操作还没被处理就发送了下一个输入事件,导致Discord无法正确识别操作序列。
修复方案
核心调整点
- 所有按键必须成对发送按下+抬起事件,避免按键“卡住”。
- 在关键操作之间插入
Sleep,给Discord足够的交互处理时间。 - 调整输入序列结构,让每个操作的事件连续发送,符合Windows输入处理逻辑。
修复后的代码
DelDiscordMsg函数
static bool DelDiscordMsg() { INPUT inputs[13] = {}; ZeroMemory(inputs, sizeof(inputs)); int idx = 0; // 选中当前消息:按下并抬起↑键 inputs[idx].type = INPUT_KEYBOARD; inputs[idx].ki.wVk = VK_UP; idx++; inputs[idx].type = INPUT_KEYBOARD; inputs[idx].ki.wVk = VK_UP; inputs[idx].ki.dwFlags = KEYEVENTF_KEYUP; idx++; // 选中消息内容:Ctrl按下 → A按下 → A抬起 → Ctrl抬起 inputs[idx].type = INPUT_KEYBOARD; inputs[idx].ki.wVk = VK_CONTROL; idx++; inputs[idx].type = INPUT_KEYBOARD; inputs[idx].ki.wVk = 'A'; idx++; inputs[idx].type = INPUT_KEYBOARD; inputs[idx].ki.wVk = 'A'; inputs[idx].ki.dwFlags = KEYEVENTF_KEYUP; idx++; inputs[idx].type = INPUT_KEYBOARD; inputs[idx].ki.wVk = VK_CONTROL; inputs[idx].ki.dwFlags = KEYEVENTF_KEYUP; idx++; // 删除消息内容:按下并抬起Backspace inputs[idx].type = INPUT_KEYBOARD; inputs[idx].ki.wVk = VK_BACK; idx++; inputs[idx].type = INPUT_KEYBOARD; inputs[idx].ki.wVk = VK_BACK; inputs[idx].ki.dwFlags = KEYEVENTF_KEYUP; idx++; // 确认删除:两次Enter(按下+抬起),每次间隔200ms给Discord响应时间 for (int i = 0; i < 2; i++) { inputs[idx].type = INPUT_KEYBOARD; inputs[idx].ki.wVk = VK_RETURN; idx++; inputs[idx].type = INPUT_KEYBOARD; inputs[idx].ki.wVk = VK_RETURN; inputs[idx].ki.dwFlags = KEYEVENTF_KEYUP; idx++; Sleep(200); } UINT uSent = SendInput(idx, inputs, sizeof(INPUT)); return uSent == idx; }
NextMsg函数
static bool NextMsg() { INPUT inputs[6] = {}; ZeroMemory(inputs, sizeof(inputs)); int idx = 0; // 退出当前输入状态:按下并抬起Enter inputs[idx].type = INPUT_KEYBOARD; inputs[idx].ki.wVk = VK_RETURN; idx++; inputs[idx].type = INPUT_KEYBOARD; inputs[idx].ki.wVk = VK_RETURN; inputs[idx].ki.dwFlags = KEYEVENTF_KEYUP; idx++; Sleep(300); // 取消可能的选中状态:按下并抬起Backspace inputs[idx].type = INPUT_KEYBOARD; inputs[idx].ki.wVk = VK_BACK; idx++; inputs[idx].type = INPUT_KEYBOARD; inputs[idx].ki.wVk = VK_BACK; inputs[idx].ki.dwFlags = KEYEVENTF_KEYUP; idx++; Sleep(300); // 选中下一条消息:按下并抬起↑键 inputs[idx].type = INPUT_KEYBOARD; inputs[idx].ki.wVk = VK_UP; idx++; inputs[idx].type = INPUT_KEYBOARD; inputs[idx].ki.wVk = VK_UP; inputs[idx].ki.dwFlags = KEYEVENTF_KEYUP; idx++; Sleep(300); UINT uSent = SendInput(idx, inputs, sizeof(INPUT)); return uSent == idx; }
优化后主函数
int main() { std::this_thread::sleep_for(std::chrono::seconds(3)); bool flag = true; // 首次定位到目标消息,失败直接退出 if (!NextMsg()) { return 1; } for (size_t i = 0; i < 5; i++) { Sleep(500); flag = DelDiscordMsg(); if (!flag) { break; } Sleep(500); if (!NextMsg()) { break; } } return 0; }
额外说明
- 延迟时间可根据系统性能和Discord响应速度调整,比如将
200ms改为300ms,确保每个操作被正确处理。 - 运行脚本前务必确保Discord窗口处于激活状态,否则
SendInput事件会发送到当前激活的其他窗口,导致操作失效。
内容的提问来源于stack exchange,提问作者GOBI
相关产品推荐
相关产品推荐

