如何以编程方式确定我的工作站是否被锁定?
时间: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 } }