如何以编程方式确定我的工作站是否被锁定?

时间:2020-03-05 18:47:57  来源:igfitidea点击:

我正在为自己编写一些生产率/指标工具,以帮助全天监控我的注意力。最近,我注意到我倾向于比平常更多地偏离轨道,并感到需要起身去散步/喝酒/等,而且我担心自己在"浪费"太多时间。

由于我总是到处走动时都锁定计算机,并且一旦返回就立即解锁(即使我只是在办公桌前看书等),我想知道如何用代码确定计算机的运行时间。被锁住了。

我在Cif中写这篇文章很有帮助,但是我对其他想法持开放态度。

我喜欢Windows服务的想法(并已接受它)是为了简洁和整洁,但不幸的是,我认为在这种特殊情况下,它不会对我有用。我想在办公室而不是在家(或者我想在家中)上在工作站上运行它,但是出于国防部的考虑,它的工作受到了很大的限制。实际上,这就是我自己推出自己的原因的一部分。

无论如何,我都会写出来,看看它是否有效。谢谢大家!

解决方案

回答

下面是100%工作代码,用于查找PC​​是否已锁定。

在使用此名称之前,请使用名称空间" System.Runtime.InteropServices"。

[DllImport("user32", EntryPoint = "OpenDesktopA", CharSet = CharSet.Ansi,SetLastError = true, ExactSpelling = true)]
private static extern Int32 OpenDesktop(string lpszDesktop, Int32 dwFlags, bool fInherit, Int32 dwDesiredAccess);

[DllImport("user32", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
private static extern Int32 CloseDesktop(Int32 hDesktop);

[DllImport("user32", CharSet = CharSet.Ansi,SetLastError = true,ExactSpelling = true)]
private static extern Int32 SwitchDesktop(Int32 hDesktop);

public static bool IsWorkstationLocked()
{
    const int DESKTOP_SWITCHDESKTOP = 256;
    int hwnd = -1;
    int rtn = -1;

    hwnd = OpenDesktop("Default", 0, false, DESKTOP_SWITCHDESKTOP);

    if (hwnd != 0)
    {
        rtn = SwitchDesktop(hwnd);
        if (rtn == 0)
        {
            // Locked
            CloseDesktop(hwnd);
            return true;
        }
        else
        {
            // Not locked
            CloseDesktop(hwnd);
        }
    }
    else
    {
        // Error: "Could not access the desktop..."
    }

    return false;
}

回答

我将创建一个处理OnSessionChange事件的Windows服务(Visual Studio 2005项目类型),如下所示:

protected override void OnSessionChange(SessionChangeDescription changeDescription)
{
    if (changeDescription.Reason == SessionChangeReason.SessionLock)
    { 
        //I left my desk
    }
    else if (changeDescription.Reason == SessionChangeReason.SessionUnlock)
    { 
        //I returned to my desk
    }
}

此时,我们将如何记录活动以及如何记录活动取决于我们,但是Windows服务可以快速,轻松地访问Windows事件,例如启动,关闭,登录/注销,以及锁定和解锁事件。

回答

下面的解决方案使用Win32 API。工作站锁定时调用OnSessionLock,解锁时调用OnSessionUnlock。

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

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

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

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

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() 
{
    Debug.WriteLine("Locked...");
}

void OnSessionUnlock() 
{
    Debug.WriteLine("Unlocked...");
}

private void Form1Load(object sender, EventArgs e)
{
    WTSRegisterSessionNotification(this.Handle, NotifyForThisSession);
}

// and then when we are done, we should unregister for the notification
//  WTSUnRegisterSessionNotification(this.Handle);

回答

我以前没有找到过,但是从任何应用程序中,我们都可以连接SessionSwitchEventHandler。显然,应用程序将需要运行,但前提是:

Microsoft.Win32.SystemEvents.SessionSwitch += new Microsoft.Win32.SessionSwitchEventHandler(SystemEvents_SessionSwitch);

void SystemEvents_SessionSwitch(object sender, Microsoft.Win32.SessionSwitchEventArgs e)
{
    if (e.Reason == SessionSwitchReason.SessionLock)
    { 
        //I left my desk
    }
    else if (e.Reason == SessionSwitchReason.SessionUnlock)
    { 
        //I returned to my desk
    }
}