繁体   English   中英

为什么NetworkChange事件不会触发

[英]Why won't NetworkChange events fire

我对这一切还很陌生,但是我已经浏览了所有问题,但找不到能回答我问题的任何东西。

我正在编写一个简单的服务,该服务将在网络设置发生更改时检查它是否可以到达我们的服务器之一。

我正在使用NetworkChange类下的两个事件NetworkAddressChanged和NetworkAvailabiltyChanged。

两种情况下,服务都会尝试对服务器执行ping操作,然后根据结果更改ProxyEnable设置。

编码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Net.NetworkInformation;
using Microsoft.Win32;


namespace ProxyManager
{
    public partial class ProxyManager : ServiceBase
    {
        static RegistryKey rk = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Internet Settings",true);
        static string currentProxy = rk.GetValue("ProxyEnable").ToString();
        static string newProxy;

        public ProxyManager()
        {
            InitializeComponent();

            NetworkChange.NetworkAddressChanged += new NetworkAddressChangedEventHandler(NetworkChange_NetworkAddressChanged);
            NetworkChange.NetworkAvailabilityChanged += new NetworkAvailabilityChangedEventHandler(NetworkChange_NetworkAvailabilityChanged);
            newProxy = "0";
        }

        protected override void OnStart(string[] args)
        {

        }

        void NetworkChange_NetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e)
        {
            ProxySwitcher();
            EventLog evt = new EventLog("ProxyManager");
            string message = "Proxy Manager, Newtwork availabilty changed.  Proxy switched to " + newProxy.ToString();
            evt.Source = "Proxy Manager";
            evt.WriteEntry(message,EventLogEntryType.Information);

        }

        void NetworkChange_NetworkAddressChanged(object sender, EventArgs e)
        {
            ProxySwitcher();
            EventLog evt = new EventLog("ProxyManager");
            string message = "Proxy Manager, Newtwork address changed.  Proxy switched to " + newProxy.ToString();
            evt.Source = "Proxy Manager";
            evt.WriteEntry(message,EventLogEntryType.Information);
        }

        void ProxySwitcher()
        {    
            if (currentProxy == "0")
            {
                newProxy = "1";
            }
            else
            {
                newProxy = "0";
            }

            try
            {
                Ping myPing = new Ping();
                string host = "FILE SERVER";
                byte[] buffer = new byte[32];
                int timeout = 1000;
                PingOptions pingOptions = new PingOptions();
                PingReply reply = myPing.Send(host, timeout, buffer, pingOptions);
                if (reply.Status == IPStatus.Success)
                {
                    if (currentProxy == "0")
                    {

                        rk.SetValue("ProxyEnable", newProxy);
                    }
                }
                else
                {
                    if (currentProxy == "1")
                    {
                        rk.SetValue("ProxyEnable", newProxy);
                    }
                }
            }
            catch (PingException pingEx)
            {
                rk.SetValue("ProxyEnable", 0);
            }
        }
        protected override void OnStop()
        {
        }
    }
}

我的问题是,在安装和运行服务时,事件未触发或未接收。 没有记录相关事件,并且代理也没有切换。

我尝试了代码,减去了可以随意运行且可以正常运行的控制台应用程序中的事件处理程序,具体取决于网络的可用性。

我正在运行Windows 7 x86,但正在.NET 3.5中进行编码。

任何帮助将不胜感激。

我编写了一个相当大的WMI应用程序,这是我永远无法与WMI很好地配合使用的功能。 抱歉,不同意Ted,但是.NET WMI支持非常糟糕,尤其是在正确处理异常以及处理Vista之前的操作系统时。

处理这些事件时有两个警告。 首先,它们仅在主线程上订阅时才起作用。 但是,由于创建了日志文件,因此您似乎已确认已触发该事件。 第二个问题是在您的代码假设网络当前状态的假设下。

从代码的外观来看,您是从Proxy = 0开始的,因此没有代理。 然后,当您收到网络更改事件时,请切换代理。 考虑在服务启动并且网络已经“关闭”时发生的情况,这很可能会在启动期间发生,具体取决于与网络堆栈初始化有关的服务启动时间。 当NIC关闭时,将设置“无代理”,然后在NIC打开时将设置“代理”。 这似乎与您要实现的目标相反。

修复很简单,如果您需要检查网络状态以了解为什么触发了更改事件,则修复很简单。 因此,在您的NetworkAvailabilityChanged事件中,您将需要检查NetworkInterface.GetIsNetworkAvailable(),只要有一个不回送或ms-tunnel的网络接口,它就会返回true。

大概对于NetworkAddressChanged事件,您将要检查该地址以查看其是否有效,以确定是否需要调用您的代理。 您可以通过抓住

UnicastIPAddressInformationCollection就像这样... NetworkInterface [] niList = NetworkInterface.GetAllNetworkInterfaces();

        foreach (NetworkInterface ni in niList)
        {
            switch (ni.NetworkInterfaceType)
            {
                case NetworkInterfaceType.Ethernet: // 10baseT
                case NetworkInterfaceType.FastEthernetT: // 100baseT
                case NetworkInterfaceType.GigabitEthernet:
                    GatewayIPAddressInformationCollection gwIPColl = ni.GetIPProperties().GatewayAddresses;
                    UnicastIPAddressInformation uniIPInfo = null;
                    UnicastIPAddressInformationCollection IPcoll = ni.GetIPProperties().UnicastAddresses;
                    if (IPcoll.Count <= 0)
                    {
                        LogFile.LogMe("No valid unicast IP address");
                        broken = true;
                        break; // Cannot continue if we don't have an IP in the colletion
                    }

或类似的东西,取决于您想要制作的复杂程度。 当我检查网络地址有效性时,我从GatewayIPAddressInformationCollection(.GetIPProperties()。GatewayAddresses)检查单播地址,网络掩码(.IPv4Mask)和已定义的网关。

希望这对您有所帮助。

您可以尝试登录到文件而不是事件日志。 事件日志存在权限问题,并且在您运行服务时,安全模型可能会阻止您写入日志。

考虑使用WMI。 http://msdn.microsoft.com/zh-cn/library/aa394595(v=vs.85).aspx上的一些示例VBScript

我从经验中知道WMI可以工作,但从未尝试使用“ NetworkChange”对象进行操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM