Войти в систему на экране блокировки с имитацией нажатия клавиш с помощью 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("\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;
}

Если это не работает, то как я могу достичь своей цели?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
61
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема в том, что когда вы блокируете экран, Windows из соображений безопасности меняет, какая сессия отображается. Службы и драйверы пользовательского режима работают в сеансе 0, а первый пользователь, вошедший в систему, работает в сеансе 1. По сути, sendInput() отправляет нажатия клавиш на ваш рабочий стол, а не на экран блокировки, который работает в другом сеансе:

https://techcommunity.microsoft.com/t5/ask-the-performance-team/application-compatibility-session-0-isolation/ba-p/372361#:~:text=The%20first%20user%20on %20the,использовал%20to%20target%20ничего не подозревающих%20users.&text=In%20Windows%20Vista%2C%20Session%200, user%20run%20in%20Session%201.

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

Вы можете обойти это ограничение, творчески используя CreateProcessAsUserA() и указав используемый рабочий стол в параметре lpStartupInfo (в частности, установите lpDesktop из STARTUPINFOA). Это потребует наличия небольшой дочерней программы, единственной целью которой является разблокировка экрана, а ваш родительский процесс запускает дочерний процесс с помощью 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

В качестве более простой (и, возможно, более безопасной) альтернативы вы пробовали использовать удаленный рабочий стол?

Создание программы только для отправки ввода и присоединение ее к службе, чтобы сеанс изменился, а мое основное приложение просто перезапустило службу. Может ли это работать или сеанс блокировки экрана и сеанс служб отличаются?

kaan kaya 11.04.2023 15:09

Это сработало после борьбы с ним несколько дней. Спасибо за ответ, принято.

kaan kaya 14.04.2023 17:29

Другие вопросы по теме