在Windows服务C#中引发自定义类事件



我确实写了一个windows服务,可以使用dll连接到网络设备。所以一切都很好,但事件处理程序在win服务中不起作用!这是我的代码:

我的自定义类代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MyNewService
{
    public class zkemkeeperHandler
    {
        public event EventHandler OnFinger;
        public event EventHandler<VerifyEventArgs> OnVerify;
        private System.Diagnostics.EventLog eventLog1 = new System.Diagnostics.EventLog();
        public zkemkeeper.CZKEMClass axCZKEM1 = new zkemkeeper.CZKEMClass();
        private bool bIsConnected = false;
        private int iMachineNumber = 1;
        public zkemkeeperHandler()
        {
            ((System.ComponentModel.ISupportInitialize)(this.eventLog1)).BeginInit();
            this.eventLog1.Log = "DoDyLog";
            this.eventLog1.Source = "DoDyLogSource";
            ((System.ComponentModel.ISupportInitialize)(this.eventLog1)).EndInit();
            eventLog1.WriteEntry("zkemkeeperHandler constructor");
        }
        public void startService()
        {
            eventLog1.WriteEntry("start service for (192.168.0.77:4370)");
            bIsConnected = axCZKEM1.Connect_Net("192.168.0.77", Convert.ToInt32("4370"));
            if (bIsConnected == true)
            {
                eventLog1.WriteEntry("bIsConnected == true !");
                iMachineNumber = 1;
                if (axCZKEM1.RegEvent(iMachineNumber, 65535))
                {
                    this.axCZKEM1.OnFinger += new kemkeeper._IZKEMEvents_OnFingerEventHandler(axCZKEM1_OnFinger);
                    this.axCZKEM1.OnVerify += new zkemkeeper._IZKEMEvents_OnVerifyEventHandler(axCZKEM1_OnVerify);
                    //This Log Appears in Event Viewer
                    eventLog1.WriteEntry("Define events (OnFingers and OnVerify) !");
                    //This Line Fires Event in Service1.cs for testing event handler
                    Finger(EventArgs.Empty);
                }
            }
            else
            {
                eventLog1.WriteEntry("Unable to connect the device");
            }
        }
        public void stopService()
        {
            if (bIsConnected) {axCZKEM1.Disconnect(); bIsConnected = false;}
        }
        //This method doesn't run :(
        private void axCZKEM1_OnFinger()
        {
            Finger(EventArgs.Empty);
        }
        //This method doesn't run too :(
        private void axCZKEM1_OnVerify(int iUserID)
        {
            VerifyEventArgs args = new VerifyEventArgs();
            args.UserID = iUserID;
            Verify(args);
        }
        public class VerifyEventArgs : EventArgs
        {
            public int UserID { get; set; }
        }
        protected virtual void Finger(EventArgs e)
        {
            EventHandler handler = OnFinger;
            if (handler != null)
                handler(this, e);
        }
        protected virtual void Verify(VerifyEventArgs e)
        {
            EventHandler<VerifyEventArgs> handler = OnVerify;
            if (handler != null)
                handler(this, e);
        }
    }
}

我的主要服务类别代码:

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Linq;
using System.Threading;
namespace MyNewService
{
    public class Service1 : System.ServiceProcess.ServiceBase
    {
        private System.Diagnostics.EventLog eventLog1;
        private System.ComponentModel.Container components = null;
        zkemkeeperHandler zkh;
        public Service1()
        {
            InitializeComponent();
            if (!System.Diagnostics.EventLog.SourceExists("DoDyLogSource"))
            {
                System.Diagnostics.EventLog.CreateEventSource("DoDyLogSource", "DoDyLog");
            } 
            eventLog1.Source = "DoDyLogSource";
            eventLog1.Log = "DoDyLog";
            eventLog1.WriteEntry("Preparing to start service");         
            try
            {
                startZKHandler();
            }
            catch (Exception ex)
            {
                eventLog1.WriteEntry(ex.InnerException.Message);
            }
        }
        private void startZKHandler()
        {
            eventLog1.WriteEntry("creating zkemkeeper handler class");
            zkh = new zkemkeeperHandler();
            zkh.OnFinger += OnFinger;
            zkh.OnVerify += OnVerify;
            zkh.startService();
        }
        private void stopZKHandler()
        {
            eventLog1.WriteEntry("Disconnecting from device (192.168.0.77)...");
            zkh.stopService();
        }
        private void writeLog2DB(string message)
        {
            try
            {
                eventLog1.WriteEntry("writing to database");
                DB.DBase.LogTable.AddObject(new LogTable
                {
                    ID = ++DB.IDCounter,
                    deviceLog = message
                });
                DB.DBase.SaveChanges();
            }
            catch (Exception ex)
            {
                eventLog1.WriteEntry(ex.Message + " - " + ex.InnerException.Message);
            }
            this.EventLog.Log = "Event Stored in DB.";
        }
        // The main entry point for the process
        static void Main()
        {
            System.ServiceProcess.ServiceBase[] ServicesToRun;
            ServicesToRun = new System.ServiceProcess.ServiceBase[] { new MyNewService.Service1()};
            System.ServiceProcess.ServiceBase.Run(ServicesToRun);   
        }
        private void InitializeComponent()
        {
            this.eventLog1 = new System.Diagnostics.EventLog();
            ((System.ComponentModel.ISupportInitialize)(this.eventLog1)).BeginInit();
            this.eventLog1.Log = "DoDyLog";
            this.eventLog1.Source = "DoDyLogSource";
            this.ServiceName = "MyNewService";
            ((System.ComponentModel.ISupportInitialize)(this.eventLog1)).EndInit();
        }
        protected override void Dispose( bool disposing )
        {
            if( disposing )
            {
                if (components != null) 
                {
                    components.Dispose();
                }
            }
            base.Dispose( disposing );
        }
        protected override void OnStart(string[] args)
        {
            // TODO: Add code here to start your service.
            eventLog1.WriteEntry("my service started");
        }
        protected override void OnStop()
        {
            // TODO: Add code here to perform any tear-down necessary to stop your service.
            eventLog1.WriteEntry("my service stoped");
            stopZKHandler();
        }
        protected override void OnContinue()
        {
            eventLog1.WriteEntry("my service is continuing in working");
        }
        private void OnFinger(object sender, EventArgs e)
        {
            eventLog1.WriteEntry("Finger Event Raised");
        }
        private void OnVerify(object sender, zkemkeeperHandler.VerifyEventArgs e)
        {
            eventLog1.WriteEntry("Verify Event Raised");
        }
    }
}

我犯了什么错?请帮帮我!

我编写的Windows服务可以引发自定义事件,但不能引发我的dll事件!

我知道这个线程很旧了,但我昨天遇到了这个问题,在浪费了很多小时之后,现在我终于找到了解决方案。问题是,COM对象必须从STA线程创建,然后,为了正确调度事件,同一STA线程(完全相同)必须泵送COM消息。这可以通过调用循环中的Application.DoEvents()或Application.Run().来完成

所以这是我的工作代码(它可以工作,即使是作为Vista+中的非交互式Windows服务,我使用的是Windows 8.1)

Thread createComAndMessagePumpThread = new Thread(() =>
{
    this.Device = new CZKEMClass(); //Here create COM object
    Application.Run();
});
createComAndMessagePumpThread.SetApartmentState(ApartmentState.STA);
createComAndMessagePumpThread.Start();

创建设备后,您可以从任何线程注册事件,这些事件由创建COM对象的STA线程调度。

在Windows窗体应用程序中,这在不执行此操作的情况下有效,因为STA主线程运行调用application.run(form).application.run()的窗体,然后调度COM事件和Windows GUI事件等事件,因此不需要使用上述技巧。

重新提出这个问题,因为我刚刚处理了一个相关的问题。显然,OP正在使用一些COM STA对象,这些对象需要一个STA线程和一个功能消息泵循环才能正常运行。默认情况下,Windows服务执行模型没有此功能。有关更多详细信息,请访问链接的答案。

您不能在Windows服务中使用事件。存在几个原因,为什么不呢?但我想为zkemgeeper提供一个的解决方案:
ZK发布了一个zkemkeeper.dll作为COM对象,用于处理Windows应用程序。当您将应用程序作为windows服务运行时,所有设备事件都将被激发,并且不会在应用程序中引发。尝试将引用System.Windows.Forms添加到项目中,并在成功连接后添加行:

Application.Run();

相关内容

  • 没有找到相关文章

最新更新