C# 为什么赢了';t网络更改事件火灾

C# 为什么赢了';t网络更改事件火灾,c#,network-programming,service,C#,Network Programming,Service,我对这一切都很陌生,但我已经浏览了所有问题,找不到任何能回答我问题的答案 我正在写一个简单的服务,检查它是否可以到达我们的服务器之一,只要有一个改变,它的网络设置 我正在使用NetworkChange类下的两个事件:NetworkAddressChanged和NetworkAvailabiltyChanged 当其中一个触发时,服务尝试ping服务器,并根据结果更改ProxyEnable设置 守则: using System; using System.Collections.Generic;

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

我正在写一个简单的服务,检查它是否可以到达我们的服务器之一,只要有一个改变,它的网络设置

我正在使用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()
        {
        }
    }
}
我的问题是,当服务安装并运行时,事件要么没有被触发,要么没有被拾取。未记录相关事件,代理未切换

我尝试了这段代码,减去控制台应用程序中的事件处理程序,我可以随意运行这些程序,根据网络可用性的不同,这些程序运行得很好

我运行的是Windows7x86,但使用的是.NET3.5


我们将非常感谢您的帮助。

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

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

请考虑使用WMI。 上的一些示例脚本

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

考虑使用WMI。 上的一些示例脚本


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

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

处理这些事件时有两个注意事项。首先,它们只有在主线程上订阅时才能工作。但是,由于日志文件已创建,因此您似乎已验证事件是否已触发。第二个问题是代码对网络当前状态的假设

从代码的外观来看,您是从Proxy=0开始的,因此没有代理。然后,当您收到网络更改事件时,切换代理。考虑当服务开始时,网络已经“宕机”时发生了什么,这可能在启动过程中很好地发生,这取决于您的服务何时开始与网络堆栈初始化有关。当NIC关闭时,您将设置“无代理”,然后在NIC打开时设置“代理”。这似乎与您试图实现的目标相反

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

对于NetworkAddressChanged事件,您可能需要检查地址是否有效,以确定是否需要调用代理。您可以通过抓住

像这样的UnicastipAddressInformation集合。。。 NetworkInterface[]niList=NetworkInterface.GetAllNetworkInterfaces()

foreach(niList中的网络接口ni)
{
交换机(ni.NetworkInterfaceType)
{
case NetworkInterfaceType.Ethernet://10baseT
案例NetworkInterfaceType.FastEthernetT://100baseT
案例NetworkInterfaceType.GigabitEthernet:
GatewayIPAddressInformationCollection gwIPColl=ni.GetIPProperties().GatewayAddresses;
UnicastIPAddressInformation uniIPInfo=null;
UnicastipAddressInformation集合IPcoll=ni.GetIPProperties().UnicastAddresss;

if(IPcoll.Count我编写了一个相当大的WMI应用程序,这是我无法很好地使用WMI的一个功能。很抱歉不同意Ted的观点,但是.NET WMI支持非常糟糕,特别是在正确处理异常和处理Vista之前的操作系统时

处理这些事件时有两个注意事项。首先,它们只有在主线程上订阅时才起作用。但是,由于日志文件已创建,因此您似乎已验证事件是否已触发。第二个问题是,您的代码假设网络的当前状态

从代码的外观看,你从代理= 0开始,所以没有代理。然后当你收到一个网络更改事件时,你可以切换代理。考虑当你的服务开始并且网络“下降”时会发生什么。这很可能在启动过程中发生,具体取决于服务启动的时间与网络堆栈初始化的关系。当NIC关闭时,您将设置“无代理”,然后在NIC启动时设置“代理”。这似乎与您试图实现的相反

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

对于NetworkAddressChanged事件,您可能希望检查地址是否有效,以确定是否需要调用代理。您可以通过抓取

像这样的UnicastipAddressInformation集合。。。 NetworkInterface[]niList=NetworkInterface.GetAllNetworkInterfaces()

foreach(niList中的网络接口)
        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
                    }