如何在网络连接以及用户登录时接收事件

Posted

技术标签:

【中文标题】如何在网络连接以及用户登录时接收事件【英文标题】:How to receive event when network is connected and also when user logs in 【发布时间】:2010-10-15 18:55:03 【问题描述】:

我有一个正在运行的服务,我希望在以下情况下收到通知:

a) 网络已连接。

b) 当用户登录机器时。

我该怎么做? (C#.NET 2.0)

【问题讨论】:

【参考方案1】:
//using Microsoft.Win32;
//using System.Net.NetworkInformation;
public class SessionChanges

    public SessionChanges()
    
        NetworkChange.NetworkAvailabilityChanged += 
            new NetworkAvailabilityChangedEventHandler(NetworkChange_NetworkAvailabilityChanged);
        SystemEvents.SessionSwitch += new SessionSwitchEventHandler(SystemEvents_SessionSwitch);
    

    void SystemEvents_SessionSwitch(object sender, SessionSwitchEventArgs e)
    
        if (e.Reason == SessionSwitchReason.SessionLogon)
         
            //user logged in
        
    

    void NetworkChange_NetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e)
    
        if (e.IsAvailable)
         
            //a network is available
        
    

【讨论】:

SystemEvents.SessionSwitch 只会为当前用户触发,这似乎不是他想要的。 (请参阅 SystemEvents.EnsureRegisteredSessionNotification 的 .Net 参考源) 请注意,要从服务中使用 SystemEvents,您需要一个消息循环。最简单的方法是创建一个隐藏表单。请参阅msdn.microsoft.com/en-us/library/… 中的示例 2,了解一个很好的示例。【参考方案2】:

要在任何用户登录机器时收到通知,请调用WTSRegisterSessionNotification,传递NOTIFY_FOR_ALL_SESSIONS,并在消息循环中监听WM_WTSSESSION_CHANGE 消息。

在消息中,将wParam 转换为Microsoft.Win32.SessionSwitchReason 枚举以了解发生了什么,并将lParam 传递给WTSQuerySessionInformation 以查找用户名。

[DllImport("Wtsapi32.dll", CharSet=.CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool WTSRegisterSessionNotification(IntPtr hWnd, int dwFlags); 

//Pass this value in dwFlags
public const int NOTIFY_FOR_ALL_SESSIONS          =  0x1; 

//Listen for this message
public const int WM_WTSSESSION_CHANGE = 0x02B1;

//Call this method before exiting your program
[DllImport("Wtsapi32.dll", CharSet=.CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool WTSUnRegisterSessionNotification(IntPtr hWnd); 

【讨论】:

【参考方案3】:

要了解网络何时连接,请在System.Net.NetworkInformation.NetworkChange 类中添加NetworkAvailabilityChanged 的处理程序。

找出用户何时登录的一种简单方法是制作一个单独的 exe 并将其放入公共启动中。 每当任何用户登录时都会执行它,然后可以与您的服务通信并提供用户名。 如果您希望您的服务与用户的桌面交互,这是(我相信)唯一的方法。但是,如果您不这样做,这可能不是一个好主意。

请记住,多个用户可以同时登录,尤其是通过远程桌面或终端服务(在 Windows 服务器上)

【讨论】:

【参考方案4】:

您不能使用 .NET 2.0 执行 b)。对于 XP 及之前的版本,您需要创建一个 GINA 替换,它是一个导出一组指定函数的非托管 DLL。

在 Vista 中,您必须使用一个不同的基于 COM 的模型,您可能能够使用 .NET 2.0,但如果您不能,我不会感到惊讶.

我要做的是让您的 GINA 替代品(或 Vista 上的同等产品)向您的服务发送某种信号。

对于 a) 这两个链接应该可以提供帮助:

Windows XP 中的网络感知

http://msdn.microsoft.com/en-us/library/ms700657(VS.85).aspx

Windows Vista 上的网络感知

http://msdn.microsoft.com/en-us/library/ms697388(VS.85).aspx

【讨论】:

请记住,GINA 与快速用户切换不兼容。根据您的目标环境,您的用户可能不喜欢这一点【参考方案5】:

你可以写一个WinLogin Notification package。但是,我不确定是否可以在 C# 中完成。 (我没有理由相信它不是,但我只在 C++ 和非托管代码中做过。)

这是一个代码项目link

我不知道如何监听网络何时连接。

【讨论】:

【参考方案6】:

SENS 可以做到这一点。 http://msdn.microsoft.com/en-us/magazine/cc301850.aspx

检查 ISensNetwork 和 ISensLogon。

为 C# 调整这个,你就完成了。

【讨论】:

以上是关于如何在网络连接以及用户登录时接收事件的主要内容,如果未能解决你的问题,请参考以下文章

无法接收网络相关事件

JQuery Ajax - 如何在进行 Ajax 调用时检测网络连接错误

用FlashFXP时总是连接失败是啥原因

新装的WIN7系统,网络连接显示的是未识别的网络,数据包发送有数字,接收是0,请问如何解决....

15网络与线程

【网络协议笔记】第四层:传输层(Transport)以及UPD协议简介