Is the computer locked?

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Is there a way using the .NET framework to find out if the machine a service
is running on is locked by the user?
 
There's a couple of ways. The easiest one, if you don't mind using a
hidden form to trap WndProc events & PINVOKE in your service is to
subscribe to WTSRegisterSessionNotification and
WTSUnRegisterSessionNotification from wtsapi32.dll:


using System;
using System.Windows.Forms;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace DetectLocked
{
public class Form1 : System.Windows.Forms.Form
{
private const int NOTIFY_THIS_SESSION_ONLY_FLAG = 0;
private const int SESSION_CHANGE_MESSAGE = 0x02B1;
private const int SESSION_PARAM_LOCKED = 0x7;
private const int SESSION_PARAM_UNLOCKED = 0x8;


// Register this form to receive notification
[DllImport("wtsapi32.dll")]
private static extern bool WTSRegisterSessionNotification(IntPtr
hWnd, int dwFlags);

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

private System.ComponentModel.Container components = null;

public Form1()
{
InitializeComponent();

WTSRegisterSessionNotification(this.Handle,
NOTIFY_THIS_SESSION_ONLY_FLAG);

//WTSUnRegisterSessionNotification
}

protected override void WndProc(ref Message m)
{

if (m.Msg == SESSION_CHANGE_MESSAGE)
{
switch (m.WParam.ToInt32())
{
case SESSION_PARAM_LOCKED:
Debug.WriteLine("session locked");
break;

case SESSION_PARAM_UNLOCKED:
Debug.WriteLine("session unlocked");
break;
}
}

base.WndProc(ref m);
}


/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(208, 181);
this.Name = "Form1";
this.Text = "Form1";

}
#endregion


}
}

I've also tried using WMI from the System.Management namespace but have
had no success - I'm not entirely sure which event to listen for.
Here's the basics:

using System;
using System.Management;
using System.Diagnostics;

namespace DetectLocked
{

public class WMISessionWatch
{
private ManagementEventWatcher eventWatcher = null;

public WMISessionWatch()
{
//eventWatcher = new ManagementEventWatcher("ROOT\\CIMV2", "SELECT *
FROM __InstanceOperationEvent WITHIN 5 WHERE TargetInstance ISA
\"Win32_UserAccount\"");
//eventWatcher = new ManagementEventWatcher("ROOT\\CIMV2", "SELECT *
FROM __InstanceOperationEvent WITHIN 5 WHERE TargetInstance ISA
\"Win32_Session\"");
eventWatcher = new ManagementEventWatcher("ROOT\\CIMV2", "SELECT *
FROM __InstanceOperationEvent WITHIN 5 WHERE TargetInstance ISA
\"Win32_LogonSession\"");
eventWatcher.EventArrived += new
EventArrivedEventHandler(eventWatcher_EventArrived);
}

private void eventWatcher_EventArrived(object sender,
EventArrivedEventArgs e)
{
Debug.WriteLine(DateTime.Now.ToString() + " " +
e.NewEvent.ToString());
}

public void Start()
{
eventWatcher.Start();
}

public void Stop()
{
eventWatcher.Stop();
}

}
}

The events are ins ROOT\CIMV2 namespace. The "WITHIN 5" polls every 5
seconds for an operation event.
 
There's a couple of ways. The easiest one, if you don't mind using a
hidden form to trap WndProc events & PINVOKE in your service is to
subscribe to WTSRegisterSessionNotification and
WTSUnRegisterSessionNotification from wtsapi32.dll:


using System;
using System.Windows.Forms;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace DetectLocked
{
public class Form1 : System.Windows.Forms.Form
{
private const int NOTIFY_THIS_SESSION_ONLY_FLAG = 0;
private const int SESSION_CHANGE_MESSAGE = 0x02B1;
private const int SESSION_PARAM_LOCKED = 0x7;
private const int SESSION_PARAM_UNLOCKED = 0x8;


// Register this form to receive notification
[DllImport("wtsapi32.dll")]
private static extern bool WTSRegisterSessionNotification(IntPtr
hWnd, int dwFlags);

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

private System.ComponentModel.Container components = null;

public Form1()
{
InitializeComponent();

WTSRegisterSessionNotification(this.Handle,
NOTIFY_THIS_SESSION_ONLY_FLAG);

//WTSUnRegisterSessionNotification
}

protected override void WndProc(ref Message m)
{

if (m.Msg == SESSION_CHANGE_MESSAGE)
{
switch (m.WParam.ToInt32())
{
case SESSION_PARAM_LOCKED:
Debug.WriteLine("session locked");
break;

case SESSION_PARAM_UNLOCKED:
Debug.WriteLine("session unlocked");
break;
}
}

base.WndProc(ref m);
}


/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(208, 181);
this.Name = "Form1";
this.Text = "Form1";

}
#endregion


}
}

I've also tried using WMI from the System.Management namespace but have
had no success - I'm not entirely sure which event to listen for.
Here's the basics:

using System;
using System.Management;
using System.Diagnostics;

namespace DetectLocked
{

public class WMISessionWatch
{
private ManagementEventWatcher eventWatcher = null;

public WMISessionWatch()
{
//eventWatcher = new ManagementEventWatcher("ROOT\\CIMV2", "SELECT *
FROM __InstanceOperationEvent WITHIN 5 WHERE TargetInstance ISA
\"Win32_UserAccount\"");
//eventWatcher = new ManagementEventWatcher("ROOT\\CIMV2", "SELECT *
FROM __InstanceOperationEvent WITHIN 5 WHERE TargetInstance ISA
\"Win32_Session\"");
eventWatcher = new ManagementEventWatcher("ROOT\\CIMV2", "SELECT *
FROM __InstanceOperationEvent WITHIN 5 WHERE TargetInstance ISA
\"Win32_LogonSession\"");
eventWatcher.EventArrived += new
EventArrivedEventHandler(eventWatcher_EventArrived);
}

private void eventWatcher_EventArrived(object sender,
EventArrivedEventArgs e)
{
Debug.WriteLine(DateTime.Now.ToString() + " " +
e.NewEvent.ToString());
}

public void Start()
{
eventWatcher.Start();
}

public void Stop()
{
eventWatcher.Stop();
}

}
}

The events are ins ROOT\CIMV2 namespace. The "WITHIN 5" polls every 5
seconds for an operation event.
 
Back
Top