为什么NetworkChange事件不会触发

时间:2011-02-17 11:52:27

标签: c# network-programming service

我对这一切都很陌生,但是我已经查看了问题,找不到任何可以回答我问题的内容。

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

我正在使用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进行编码。

将非常感激地收到任何帮助。

3 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

考虑使用WMI。 http://msdn.microsoft.com/en-us/library/aa394595(v=vs.85).aspx

上的一些示例VBScripts

根据经验我知道WMI可以工作,但从未尝试过使用“NetworkChange”对象。

答案 2 :(得分:1)

我写了一个相当大的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
                    }

。 。

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

希望能帮到你一点点。