登录用户在锁定屏幕模拟按键使用SendInput?



我想使用SendInput()函数登录到我的帐户,就像我亲自做的那样;按回车键,按密码键,再按回车键。

这样做的目的是我写了一个远程连接程序,我可以得到屏幕截图来检查是否一切正常。该程序以任务调度程序开始,所以当我的电脑重启时,我仍然可以发送命令并获得屏幕截图。但是我想添加一个远程登录选项,所以如果我的电脑重启,我可以远程发送信号登录。

它在桌面中工作,但当我用win+L锁定我的用户时,它在锁定屏幕中没有做任何事情,当我登录检查桌面时。

下面是代码

void sendPassword(){
//Map to store keys as char-WORD
QMap<QString, WORD> keyMap;
keyMap["Enter"] = 0x0D;

keyMap["0"] = 0x30;    keyMap["1"] = 0x31;    keyMap["2"] = 0x32;    keyMap["3"] = 0x33;
keyMap["4"] = 0x34;    keyMap["5"] = 0x35;    keyMap["6"] = 0x36;    keyMap["7"] = 0x37;
keyMap["8"] = 0x38;    keyMap["9"] = 0x39;

keyMap["A"] = 0x41;    keyMap["B"] = 0x42;    keyMap["C"] = 0x43;    keyMap["D"] = 0x44;
keyMap["E"] = 0x45;    keyMap["F"] = 0x46;    keyMap["G"] = 0x47;    keyMap["H"] = 0x48;
keyMap["I"] = 0x49;    keyMap["J"] = 0x4A;    keyMap["K"] = 0x4B;    keyMap["L"] = 0x4C;
keyMap["M"] = 0x4D;    keyMap["N"] = 0x4E;    keyMap["O"] = 0x4F;    keyMap["P"] = 0x50;
keyMap["Q"] = 0x51;    keyMap["R"] = 0x52;    keyMap["S"] = 0x53;    keyMap["T"] = 0x54;
keyMap["U"] = 0x55;    keyMap["V"] = 0x56;    keyMap["W"] = 0x57;    keyMap["X"] = 0x58;
keyMap["Y"] = 0x59;    keyMap["Z"] = 0x5A;
//Get password from file.
QFile passFile("password.txt");
passFile.open(QIODevice::ReadOnly);
QString password = QString::fromUtf8(passFile.readAll()).split("rn")[0].split("n")[0];
passFile.close();
//Initialize inputs array.
INPUT* inputs = new INPUT[password.length()*2+4] {};
//Add enter button to inputs array, key down and up.
inputs[0].type = INPUT_KEYBOARD;
inputs[0].ki.wVk = keyMap["Enter"];
inputs[1].type = INPUT_KEYBOARD;
inputs[1].ki.wVk = keyMap["Enter"];
inputs[1].ki.dwFlags = KEYEVENTF_KEYUP;

for(int i=0; i<password.length(); i++){

//Add password to inputs array char by char, key down and up.
inputs[i*2+2].type = INPUT_KEYBOARD;
inputs[i*2+2].ki.wVk = keyMap[(QString)password[i]];
inputs[i*2+3].type = INPUT_KEYBOARD;
inputs[i*2+3].ki.wVk = keyMap[(QString)password[i]];
inputs[i*2+3].ki.dwFlags = KEYEVENTF_KEYUP;
}
//Add enter button to inputs array, key down and up.
inputs[password.length()*2+2].type = INPUT_KEYBOARD;
inputs[password.length()*2+2].ki.wVk = keyMap["Enter"];
inputs[password.length()*2+3].type = INPUT_KEYBOARD;
inputs[password.length()*2+3].ki.wVk = keyMap["Enter"];
inputs[password.length()*2+3].ki.dwFlags = KEYEVENTF_KEYUP;

//SendInput, send inputs array.
SendInput(password.length()*2+4, inputs, sizeof(INPUT));
//Delete inputs array.
delete[] inputs;
}

如果这没有办法工作,那么我怎么能达到我的目的?

问题是,当您锁定屏幕时,出于安全原因,Windows会更改显示的会话。用户模式服务和驱动程序在会话0中运行,第一个登录的用户在会话1中运行。本质上,sendInput()是发送击键到你的桌面,而不是锁屏,锁屏在另一个会话中运行:

https://techcommunity.microsoft.com/t5/ask-the-performance-team/application-compatibility-session-0-isolation/ba-p/372361: ~:文本= % 20第一% 20用户% 20 % 20,使用% 20 % 20目标% 20毫无戒心的% 20用户。amp;文本= % 20 windows vista % 20 200年% % 2 c % 20会议,用户% 20运行% 20 201年% % 20会议。

https://learn.microsoft.com/en-us/previous-versions/bb756986 (v = msdn.10)

您可以创造性地使用CreateProcessAsUserA()并在lpStartupInfo参数中指定要使用的桌面来解决这个限制(具体来说,设置STARTUPINFOAlpDesktop)。这将涉及到一个小的子程序,它的唯一目的是解锁屏幕,并让你的父进程运行CreateProcessAsUserA()的子进程。

https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessasusera

https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/ns-processthreadsapi-startupinfoa

作为一个更简单(也可能更安全)的选择,你试过使用远程桌面吗?

最新更新