简体   繁体   English

为什么NetworkChange事件不会触发

[英]Why won't NetworkChange events fire

I am fairly new to all this but I have looked through questions and can't find anything that answers my question. 我对这一切还很陌生,但是我已经浏览了所有问题,但找不到能回答我问题的任何东西。

I am writing a simple service that checks whether it can reach one of our servers whenever there is a change to it's network settings. 我正在编写一个简单的服务,该服务将在网络设置发生更改时检查它是否可以到达我们的服务器之一。

I am using the two events under the NetworkChange class, NetworkAddressChanged and NetworkAvailabiltyChanged. 我正在使用NetworkChange类下的两个事件NetworkAddressChanged和NetworkAvailabiltyChanged。

When either fire the service tries to ping the server and depending on the result changes the ProxyEnable setting. 两种情况下,服务都会尝试对服务器执行ping操作,然后根据结果更改ProxyEnable设置。

The Code: 编码:

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()
        {
        }
    }
}

My problem is that when the service is installed and running, the events are either not being triggered or not being picked up. 我的问题是,在安装和运行服务时,事件未触发或未接收。 There related events are not being logged and the proxy is not switching. 没有记录相关事件,并且代理也没有切换。

I tried the code, minus the event handlers in a console app that I could run at will and that worked fine, depending on the network availability. 我尝试了代码,减去了可以随意运行且可以正常运行的控制台应用程序中的事件处理程序,具体取决于网络的可用性。

I am running Windows 7 x86, but am coding in .NET 3.5. 我正在运行Windows 7 x86,但正在.NET 3.5中进行编码。

Any help will be gratefully received. 任何帮助将不胜感激。

I wrote a rather large WMI application and this is the one feature that I could never get to work well with WMI. 我编写了一个相当大的WMI应用程序,这是我永远无法与WMI很好地配合使用的功能。 Sorry to disagree with Ted but .NET WMI support is terrible, particularly with dealing with exceptions properly and when dealing with pre-Vista operating systems. 抱歉,不同意Ted,但是.NET WMI支持非常糟糕,尤其是在正确处理异常以及处理Vista之前的操作系统时。

Two caveats when dealing with these events. 处理这些事件时有两个警告。 First, they only work if subscribed on the main thread. 首先,它们仅在主线程上订阅时才起作用。 However, since your log file gets created then you appear to have verified that the event is being triggered. 但是,由于创建了日志文件,因此您似乎已确认已触发该事件。 The second problem is in the assumption your code makes about the current state of the network. 第二个问题是在您的代码假设网络当前状态的假设下。

From the look of your code you are starting with Proxy = 0, so no proxy. 从代码的外观来看,您是从Proxy = 0开始的,因此没有代理。 Then when you receive a network change event you toggle the proxy. 然后,当您收到网络更改事件时,请切换代理。 Consider what happens when your service starts and the network is "down" already, which might very well happen during bootup depending on when your service starts in relation to the network stack initialization. 考虑在服务启动并且网络已经“关闭”时发生的情况,这很可能会在启动期间发生,具体取决于与网络堆栈初始化有关的服务启动时间。 You will be setting "no proxy" when the NIC is down, then setting "Proxy" when the NIC is up. 当NIC关闭时,将设置“无代理”,然后在NIC打开时将设置“代理”。 This seems to be inverted to what you were trying to accomplish. 这似乎与您要实现的目标相反。

The fix is simple, in the event you need to check the state of the network to know why the change event was fired. 修复很简单,如果您需要检查网络状态以了解为什么触发了更改事件,则修复很简单。 So, in your NetworkAvailabilityChanged event you are going to want to check NetworkInterface.GetIsNetworkAvailable() which returns true as long as there is one network interface that isn't loopback or ms-tunnel. 因此,在您的NetworkAvailabilityChanged事件中,您将需要检查NetworkInterface.GetIsNetworkAvailable(),只要有一个不回送或ms-tunnel的网络接口,它就会返回true。

For the NetworkAddressChanged event presumably you are going to want to check the address to see if it's valid or not to determine if your proxy needs to be invoked. 大概对于NetworkAddressChanged事件,您将要检查该地址以查看其是否有效,以确定是否需要调用您的代理。 You can do this by grabbing the 您可以通过抓住

UnicastIPAddressInformationCollection like this... NetworkInterface[] niList = NetworkInterface.GetAllNetworkInterfaces(); 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
                    }

. . .

or something similar depending on how complicated your want to make it. 或类似的东西,取决于您想要制作的复杂程度。 When I check for network address validity I check the Unicast address, Netmask (.IPv4Mask) and the defined gateway from GatewayIPAddressInformationCollection (.GetIPProperties().GatewayAddresses) 当我检查网络地址有效性时,我从GatewayIPAddressInformationCollection(.GetIPProperties()。GatewayAddresses)检查单播地址,网络掩码(.IPv4Mask)和已定义的网关。

Hopefully that helps you out a little bit. 希望这对您有所帮助。

You may try logging to a file instead of the event log. 您可以尝试登录到文件而不是事件日志。 There are permission issues with the event log and when you are running the service, the security model may be preventing you from writing to the log. 事件日志存在权限问题,并且在您运行服务时,安全模型可能会阻止您写入日志。

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

I know from experience that WMI works, but never tried it with "NetworkChange" object. 我从经验中知道WMI可以工作,但从未尝试使用“ NetworkChange”对象进行操作。

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

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