Alternative way to check for screen presence CTRL + ALT + DEL

I am currently using the below code to check if the screen is displayed CTRL+ ALT+ DELand it works as expected. The problem is that polling this information requires a CPU and I'm looking for an event based option. Does anyone know of another way to determine if this screen is displayed?

I only need to know when this screen is closed. I don't care when it opens. It's just that it was open and is now closed.

To be honest, I found this code and I'm not entirely sure how specific, if at all, it is on the screen I'm talking about. It seems to be looking for process creation and deletion events. This means that this screen should open a new process. Knowing this process name will also be helpful.

var interval = new TimeSpan(0, 0, 3);
const string isWin32Process = "TargetInstance isa \"Win32_Process\"";

// Listen for started processes.
WqlEventQuery startQuery = new WqlEventQuery("__InstanceCreationEvent", interval, isWin32Process);
var _startWatcher = new ManagementEventWatcher(startQuery);
_startWatcher.Start();
_startWatcher.EventArrived += OnStartEventArrived;

// Listen for closed processes.
WqlEventQuery stopQuery = new WqlEventQuery("__InstanceDeletionEvent", interval, isWin32Process);
var _stopWatcher = new ManagementEventWatcher(stopQuery);
_stopWatcher.Start();
_stopWatcher.EventArrived += OnStopEventArrived;

      

What is the name of this screen? And how can I detect this type of window? It looks like the same type as the login window.

enter image description here

+3


source to share


2 answers


When you press CTRL+ ALT+ DEL, Windows switches to another dedicated virtual desktop a that hosts the process winlogon

that is responsible for user login / logout / locking, etc. actions. Using a WinAPI function SetWinEventHook

with EVENT_SYSTEM_DESKTOPSWITCH

, you can set up a callback function that gets called whenever a desktop switch like this occurs:

//Store the callback in a variable so that it is not GC'd private static 
private static readonly WinEventDelegate callback = EventCallback;
static void StartListeningForDesktopSwitch()
{
    SetWinEventHook(EVENT_SYSTEM_DESKTOPSWITCH, EVENT_SYSTEM_DESKTOPSWITCH,
        IntPtr.Zero, callback, 0, 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNTHREAD);
}

static void EventCallback(IntPtr hWinEventHook, uint eventType,
       IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
{
    Console.WriteLine("Desktop switched");
}

      

Note. ... If you want to use this in a console application, you need to add a message loop by adding a hidden one Form

:

static void Main(string[] args)
{        
    StartListeningForDesktopSwitch(); 

    // Run message loop
    Application.Run(new HiddenForm());
}

private class HiddenForm : Form
{
    public HiddenForm()
    {
        this.FormBorderStyle = FormBorderStyle.None;
        this.WindowState = FormWindowState.Minimized;
        this.ShowInTaskbar = false;
    }
}

delegate void WinEventDelegate(IntPtr hWinEventHook, uint eventType,
    IntPtr hwnd, int idObject, int idChild, uint dwEventThread,
    uint dwmsEventTime);

[DllImport("user32.dll")]
static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr
    hmodWinEventProc, WinEventDelegate lpfnWinEventProc, uint idProcess,
    uint idThread, uint dwFlags);

const uint WINEVENT_OUTOFCONTEXT = 0x0000;
const uint WINEVENT_SKIPOWNTHREAD = 0x0001;
const uint EVENT_SYSTEM_DESKTOPSWITCH = 0x0020;

      


Next . The desktop switcher also appears when the user presses Win+ Lor a UAC window appears. Thus, we need a way to detect these other cases. The UAC case is pretty trivial, just check if the process is running consent.exe

during the callback function:



var processes = Process.GetProcessesByName("consent");
if (processes.Length == 0)
    Console.WriteLine("This is not a UAC prompt");

      

The other case, unfortunately, is a little more complicated. I only managed to detect that the user is returning from the lock screen, but is not entering it (as you said, this does not apply to you, but I would like to mention it anyway).

Session lock detection can be done by listening SystemEvents.SessionSwitch

in our HiddenForm

. The property is SessionSwitchEventArgs.Reason

set to SessionSwitchReason.SessionLock

if this event is blocking and SessionSwitchReason.SessionUnlock

if the user is unlocking. We can find out if the desktop switch has switched to the locked desktop when we return to the default desktop, since the desktop switch calls are called before the session is locked and after the session is unlocked. This results in the following code for a sample console application:

private static readonly WinEventDelegate callback = EventCallback;
static void Main(string[] args)
{
    SetWinEventHook(EVENT_SYSTEM_DESKTOPSWITCH,
        EVENT_SYSTEM_DESKTOPSWITCH, IntPtr.Zero, callback, 0, 0,
        WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNTHREAD);

    Application.Run(new HiddenForm());
}

private class HiddenForm : Form
{
    public HiddenForm()
    {
        this.FormBorderStyle = FormBorderStyle.None;
        this.WindowState = FormWindowState.Minimized;
        this.ShowInTaskbar = false;
        SystemEvents.SessionSwitch += SystemEvents_SessionSwitch;
    }

    private void SystemEvents_SessionSwitch(object sender, SessionSwitchEventArgs e)
    {
        if (e.Reason == SessionSwitchReason.SessionUnlock)
            wasUnlocked = true;
    }
}

static bool wasUnlocked = false;
static bool wasOpened = false;

static void EventCallback(IntPtr hWinEventHook, uint eventType,
    IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
{
    // Check if UAC dialog is being shown
    var processes = Process.GetProcessesByName("consent");
    if (processes.Length == 0)
    {
        if (wasOpened)
        {
            if (!wasUnlocked)
                Console.WriteLine("Exited from CTRL+ALT+DEL");
            wasUnlocked = false;
            wasOpened = false;
        }
        else
            wasOpened = true;
    }
}

delegate void WinEventDelegate(IntPtr hWinEventHook, uint eventType,
    IntPtr hwnd, int idObject, int idChild, uint dwEventThread,
    uint dwmsEventTime);

[DllImport("user32.dll")]
static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr
    hmodWinEventProc, WinEventDelegate lpfnWinEventProc, uint idProcess,
    uint idThread, uint dwFlags);

const uint WINEVENT_OUTOFCONTEXT = 0x0000;
const uint WINEVENT_SKIPOWNTHREAD = 0x0001;
const uint EVENT_SYSTEM_DESKTOPSWITCH = 0x0020;

      


a This type of virtual desktop has nothing to do with the recently introduced "virtual desktop" feature in Windows 10

+3


source


Not sure if this can help. This will not check if there is a bot on the screen, and if events have been triggered, you may need to enable logging of these events to do this, you can do this by opening the Group Policy Editor:

gpedit.msc

→ Computer configuration → Windows Settings → Security settings → Advanced audit policy configuration and rarr; System audit policies and rarr; Local Group Policy Object -> Login / Logout -> Audit Other Login / Logout



Once it has been enabled, you can listen to the event ID 4800

for blocking and 4801

for unlocking.

0


source







All Articles