【问题标题】:Threads and Invoking a method in Windows Service线程和调用 Windows 服务中的方法
【发布时间】:2015-12-17 14:00:02
【问题描述】:

我将这个项目作为 Windows 服务来实现。我正在尝试找出本地开放的网络接口并记录它们。当网络接口发生变化时,会触发 newAdapterNotifier 方法

    public void newAdapterNotifier(object sender, EventArrivedEventArgs e) //Change in network
    {
        checkNetworkAdapters();
    }

这个方法是由WMI触发的,我的意思是;

ManagementEventWatcher watcher = null;
query = new WqlEventQuery();
query.EventClassName = "__InstanceOperationEvent";
query.WithinInterval = new TimeSpan(0, 0, 1);
query.Condition = @"TargetInstance ISA 'Win32_NetworkAdapter' AND TargetInstance.NetConnectionStatus IS NOT NULL";
watcher = new ManagementEventWatcher(scope, query);
watcher.EventArrived += new EventArrivedEventHandler(newAdapterNotifier);

在 newAdapterNotifier 我调用 checkNetworkAdapters 它没有给出任何错误但也不起作用。在 WindowsForms 中,我正在执行相同的代码,唯一的区别是它正在工作!!!;

public delegate void ControlNetworkAdapter();
public void newAdapterNotifier(object sender, EventArrivedEventArgs e) //Change in network
{
    this.Invoke(new ControlNetworkAdapter(checkNetworkAdapters));
}

由于 Windows 服务应用程序中没有 Invoke 方法,因此无法正常工作。我该如何解决?

类的完整代码(如果在允许的情况下打开任何其他网络接口。发送邮件)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Management;
using System.Net.NetworkInformation;

namespace newInternetNotifier
{
    class newNetworkInterfaceNotifier
    {
        ManagementEventWatcher watcher = null;
        WqlEventQuery query;
        ManagementOperationObserver observer = new ManagementOperationObserver();
        ManagementScope scope = new ManagementScope("root\\CIMV2");
        DbManager sqlConn;
        string cameras1IP = "10.0.0.102";
        string cameras2IP = "10.0.0.103";

        public newNetworkInterfaceNotifier(DbManager _sqlConn)
        {
            sqlConn = _sqlConn;
            getPingableIPs();
            System.Threading.Thread thr = System.Threading.Thread.CurrentThread;
            tmr.Tick +=new EventHandler(tmr_Tick);

            stopTimer();

            checkNetworkAdapters();
            prepareEvent();
        }

        void getPingableIPs() {
            cameras1IP = sqlConn.GetScalarValue("SELECT dbo.GetIP(1)").ToString();
            cameras2IP = sqlConn.GetScalarValue("SELECT dbo.GetIP(2)").ToString();
        }

        int elapsedTime;
        System.Windows.Forms.Timer tmr = new System.Windows.Forms.Timer();
        void startTimer() 
        {
            elapsedTime = 0;
            tmr.Interval = 1000;
            tmr.Start();
        }

        void stopTimer()
        {
            tmr.Stop();
        }

        void tmr_Tick(object sender, EventArgs e)
        {
            elapsedTime += 1;
            if (elapsedTime == 10) {
                stopTimer();
                MailSend();
            }
        }

        public void MailSend() {
            //Send mail code here
        }

        bool sendMail = false;
        protected bool SendMail
        {
            set 
            {
                if (value && !sendMail)
                    startTimer();
                else if (!value && sendMail)
                    stopTimer();

                sendMail = value; 
            }
            get { return sendMail; }
        }

        public void prepareEvent()
        {
            scope.Options.EnablePrivileges = true;
            try
            {
                query = new WqlEventQuery();
                query.EventClassName = "__InstanceOperationEvent";
                query.WithinInterval = new TimeSpan(0, 0, 1);
                query.Condition = @"TargetInstance ISA 'Win32_NetworkAdapter' AND TargetInstance.NetConnectionStatus IS NOT NULL";
                watcher = new ManagementEventWatcher(scope, query);
                watcher.EventArrived += new EventArrivedEventHandler(newAdapterNotifier);
                watcher.Start();                   
            }
            catch
            {
                System.Threading.Thread.Sleep(100000);
                prepareEvent();
            }
        }

        public void watcherStop()
        {
            watcher.Stop();
        }

        Ping p = new Ping();
        public HashSet<NetworkInterface> upAndReal;
        public void checkNetworkAdapters()
        {
            if (upAndReal == null)
                upAndReal = new HashSet<NetworkInterface>();
            else if (upAndReal.Count > 0)
                upAndReal.Clear();

            string desc = "";
            string name = "";

            foreach (NetworkInterface netInt in NetworkInterface.GetAllNetworkInterfaces())
            {
                desc = netInt.Description;
                name = netInt.Name;

                if (netInt.OperationalStatus == OperationalStatus.Up && desc.IndexOf("virtual", StringComparison.OrdinalIgnoreCase) < 0 && name.IndexOf("virtual", StringComparison.OrdinalIgnoreCase) < 0 && desc.IndexOf("Microsoft", StringComparison.OrdinalIgnoreCase) < 0 && name.IndexOf("Microsoft", StringComparison.OrdinalIgnoreCase) < 0 && (desc.IndexOf("Loopback", StringComparison.OrdinalIgnoreCase) < 0) && name.IndexOf("Loopback", StringComparison.OrdinalIgnoreCase) < 0)
                {
                    upAndReal.Add(netInt);
                }
            }

            if (upAndReal.Count <= 1 || (upAndReal.Count == 2 && p.Send(cameras1IP).Status == IPStatus.Success && p.Send(cameras2IP).Status == IPStatus.Success)){
                SendMail = false;
                return;
            }

            SendMail = true;
        }

        public void newAdapterNotifier(object sender, EventArrivedEventArgs e) //Change in network
        {

            checkNetworkAdapters();
        }
    }
}

【问题讨论】:

  • 服务在哪个帐户下运行,可能是权限问题,但如果是这种情况,您可能会遇到某种形式的错误。
  • 具有管理员权限的ActiveDirectory
  • 你得到了什么异常?捕获异常并记录它们。
  • 没有例外.. 实际上我擅长 WinForms 但在 Windows 服务方面是新的.. 我知道测试代码的唯一方法是安装它。所以很难,我在课堂上实现它而不是 Windows 服务。我可以发送课程的完整代码。
  • 我建议您使用 Windows 服务来检查您的 Windows 应用程序是否正在运行。为什么要在 Windows 服务中做这些事情?

标签: c# multithreading windows-services invoke wmi-query


【解决方案1】:

我解决了这个问题。这是关于计时器的。我们不能在 Windows 服务中使用 System.Windows.Forms.Timer.. 我们需要使用其他的.. 但它是哪一个?

【讨论】:

  • 问一个新问题(在你做之前先搜索 SO)。提示:查看System.Threading.Timer
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-29
相关资源
最近更新 更多