C# 如何在服务中识别电脑当前是否已锁定或未登录?

C# 如何在服务中识别电脑当前是否已锁定或未登录?,c#,.net,windows,windows-services,C#,.net,Windows,Windows Services,简短:在服务中,我如何识别电脑当前是否未显示活动桌面(即,它已锁定或未登录) Long:我正在尝试构建一个Win 7-10解决方案,包括一个DB、一个服务和一个WPF应用程序。在数据库中设置标志时,服务将向用户发送一条自定义消息,无论用户是否登录。 如果有人登录,该服务将启动该应用程序,该应用程序将显示消息以及重新启动/注销选项。 这很好,到目前为止还不错 如果屏幕被锁定或没有用户登录,则问题是在锁定屏幕上显示消息。我可以使用“msg.exe*message”显示消息,但如果用户登录,我不希望m

简短:在服务中,我如何识别电脑当前是否未显示活动桌面(即,它已锁定或未登录)

Long:我正在尝试构建一个Win 7-10解决方案,包括一个DB、一个服务和一个WPF应用程序。在数据库中设置标志时,服务将向用户发送一条自定义消息,无论用户是否登录。
如果有人登录,该服务将启动该应用程序,该应用程序将显示消息以及重新启动/注销选项。 这很好,到目前为止还不错

如果屏幕被锁定或没有用户登录,则问题是在锁定屏幕上显示消息。我可以使用“msg.exe*message”显示消息,但如果用户登录,我不希望msg.exe和应用程序同时启动。因此,我需要能够在从数据库读取标志时确定哪个可执行文件是合适的。
明确地说:我对射击事件不感兴趣。我对在特定时间阅读“当前状态”感兴趣


NB:有很多问题类似于这个问题,但我还没有找到一个能准确描述我困境的问题。大多数都与锁定事件有关,或者在没有用户登录的服务中不起作用。

调用
RegisterServiceCtrlHandlerEx
在您的服务中,您的回调将收到
服务控制会话更改
通知,您可以跟踪和
WTS\U会话解锁
事件


可以为您提供特定会话的状态(.SessionFlags)。

在您的服务中调用
RegisterServiceCtrlHandlerEx
,然后您的回调将收到
服务控制会话更改
通知,您可以跟踪和
WTS\u会话解锁
事件


可以给你一个特定的会话状态(.Session FLAGS)。

< P>我没有在C语言中实现WTSSessionInfoEx(我只能找到C++实例,并且不能成功转换),所以我接受失败,而不是监视事件。 这个答案很有效:
谢谢你,迈克尔

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceProcess;
using System.Diagnostics;

namespace MyCode
{
    class MyService : ServiceBase
    {
        public MyService()
        {
            this.CanHandleSessionChangeEvent = true;
        }

        protected override void OnSessionChange(SessionChangeDescription changeDescription)
        {
            switch (changeDescription.Reason)
            {
                case SessionChangeReason.SessionLogon:
                    Debug.WriteLine(changeDescription.SessionId + " logon");
                    break;
                case SessionChangeReason.SessionLogoff:
                    Debug.WriteLine(changeDescription.SessionId + " logoff");
                    break;
                case SessionChangeReason.SessionLock:
                    Debug.WriteLine(changeDescription.SessionId + " lock");
                    break;
                case SessionChangeReason.SessionUnlock:
                    Debug.WriteLine(changeDescription.SessionId + " unlock");
                    break;
            }

            base.OnSessionChange(changeDescription);
        }
    }
}

<>我没有在C语言中实现WTSSessionInfoEx(我只能找到C++实例,并且不能成功转换),所以我接受失败,而不是监视事件。 这个答案很有效:
谢谢你,迈克尔

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceProcess;
using System.Diagnostics;

namespace MyCode
{
    class MyService : ServiceBase
    {
        public MyService()
        {
            this.CanHandleSessionChangeEvent = true;
        }

        protected override void OnSessionChange(SessionChangeDescription changeDescription)
        {
            switch (changeDescription.Reason)
            {
                case SessionChangeReason.SessionLogon:
                    Debug.WriteLine(changeDescription.SessionId + " logon");
                    break;
                case SessionChangeReason.SessionLogoff:
                    Debug.WriteLine(changeDescription.SessionId + " logoff");
                    break;
                case SessionChangeReason.SessionLock:
                    Debug.WriteLine(changeDescription.SessionId + " lock");
                    break;
                case SessionChangeReason.SessionUnlock:
                    Debug.WriteLine(changeDescription.SessionId + " unlock");
                    break;
            }

            base.OnSessionChange(changeDescription);
        }
    }
}

我曾经做过一件事,那就是我必须通过一个服务在桌面上启动应用程序。要做到这一点,我必须在系统托盘中创建一个图标,以获得对桌面的权限。也许,如果你设置了一个系统,试着在启动时运行图标应用,你可以与它通信,以确定是否有人登录了它(我假设这是一个单点登录的情况)。这是一个单点登录的情况,是的。我可能可以确定某人是否以这种方式签名,但它不会告诉我他们是否被锁定。我将把它作为一个可能的部分解决方案牢记在心,但我真的不希望在服务之上添加一个始终运行的应用程序。我希望它尽可能简单,因为稳定性和低占地面积是关键。它将在10-30k pc上运行,并向用户提供关键信息。如果控制台会话在锁定时显示为“已断开”,则可以枚举所有终端服务会话,并检查它们是否都处于断开状态。我不知道它是不是真的。是的,就我所知,它即使被锁定也会保持活动状态,不幸的是(在赢10的时候)。在发布之前,我用powershell进行了测试,所以我非常确定。我曾经做过一件事,那就是我必须从一个服务在桌面上启动应用程序。要做到这一点,我必须在系统托盘中创建一个图标,以获得对桌面的权限。也许,如果你设置了一个系统,试着在启动时运行图标应用,你可以与它通信,以确定是否有人登录了它(我假设这是一个单点登录的情况)。这是一个单点登录的情况,是的。我可能可以确定某人是否以这种方式签名,但它不会告诉我他们是否被锁定。我将把它作为一个可能的部分解决方案牢记在心,但我真的不希望在服务之上添加一个始终运行的应用程序。我希望它尽可能简单,因为稳定性和低占地面积是关键。它将在10-30k pc上运行,并向用户提供关键信息。如果控制台会话在锁定时显示为“已断开”,则可以枚举所有终端服务会话,并检查它们是否都处于断开状态。我不知道它是不是真的。是的,就我所知,它即使被锁定也会保持活动状态,不幸的是(在赢10的时候)。在发布之前,我用powershell测试了这一点,所以我相当确定。正如我在OP中提到的,我不想看事件,只看当前状态。我会研究WTSQuerySessionInformation,然后给你回复,这听起来很有希望:)这个事件是为服务设计的,很容易实现,所以我不明白为什么你不能使用它。我可以让WTSQuerySessionInformation工作得很好,但没有WTSquerySessionInfoEx,它无法提供我所需要的信息——这更麻烦。我只能在C++中找到我没有经验的例子。我发现一篇帖子,有人试图将其转换为C:…但我无法让他的代码正常工作。我不是一个很强的程序员,所以我可能是在我的头在这里。毕竟,我可能不得不求助于使用事件。正如我在OP中提到的,我宁愿不看事件,只看当前状态。我会研究WTSQuerySessionInformation,然后给你回复,这听起来很有希望:)这个事件是为服务设计的,很容易实现,所以我不明白为什么你不能使用它。我可以让WTSQuerySessionInformation工作得很好,但没有WTSquerySessionInfoEx,它无法提供我所需要的信息——这更麻烦。我只能在C++中找到我没有经验的例子。我找到了一个帖子,有人试图