Detect if Workstation is locked

T

ThunderMusic

Hi,
I want to detect in my C# app (can use iterop) if the workstation is locked.
I've seen on the web people saying it's impossible except by looking if the
Screensaver process is running. There must be a clean way of doing it
because MSN detects it and can change your status based on this.

Does someone have a solution to this please?

thanks

ThunderMusic
 
M

Michael Nemtsev

Hello ThunderMusic,

There is no fuction to detect whether the workstration locked. You can detect
it by checking if any window is visible

T> Hi,
T> I want to detect in my C# app (can use iterop) if the workstation is
T> locked.
T> I've seen on the web people saying it's impossible except by looking
T> if the
T> Screensaver process is running. There must be a clean way of doing it
T> because MSN detects it and can change your status based on this.
T> Does someone have a solution to this please?
T>
T> thanks
T>
T> ThunderMusic
T>
---
WBR,
Michael Nemtsev :: blog: http://spaces.live.com/laflour

"At times one remains faithful to a cause only because its opponents do not
cease to be insipid." (c) Friedrich Nietzsche
 
T

ThunderMusic

ok, but msn does it very very very well, there's certainly a way... Is there
a way to know the state of the computer, locked/unlocked. It does not have
to be an event. Only a function that returns locked/not locked. maybe via
the user account?

thanks

ThunderMusic
 
P

Peter Duniho

ThunderMusic said:
ok, but msn does it very very very well, there's certainly a way... Is
there a way to know the state of the computer, locked/unlocked.

As Michael and John both posted, there IS a way. Test to see if your window
is visible (if it's not, and you haven't specifically made it not visible,
then the session is locked). Of course, you do need a window for that to
work.
It does not have to be an event. Only a function that returns locked/not
locked. maybe via the user account?

Also, see the SessionSwitch SystemEvent. It provides access to the
WM_WTSSESSION_CHANGE window message in .NET. As long as your program is
running, you can use that message to track when session changes occur
(including locking and unlocking).

By the way, I'd disagree that MSN does this "very well". I've seen it get
confused plenty of times. :)

Pete
 
W

Willy Denoyette [MVP]

| Hi,
| I want to detect in my C# app (can use iterop) if the workstation is
locked.
| I've seen on the web people saying it's impossible except by looking if
the
| Screensaver process is running. There must be a clean way of doing it
| because MSN detects it and can change your status based on this.
|
| Does someone have a solution to this please?
|
| thanks
|
| ThunderMusic
|
|

When running on XP or higher you can register for session change
notifications by calling (through PInvoke) the TS API
"WTSRegisterSessionNotification", note that you need a Windows procedure to
capture the messages.


Here are the PInvoke declarations..

[DllImport("wtsapi32.dll")]
private static extern bool WTSRegisterSessionNotification(IntPtr hWnd,
int dwFlags);

[DllImport("wtsapi32.dll")]
private static extern bool WTSUnRegisterSessionNotification(IntPtr
hWnd);

and here how to register...

private const int NotifyForThisSession = 0; // This session only

WTSRegisterSessionNotification(this.Handle, NotifyForThisSession);

and here the messages you can check..

private const int SessionChangeMessage = 0x02B1;
private const int SessionLockParam = 0x7;
private const int SessionUnlockParam = 0x8;

in your overriden WndProc.

protected override void WndProc(ref Message m)
{
// check for session change notifications
if(m.Msg == SessionChangeMessage)
{
if(m.WParam.ToInt32() == SessionLockParam)
OnSessionLock(); // Do something when locked
else if(m.WParam.ToInt32() == SessionUnlockParam)
OnSessionUnlock(); // Do something when unlocked
}

base.WndProc(ref m);
return;
}


void OnSessionLock() {...}

...
void OnSessionUnlock() {...}


call "WTSUnRegisterSessionNotification" when you no longer need to be
notified...

Willy.
 
J

John Brown

I've found a solution, tought maybe it's not the best way, it does the
trick pretty well :

I recommend you investigate this thoroughly. People often apply esoteric
ways of doing things but unless the techniques are officially sanctioned by
MSFT, you're asking for trouble (don't be surprised if it breaks one day
IOW).
 
P

Peter Duniho

ThunderMusic said:
I've found a solution,

You mean you found *another* solution. Two different methods had already
been posted to this thread.
tought maybe it's not the best way, it does the trick pretty well :

http://www.thescripts.com/forum/thread225183.html

I think it's a pretty good bet that the other solution you found is not the
best way, and in fact is unlikely to be better than the methods already
given in this thread.

Pete
 
P

Peter Duniho

ThunderMusic said:
cool!! wow!! thanks a lot... ;)

Or you could accomplish the same thing simply by handling the SessionSwitch
event, as I posted previously. No p/invoke required.

Pete
 
S

Sgt.Sausage

John Brown said:
I recommend you investigate this thoroughly. People often apply esoteric
ways of doing things but unless the techniques are officially sanctioned
by MSFT, you're asking for trouble (don't be surprised if it breaks one
day IOW).

Also consider something that works fine in your environment, but
not someone else's. Consider what happens when, say, running
under Terminal Services, Citrix, et.al.

I've been burned this way many, many times -- I've since learned
my lesson.

Later ...

Sarge
 
W

Willy Denoyette [MVP]

| cool!! wow!! thanks a lot... ;)
|
|

Note that as Peter said, V2 of the framework nicely wraps the stuff I posted
through the SystemEvents class in Microsoft.Win32.
Note that just like you have to make sure to call
WTSUnRegisterSessionNotification in V1, you'll have to make sure to detach
the handler or you'll leak a handle.

Here's a small console app. sample...

using System;
using Microsoft.Win32;

public class App
{
static void Main()
{

SystemEvents.SessionSwitch += SystemEvents_SessionSwitch;
Console.ReadLine(); // block main thread
// !! detach the eventhandler when the application terminates, or you will
leak a handle.
SystemEvents.SessionSwitch -= SystemEvents_SessionSwitch;
}
static void SystemEvents_SessionSwitch(object sender,
SessionSwitchEventArgs e)
{
if(e.Reason == SessionSwitchReason.SessionLock)
{...}
}
}

}


Willy.
 
T

ThunderMusic

thanks it works fine... ;) excellent!!! we have to spread the word...
because unfortunately, this information is pretty hard to get on the net...
it's said almost everywhere that it's not possible to know for sure.... Now
it is!! ;)

thanks

ThunderMusic
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top