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

2023-12-02

我确实编写了一个可以使用 dll 连接到网络设备的 Windows 服务。所以一切正常,但是事件处理程序在 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 事件等事件,因此不需要上述技巧。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Windows 服务 C# 中引发自定义类事件 的相关文章

  • 如何在 C++ 中对四元结构进行有效排序?

    我有一个包含 x y z 和 w 成员的结构 如何高效排序 在 C 中首先按 x 然后按 y 按 z 最后按 w 如果你想实现字典排序 那么最简单的方法是使用std tie实现小于或大于比较运算符或函子 然后使用std sort http
  • 使用 strcpy 从整数生成指针,无需进行强制转换

    我不明白我做错了什么 我正在学习 C 很抱歉 如果这显然是错误的 但我正在尝试使用uthash http uthash sourceforge net 制作股票及其价格的哈希图 但是当我将股票添加到哈希映射时 我收到上述错误 我所做的就是从
  • 如何通过实体键添加/删除与实体框架的多对多关系?

    I tried using Entities e new Entities EntityKey key new EntityKey Entities Users UserId 20 User user new User EntityKey
  • 确保 unsigned int/long 始终在 C# 中的检查上下文中执行

    有没有人觉得奇怪 uint 和 ulong 的默认上下文是未检查的 而不是检查的 因为它们旨在表示永远不能为负的值 因此 如果某些代码试图违反该约束 在我看来 自然且首选的行为是抛出异常 而不是返回最大值 这很容易使重要数据处于无效状态并且
  • Debug.WriteLine() 未命中

    我正在调试 Windows 服务 通过点击F5在 Visual Studio 2010 中 使用以下代码 In 程序 cs file static void Main if Environment UserInteractive We ar
  • 如何有效地左填充字节数组

    假设我有一个数组 LogoDataBy byte 0x00000008 0x00000000 0x41 0x00000001 0x42 0x00000002 0x43 0x00000003 0x44 0x00000004 0x31 0x00
  • MouseDoubleClick 事件不会冒泡

    我的场景经过简化 我有一个包含员工行的 ListView 在每个员工行中 都有 增加 和 减少 按钮来调整他的工资 假设在我的程序中 双击 员工 行意味着 解雇此人 The problem是当我快速单击 增加 时 这会触发 ListView
  • 会员提供商使用还是不使用?

    我正在开发一个使用 Facebook 的网站 现在为了管理用户我想使用MembershipProvider并选择开发一个定制的会员提供商 我的问题是我的数据库架构与标准成员资格架构不匹配 并且提供的用于覆盖的函数采用与我预期不同的参数 例如
  • DataGridView小数不排序

    好吧 我有一个 DataGridView 它的数据绑定如下 dataGridViewChartOre AutoGenerateColumns false dataGridViewChartOre DataSource xml GetOreC
  • C++在子类中调用虚方法

    我有以下课程 class A protected A inner public virtual void doSomething 0 class B public A void doSomething if inner NULL inner
  • 获取进程的所有 DLL

    我想获取为给定进程加载的所有 dll 的列表 我目前正在使用 NET框架4 0 我知道有一个bug https connect microsoft com VisualStudio feedback details 546430 syste
  • 使用 c# 中的 c++ ref 中的引用从 C# 调用 C++ 代码错误

    所以在我的 c dll 文件中我得到了以下函数 DLL void GetUserPass char userName char passWord userName ceva passWord altceva 现在我想从 c 调用它 但它给了
  • 如何使用 HttpClient 验证 Pardot API

    我花了大约一天的时间尝试对 Pardot API 进行身份验证 它不喜欢我尝试发布消息正文的方式 所以我想发布对我有用的解决方案 如果您有任何建议或替代方案 我想听听 ServicePointManager SecurityProtocol
  • 获取RFC返回的嵌套结构的值?

    我是 C 新手 我有 rfc 它以嵌套结构的形式从 SAP 系统返回数据 但是当我使用以下方式获取该数据时 IrfcTable table rfc getTable exporting parameter et customer 它仅返回第
  • 如何在PropertyGrid中自定义绘制GridItem?

    我想以与所有者在 ListView 详细信息 和其他控件中绘制项目类似的方式在 PropertyGrid 中绘制属性值 如果将属性声明为 Color 类型 则其值将使用字符串描述旁边的颜色样本来绘制 如果属性是图像类型 则在字符串描述旁边绘
  • 为什么 g++ 在编译的二进制文件中存储类名?

    我注意到如果我跑strings在我编译的程序上g 输出包含它使用的各种类的名称 该程序是用 O3并且没有 g or p 并且当我剥离二进制文件时 类名仍然存在 我想知道为什么有必要g 将此信息存储在二进制文件中 出现的类名似乎都是使用虚函数
  • 初始化二维数组时出现分段错误

    我已经检查过我的代码是否正确地划分了内存空间 但是一旦我尝试将 2D 数组初始化为某些值 然后对这些值求和 我就会在 2x2 数组上收到分段错误 我想最终将我的代码扩展到更大的数组 但我什至无法让它在这里工作 我知道有很多关于 malloc
  • 使用客户端 hello 消息进行 TLS 协议检测

    我需要检测网络流量中的 https 数据包 到目前为止 我将所有 443 标记为 https 但我不想再在这种情况下使用端口信息 检查客户端问候消息是否足够 Check 22 and version info 0300 0301 or 03
  • 比较 C# 中的对象属性[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 Locked 这个问题及其答案是locked help locked posts因为这个问题是题外话 但却具有历史意义 目前不接受新的答案或互动
  • Eclipse CDT C/C++:包含另一个项目的头文件

    我在 Eclipse CDT 中有两个 C 项目main and shared In shared我有一个名为calc h 我想在中使用这个标头main 所以我做了以下事情 added include calc h到相关文件main In

随机推荐