Raising custom class events in a C # Windows service

I wrote a windows service that can connect to a network device using dll. so everything works fine, but the event handler does not work in win service! here is my code:

My custom class:

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);
        }
    }
}

Code of my main service:

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");
        }

    }
}

What's my mistake? please help me!

The Windows service I wrote can raise custom events, but it cannot raise my DLL events!

+2
source share
3 answers

, , , , , , . , COM- STA, , , STA ( ) COM . , Application.DoEvents() Application.Run().

, ( , Windows Vista +, Windows 8.1)

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

, STA, COM-.

Windows Forms , STA , Application.Run(Form). Application.Run() , COM- Windows GUI, .

+2

, . -, COM STA, STA . Windows . . .

+2

You cannot use events in a Windows service. There are several reasons why not, but I would like to offer a just solution for zkemkeeper:
ZK released zkemkeeper.dll as a COM object for working with Windows Application. All device events will be triggered and not appear in your application when you launch it as a Windows service. Try adding the System.Windows.Forms link to the project and after successful connection add the line:

Application.Run();
0
source

Source: https://habr.com/ru/post/1524339/


All Articles