Почему события NetworkChange не запускаются - PullRequest
0 голосов
/ 17 февраля 2011

Я довольно новичок во всем этом, но я просмотрел вопросы и не могу найти ничего, что отвечало бы на мой вопрос.

Я пишу простой сервис, который проверяет, может ли он достигнуть одного из наших серверов при любых изменениях его сетевых настроек.

Я использую два события в классе NetworkChange, NetworkAddressChanged и NetworkAvailabiltyChanged.

При любом запуске служба пытается пропинговать сервер и в зависимости от результата меняет настройку 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 ]

1 голос
/ 17 февраля 2011

Рассмотрите возможность использования WMI.Некоторые примеры VBScripts на http://msdn.microsoft.com/en-us/library/aa394595(v=vs.85).aspx

Из опыта я знаю, что WMI работает, но никогда не пробовал его с объектом "NetworkChange".

1 голос
/ 22 февраля 2013

Я написал довольно большое приложение WMI, и это единственная функция, с которой я никогда не смог нормально работать с WMI.Извините, что не согласен с Тедом, но поддержка .NET WMI ужасна, особенно в том, что касается правильной работы с исключениями и при работе с операционными системами, предшествующими Vista.Во-первых, они работают, только если подписаны на основной поток.Тем не менее, поскольку ваш файл журнала создается, вы, кажется, убедились, что событие инициируется.Вторая проблема заключается в предположении, что ваш код определяет текущее состояние сети.

Судя по вашему коду, вы начинаете с Proxy = 0, так что прокси отсутствует.Затем, когда вы получаете событие изменения сети, вы переключаете прокси.Подумайте, что происходит, когда ваша служба запускается, а сеть уже «отключена», что вполне может произойти во время загрузки в зависимости от того, когда ваша служба запускается в связи с инициализацией сетевого стека.Вы будете устанавливать «без прокси», когда сетевой адаптер не работает, а затем устанавливать «Прокси», когда сетевой адаптер работает.Это похоже на то, что вы пытались выполнить.

Исправление простое, если вам нужно проверить состояние сети, чтобы узнать, почему произошло событие изменения.Итак, в вашем событии NetworkAvailabilityChanged вы захотите проверить NetworkInterface.GetIsNetworkAvailable (), который возвращает true, если существует один сетевой интерфейс, который не является loopback или ms-tunnel.

Для события 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
                    }

.,.

или что-то подобное в зависимости от того, насколько сложным вы хотите это сделать.Когда я проверяю действительность сетевого адреса, я проверяю адрес Unicast, сетевую маску (.IPv4Mask) и определенный шлюз из GatewayIPAddressInformationCollection (.GetIPProperties (). GatewayAddresses)

Надеюсь, это немного вам поможет.

1 голос
/ 17 февраля 2011

Вы можете попробовать войти в файл вместо журнала событий.Существуют проблемы с разрешениями в журнале событий, и при запуске службы модель безопасности может препятствовать записи в журнал.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...