【问题标题】:Windows .NET Service - OnSessionChange event seems quite unreliableWindows .NET 服务 - OnSessionChange 事件似乎很不可靠
【发布时间】:2015-03-16 21:28:05
【问题描述】:

我正在用 C# 编写一个需要跟踪当前活动登录用户的 Windows 服务。为此,我重写了 OnSessionChange 事件,以记录用户何时登录、注销或锁定计算机。这通常在大多数情况下都有效,但有时该服务会丢失对活动用户的跟踪。在我的日志文件中,我可以看到问题出在 OnSessionChange 方法上。每次调用此函数时,我都会输出一些日志信息,显然,OnSessionChange 调用有时会以错误的顺序出现。也就是说,如果用户锁定了计算机,然后又快速再次登录,有时会发生两次 OnSessionChange 调用,这会导致调用顺序错误(例如,首先是解锁事件,然后是锁定事件)。

有人知道为什么会这样吗?有没有解决这个问题的方法?

编辑:这是一些示例代码,使其更清晰(希望如此):

protected override void OnSessionChange(SessionChangeDescription changeDescription)
{
    try
    {
        var user = _getUserName(changeDescription.SessionId);

        if (changeDescription.Reason == SessionChangeReason.SessionLock ||
            changeDescription.Reason == SessionChangeReason.SessionLogoff ||
            changeDescription.Reason == SessionChangeReason.ConsoleDisconnect)

            LogText(String.Format("{0} locked at {1}\r\n", user, DateTime.Now));

        else if (changeDescription.Reason == SessionChangeReason.SessionUnlock ||
                 changeDescription.Reason == SessionChangeReason.SessionLogon ||
                 changeDescription.Reason == SessionChangeReason.ConsoleConnect)

            LogText(String.Format("{0} unlocked at {1}\r\n", user, DateTime.Now));

        base.OnSessionChange(changeDescription);
    }
    catch (Exception e)
    {
        LogText("Exception: " + e);
    }
}

(函数 _getUserName 和 LogText 没有显示,但它们按照它们的名字所暗示的那样做。另外,我从来没有遇到异常,所以 try-catch-block 只是为了验证我实际上没有得到任何异常。)

现在,有时,在我的日志中我会得到这样的信息:

UserA 于 18.01.2015 08:40:29 解锁 UserA 于 18.01.2015 08:44:28 解锁 UserA 锁定于 18.01.2015 08:44:28

这就是今天早上发生的事情。 UserA 登录,然后锁定并立即(我认为)再次登录。但是最后两个事件以错误的顺序触发,所以在这个序列之后,我的服务错误地认为 UserA 已经消失了。

通常,我会连续收到几个解锁事件,比如昨天的这个:

UserA 于 17.01.2015 10:55:26 解锁 UserA 于 17.01.2015 10:55:26 解锁 UserA 于 17.01.2015 10:56:33 解锁

或者我可以连续获得多个锁定事件,这可能意味着我错过了它们之间的一个或多个解锁事件:

UserA 于 17.01.2015 09:29:35 解锁 UserA 锁定于 17.01.2015 10:25:28 UserA 锁定于 17.01.2015 10:30:20

【问题讨论】:

  • 我认为显示代码本身的某些部分可能有助于我们理解您在说什么。虽然我确实知道 OnSessionChange,但我认为在您的程序中研究一般登录/注销概念可能会帮助我(或其他人)回答您。
  • 好的,我会添加一些代码
  • 您的代码不会检查 changeDescription.Reason 的每个可能值(即 RemoteConnect、RemoteDisconnect、SessionRemoteControl 将导致无日志输出)。也许记录这些事件也会很有用,以便全面了解系统正在做什么并可能有助于诊断问题?
  • 实际上,我的代码中确实有另一个 else-branch 可以做到这一点(我只是在此处将其删除以缩短一点)。基本上,它只是一个“else LogText(”其他原因:“+changeDescription.Reason)”。它永远不会发生。
  • 你解决过这个问题吗?我得到了同样的东西(我也有一个与你的代码做完全相同的事情的服务)......有时它有效......有时它没有。我还看到的是,当操作系统创建配置文件时,根本不会调用 OnSessionChange。

标签: c# windows service login


【解决方案1】:

this.CanHandleSessionChangeEvent 必须设置为 true,默认值为 false。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多