Как стать автором
Обновить

Windows: возможность завершить сеанс если экран заблокирован

Время на прочтение3 мин
Количество просмотров4.6K

Задача


Необходимо иметь возможность завершить сеанс другого пользователя заблокировавшего экран, чтобы войти под своим, при условии что:
— экран блокируется автоматически по истечении некоторого времени
— вы не администратор системы
— нет возможности использовать «быстрое переключение пользователей»
— нельзя использовать автоматическое завершение сеанса по времени

А так же желательно:
— избежать появления чёрного консольного окошка в реализации



Решение


Не буду утомлять вас рассказами о том какие решения были испробованы и сколько костылей пришлось поломать, но решение таки было найдено. В решении таких задач лучше всего обходиться скриптами, но не всегда это удаётся, как и не удалось на этот раз. Дело в том, что для решения обозначенной задачи необходимо было запускать скрипт как заставку, но скрипт на заставку поставить нельзя. Для решения этой проблемы воспользуемся небольшим кодом на C, который, в свою очередь, запускает скрипт на vbs.

winexec.cpp

#include "stdio.h"
#include "shlwapi.h"

void RemoveNewLine (char* str)
{
    char* pos = strrchr(str,'\n');
    if (pos) *pos = '\0';
}

int main(int argc, char *argv[]) {

    // Get command line argument
    if (argc < 2) return 0;
    if (stricmp(argv[1],"/s")) return 0;

    // Init vars
    char config_file[MAX_PATH] = "";
    char command[MAX_PATH] = "";
    char args[MAX_PATH] = "";

    // Get own path and set config_file
    GetModuleFileName (NULL,config_file,MAX_PATH);
    PathRemoveExtension (config_file);
    strcat (config_file,".cfg");

    // Read config file
    FILE* file = fopen (config_file,"r") ;
    if (file == NULL) {
        MessageBox (NULL,"Error opening config file",NULL,0);
        return 1;
    }
    fgets (command,MAX_PATH,file); RemoveNewLine (command);
    fgets (args,MAX_PATH,file); RemoveNewLine (args);

    // Run process
    PROCESS_INFORMATION processInformation;
    STARTUPINFO startupInfo;
    memset ( &processInformation,0,sizeof (processInformation) );
    memset ( &startupInfo,0,sizeof (startupInfo) );
    if ( !CreateProcess (command,args,NULL,NULL,0,CREATE_NO_WINDOW,NULL,NULL,&startupInfo,&processInformation) ) {
        MessageBox (NULL,"ERROR: Create Process failed!",NULL,0);
        return 1;
    }

    // Wait until child process exits.
    WaitForSingleObject (processInformation.hProcess,INFINITE);

    // Close process and thread handles. 
    CloseHandle (processInformation.hProcess);
    CloseHandle (processInformation.hThread);
}

winexec.cfg

c:\windows\system32\cscript.exe
cscript.exe c:\windows\winexec.vbs


winexec.vbs

'Create common objects
Set WshShell = CreateObject("WScript.Shell")
Set WshNetwork = CreateObject("WScript.NetWork")

'Set common variables
username = WshNetwork.UserName
title = "Завершение сеанса пользователя" & " " & username
text = "Желаете выйти из системы?"

'Run logout dialog
Button = WshShell.Popup(text,,title,36)

'Check answer
If Button <> 6 Then Wscript.Quit

'Force logoff if "Yes"
WshShell.Run "shutdown.exe -l",,true


Как это использовать



— Собираем код C в запускаемый файл winexec.scr используя mingw
Ubuntu: i586-mingw32msvc-gcc -mwindows -s winexec.cpp -o winexec.scr -lshlwapi
Archlinux: i486-mingw32-gcc -mwindows -s winexec.cpp -o winexec.scr -lshlwapi
— Помещаем winexec.scr, winexec.cfg и winexec.vbs в директорию %WINDIR%
— Настраиваем заставку (используя групповые политики — gpedit.msc — можно настроить заставку для всех пользователей системы единым образом)


Как это работает


— По таймауту блокируется экран и запускается winexec.scr, который считывает winexec.cfg (winexec.cfg содержит параметры запуска vbs скрипта)
— Следом запускается vbs-скрипт с вопросом «завершить сеанс?». Нажатие кнопки «Нет» приведёт к появлению окна блокировки, в котором можно ввести пароль. Нажадие «Да» завершит сеанс и позволит войти под другим пользователем.
— Несмотря на то, что из vbs-скрипта запускается консольная команда shutdown, чёрного окна cmd не появляется (это достигается параметром CREATE_NO_WINDOW при создании процесса в коде C)

Комментарии


— winexec.scr можно использовать не только для запуска logout-скрипта, но и для любой другой программы (или скрипта), которую вы хотите запускать вместо экранной заставки
Теги:
Хабы:
Если эта публикация вас вдохновила и вы хотите поддержать автора — не стесняйтесь нажать на кнопку
Всего голосов 15: ↑9 и ↓6+3
Комментарии16

Публикации

Истории

Работа

Ближайшие события