簡體   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