论坛首页 AI安全讨论区 阅读主题

[原创]如何让Apollo(Sunshine)串流时自动“熄屏”,屏蔽物理键鼠;串流结束后自动锁屏

104 浏览 0 回复
#1 楼主 2026-06-01 21:08:59
如何让Sunshine串流时自动“熄屏”,屏蔽物理键鼠;串流结束后自动锁屏

前言
远程串流搞完了,觉得串流时电脑键鼠仍然有输入,屏幕亮着,结束后不会锁屏不安全(也不想让别人看见)。于是自己搜,再把要求给AI写了一些东西。经过实际测试使用是没有问题的。

说明
屏蔽键鼠使用C#​程序,屏蔽物理键盘/鼠标/触控板​输入,客户端串流设备的键盘/鼠标/触控板​可以操作电脑。如果需要应急解除屏蔽,快速按3次esc。
使用的是Sunshine的改版Apollo,原版Sunshine未经过测试。如需要安装Apollo,需要先卸载Sunshine,重启后再安装。

==声明==
==以下程序或脚本均由AI生成,如果使用过程中造成财产损失,本人概不负责。==


编译C#程序
主程序
​input-blocker.cs
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;

class InputBlocker {
// ── Win32 imports ──────────────────────────────
const int WH_KEYBOARD_LL = 13;
const int WH_MOUSE_LL = 14;
const uint LLKHF_INJECTED = 0x10;
const uint LLMHF_INJECTED = 0x01;
const uint PM_REMOVE = 1;
const int VK_ESCAPE = 0x1B;

delegate IntPtr LowLevelHookProc(int nCode, IntPtr wParam, IntPtr lParam);

[DllImport("user32.dll")]
static extern IntPtr SetWindowsHookEx(int idHook, LowLevelHookProc lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll")]
static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll")]
static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll")]
static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport("user32.dll")]
static extern bool PeekMessage(out MSG msg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax, uint wRemoveMsg);
[DllImport("user32.dll")]
static extern bool TranslateMessage(ref MSG msg);
[DllImport("user32.dll")]
static extern IntPtr DispatchMessage(ref MSG msg);

[StructLayout(LayoutKind.Sequential)]
struct MSG {
public IntPtr hwnd;
public uint message;
public IntPtr wParam;
public IntPtr lParam;
public uint time;
public int pt_x;
public int pt_y;

// ── 静态字段 ───────────────────────────────────
static LowLevelHookProc kbdProc;
static LowLevelHookProc mouseProc;
static IntPtr hHookKbd = IntPtr.Zero;
static IntPtr hHookMouse = IntPtr.Zero;
static EventWaitHandle stopEvent;

// ── 紧急逃生:连按 3 次 Esc(1.5 秒内)→ 解除 ──
static int escCount = 0;
static Stopwatch escWatch = Stopwatch.StartNew();
static long lastEscMs = 0;

// ── 拦截判定:是否为物理按键按下事件 ──
static bool IsPhysicalKeyDown(IntPtr wParam, IntPtr lParam, out int vkCode) {
int msg = (int)wParam;
// WM_KEYDOWN=0x0100, WM_SYSKEYDOWN=0x0104
if (msg != 0x0100 && msg != 0x0104) {
vkCode = 0;
return false;
uint flags = (uint)Marshal.ReadInt32(lParam, 8);
vkCode = Marshal.ReadInt32(lParam, 0);
return (flags & LLKHF_INJECTED) == 0;

// ── 钩子回调 ───────────────────────────────────
static IntPtr KbdHook(int nCode, IntPtr wParam, IntPtr lParam) {
if (nCode >= 0) {
int vkCode;
if (!IsPhysicalKeyDown(wParam, lParam, out vkCode))
return CallNextHookEx(IntPtr.Zero, nCode, wParam, lParam);

long now = escWatch.ElapsedMilliseconds;

if (vkCode == VK_ESCAPE) {
if (now - lastEscMs

...(已截断)

---
来源: 看雪论坛
原文链接: https://bbs.kanxue.com/thread-291295.htm

暂无回复,快来抢沙发吧!

请登录后参与讨论

立即登录 注册账号