Knowing when the user locks the PC

Posted on 2009-05-07
Last Modified: 2013-12-17
   As an initiative to save power in my company, I am planning to write an application which turns off the monitor when the user locks his/her PC.

   The OS is Windows XP SP2.

   I have the code for switching off the monitor.

   The user locks his/her machine by either pressing the "WindowsKey + L"  or pressing "Ctrl + Alt+ Del" and then choosing the Lock Computer option.

   Should I make a windows service? how will the service come to know whether the user has locked the machine?
   I want to code it in C#.

Question by:CuteBug

Expert Comment

ID: 24325101
just enable power safe - disable monitor after period of time
LVL 16

Author Comment

ID: 24325446
Well we do not have access to that feature. Only the sysadmins have access.
LVL 75

Accepted Solution

käµfm³d   👽 earned 300 total points
ID: 24327035
You can use a global key hook to trap keys pressed within the OS. From

Now obviously you can modify the code to fit your needs, but as is, you could check "message" for "LWin/RWin", store it to some private variable if set and then check for "L" to be the next key pressed.

Ctrl-Alt-Delete will be a little more difficult to capture. The method below will not work. From what I have read, you have to write something called a GINA stub to capture that--please don't ask me to explain :/ The following article talks about it though.   <<--- last post

// Intercept Keys Class


using System;

using System.Diagnostics;

using System.Windows.Forms;

using System.Runtime.InteropServices;

class InterceptKeys


    private const int WH_KEYBOARD_LL = 13;

    private const int WM_KEYDOWN = 0x0100;

    private const int WM_SYSKEYDOWN = 0x0104; 

    private static LowLevelKeyboardProc _proc = HookCallback;

    private static IntPtr _hookID = IntPtr.Zero;

    private static ExternalCallback callback;

    public delegate void ExternalCallback(string message);

    public static void Begin(ExternalCallback cb)


        _hookID = SetHook(_proc);

        callback = cb;


    public static void End()



        _hookID = IntPtr.Zero;


    private static IntPtr SetHook(LowLevelKeyboardProc proc)


        using (Process curProcess = Process.GetCurrentProcess())

        using (ProcessModule curModule = curProcess.MainModule)


            return SetWindowsHookEx(WH_KEYBOARD_LL, proc,

                GetModuleHandle(curModule.ModuleName), 0);



    private delegate IntPtr LowLevelKeyboardProc(

        int nCode, IntPtr wParam, IntPtr lParam);

    private static IntPtr HookCallback(

        int nCode, IntPtr wParam, IntPtr lParam)


        if (nCode >= 0 && (wParam == (IntPtr)WM_KEYDOWN || wParam == (IntPtr)WM_SYSKEYDOWN))


            int vkCode = Marshal.ReadInt32(lParam);



        return CallNextHookEx(_hookID, nCode, wParam, lParam);


    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]

    private static extern IntPtr SetWindowsHookEx(int idHook,

        LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]

    [return: MarshalAs(UnmanagedType.Bool)]

    private static extern bool UnhookWindowsHookEx(IntPtr hhk);

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]

    private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,

        IntPtr wParam, IntPtr lParam);

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]

    private static extern IntPtr GetModuleHandle(string lpModuleName);



// Form


using System;

using System.Windows.Forms;

namespace WindowsFormsApplication3


    public partial class Form1 : Form


        public Form1()




        private void Form1_Load(object sender, EventArgs e)




        private void Form1_FormClosing(object sender, FormClosingEventArgs e)




        private void UpdateBox(string message)






Open in new window

LVL 85

Assisted Solution

by:Mike Tomlinson
Mike Tomlinson earned 200 total points
ID: 24328106
LVL 16

Author Closing Comment

ID: 31578966
Thanks a lot! Your answers have been very helpful.

Featured Post

3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
What is Thread.Sleep? 5 45
Connection String 16 41
C# parent child form 5 13
Where to download and how to install sqldmo.dll 5 27
This article describes relatively difficult and non-obvious issues that are likely to arise when creating COM class in Visual Studio and deploying it by professional MSI-authoring tools. It is assumed that the reader is already familiar with the cla…
Performance in games development is paramount: every microsecond counts to be able to do everything in less than 33ms (aiming at 16ms). C# foreach statement is one of the worst performance killers, and here I explain why.
Concerto provides fully managed cloud services and the expertise to provide an easy and reliable route to the cloud. Our best-in-class solutions help you address the toughest IT challenges, find new efficiencies and deliver the best application expe…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

929 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

8 Experts available now in Live!

Get 1:1 Help Now