Я хочу использовать функцию 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("\r\n")[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://learn.microsoft.com/en-us/previous-versions/bb756986(v=msdn.10)
Вы можете обойти это ограничение, творчески используя CreateProcessAsUserA()
и указав используемый рабочий стол в параметре lpStartupInfo
(в частности, установите lpDesktop
из STARTUPINFOA
). Это потребует наличия небольшой дочерней программы, единственной целью которой является разблокировка экрана, а ваш родительский процесс запускает дочерний процесс с помощью CreateProcessAsUserA()
.
В качестве более простой (и, возможно, более безопасной) альтернативы вы пробовали использовать удаленный рабочий стол?
Это сработало после борьбы с ним несколько дней. Спасибо за ответ, принято.
Создание программы только для отправки ввода и присоединение ее к службе, чтобы сеанс изменился, а мое основное приложение просто перезапустило службу. Может ли это работать или сеанс блокировки экрана и сеанс служб отличаются?