检查Windows当前是否已锁定

时间:2017-11-20 13:59:20

标签: c# windows process

我在Windows 10 Pro x64 ver 1703 build 15063.726上,尝试编写程序重启服务。它通过管理员权限在我的用户下运行,每10分钟通过计划任务运行。

如果服务器不可用或被塞住:

  • 如果我的计算机被锁定,则重新启动程序会终止并重新启动服务器程序。
  • 如果我的计算机未锁定,则重新启动器会显示一个确认重新启动的对话框。我可能正在对服务器程序进行工作,不希望重新启动会破坏任何调试。

唯一的复杂因素是检测计算机是否已锁定。我尝试了几种方法:

  1. OpenInputDesktop()
  2. 仅当用户自计算机锁定后才开始输入密码时,才返回NULL。除此之外返回一个有效的句柄。据推测,在用户尝试登录并输入切换之前,不会取消选择输入桌面。

    1. OpenInputDesktop()vs GetThreadDesktop()
    2. (当然,传入GetCurrentThreadID())

      句柄仍然匹配,可能是由于同样的原因1失败。

      1. 进程检查LockApp.exe / LockAppHost.exe
      2. 似乎与用户输入密码有关......或者因为我的服务器重启应用程序是32位,在读取64位进程LockApp.exe时遇到问题。

        1. GetForegroundWindow()在锁定时返回null
        2. 虽然mentioned as dubious,我也试过了。假阴性,表示没有锁定

          1. 手动切换桌面并查看其是否有效
          2. 用代码示例here描述,这个也是一个半身像,并给出了假阴性。

            还有什么办法吗?我真的宁愿没有服务只是为了注册锁定/解锁持续运行。

            或者其中一种方法是否已经有效,我的Windows会被窃听?

            干杯

2 个答案:

答案 0 :(得分:0)

在进程列表中搜索正在运行的LockApp似乎是可行的方法。

pslist是32位但在后台生成64位进程以列出64位对应的进程,因此不会依赖于C#应用程序是x86或x64(或LockApp)

它不是很好,但它有效。

Process p = new Process
{
    StartInfo = new ProcessStartInfo
    {
        FileName = @"[path to SysSuite]\pslist.exe",
        Arguments = " -nobanner lockapp",
        UseShellExecute = false,
        RedirectStandardOutput = true,
        CreateNoWindow = true
    }
};

p.Start();
p.WaitForExit();
string s = p.StandardOutput.ReadToEnd();
if (!s.Contains("process lockapp was not found on "))
{
    Debug.WriteLine("Windows is locked.");
    return true;
}

稍后,我可以用同样的方式调用pskill。 尽管如此,Windows没有内置的方式来实现这样的基本功能,真的非常愚蠢。

答案 1 :(得分:0)

我不确定如何在C#中执行此操作,但是使用PowerShell,我检查了LockApp.exe线程是否已挂起以查看桌面是否已解锁或锁定,如下所示:

select demo.*, 
      row_number() over (partition by id order by creator desc) as rn 
from demo

此脚本循环60秒并写出锁定/解锁状态。