Windows: the ability to end a session if the screen is locked
Task
You must be able to end the session of another user who has locked the screen in order to log in, provided that:
- the screen locks automatically after some time
- you are not a system administrator
- there is no way to use “fast user switching”
- you cannot use automatic session termination by time
A It is also desirable:
- to avoid the appearance of a black console window in the implementation
Decision
I will not bore you with stories about what solutions have been tried and how many crutches had to be broken, but a solution was found. In solving such problems, it is best to do with scripts, but this is not always possible, as it was not possible this time. The fact is that in order to solve the indicated problem it was necessary to run the script as a screensaver, but the script cannot be installed on the screensaver. To solve this problem, we will use a small code in C, which, in turn, runs a script in 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
How to use it
- We collect the C code in the winexec.scr file to be run using mingw
Ubuntu: Archlinux: - We put winexec.scr, winexec.cfg and winexec.vbs in the% WINDIR% directory - Configure the screensaver (using group policies - gpedit.msc - you can configure the screensaver for all users of the system in a single way)
i586-mingw32msvc-gcc -mwindows -s winexec.cpp -o winexec.scr -lshlwapi
i486-mingw32-gcc -mwindows -s winexec.cpp -o winexec.scr -lshlwapi
How it works
- By timeout, the screen is locked and winexec.scr is launched, which reads winexec.cfg (winexec.cfg contains the parameters for launching a vbs script)
- Next, a vbs-script is run with the question "end the session?" Pressing the “No” button will display a lock window in which you can enter a password. Clicking Yes will end the session and allow you to log in as another user.
- Despite the fact that the shutdown console command is launched from the vbs script, the cmd black window does not appear (this is achieved by the CREATE_NO_WINDOW parameter when creating the process in C code)
Comments
- winexec.scr can be used not only to run a logout script, but also for any other program (or script) that you want to run instead of a screen saver