Windows系统服务+C#WebSocket服务+C#调用ActiveX实现多种浏览器调用ActiveX插件

C#是微软的产物,所以其生成的COM组件目前只能提供给IE使用。

实现网页和本地系统双向调用的方法IE使用ActiveX控件,而在Chrome、FireFox等浏览器有类似的NPAPI插件技术。

开发ActiveX较为简单,开发NPAPI教程较少。

微软新生代浏览器Edge不再支持ActiveX控件,且除了IE其他浏览器基本不兼容ActiveX。

采用Windows系统服务启动WebSocket服务,接收网页客户端发送的指令信息完成相关操作,实现多种浏览器调用ActiveX插件。

C#ActiveX插件制作https://blog.csdn.net/qq_25189723/article/details/101544749

所有测试都支持.Net3.5 

 

Windows系统服务_C#WebSocket服务_C#调用ActiveX实现多种浏览器调用ActiveX插件例子下载

 

一、Windows服务

新建Windows服务项目

Windows系统服务+C#WebSocket服务+C#调用ActiveX实现多种浏览器调用ActiveX插件_第1张图片

设计视图中切换到代码视图

Windows系统服务+C#WebSocket服务+C#调用ActiveX实现多种浏览器调用ActiveX插件_第2张图片

重写OnStart和OnStop方法


    public partial class EL100Service : ServiceBase
    {
        public EL100Service()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
            WriteMessage("服务启动");
        }

        protected override void OnStop()
        {
            WriteMessage("服务停止");
        }
        //写文件验证启动
        public void WriteMessage(string msg)
        {
            StreamWriter dout = new StreamWriter(@"D:\" + "EL100WindowsServiceLog.txt", true);
            dout.Write("\r\n" + System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " " + msg);
            dout.Close();
        }
    }

设计视图上右键 点 添加安装程序

Windows系统服务+C#WebSocket服务+C#调用ActiveX实现多种浏览器调用ActiveX插件_第3张图片

系统会自动生成“ProjectInstaller.cs”文件,在该文件的设计视图界面会有两个控件,一个是serviceProcessInstaller1,一个是serviceInstaller1

serviceInstaller1属性中设置:

    Description(系统服务的描述)

    DisplayName (系统服务中显示的名称)

    ServiceName(系统事件查看器里的应用程序事件中来源名称)

    StartType(启动服务的方式,分为手动、自动和禁用)

Windows系统服务+C#WebSocket服务+C#调用ActiveX实现多种浏览器调用ActiveX插件_第4张图片

serviceProcessInstaller1属性设置:

    Account 下拉设置成 LocalSystem

生成服务程序之后,使用InstallUtil.exe进行服务的安装(该文件可能在C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\)

安装使用命令 InstallUtil EL100WindowsService.exe

Windows系统服务+C#WebSocket服务+C#调用ActiveX实现多种浏览器调用ActiveX插件_第5张图片

卸载使用命令 InstallUtil -u EL100WindowsService.exe

Windows系统服务+C#WebSocket服务+C#调用ActiveX实现多种浏览器调用ActiveX插件_第6张图片

启动服务或手动启动

NET START EL100ActiveXService

Windows系统服务+C#WebSocket服务+C#调用ActiveX实现多种浏览器调用ActiveX插件_第7张图片

Windows系统服务+C#WebSocket服务+C#调用ActiveX实现多种浏览器调用ActiveX插件_第8张图片

二、WebSocket

启动服务

如建控制台应用测试

websocket-sharp.dll

using WebSocketSharp.Server;
        static void Main(string[] args)
        {
            WebSocketServer webSocketServer = new WebSocketServer(23981);
            webSocketServer.AddWebSocketService("/el100activex"); 
            webSocketServer.Start();
            Console.WriteLine("服务启动");
            Console.ReadKey();
        }

消息处理

using WebSocketSharp;
using WebSocketSharp.Server;
    public class EL100ActiveXMessageHandler : WebSocketBehavior
    {
        protected override void OnOpen()
        {
            Console.WriteLine("建立连接" + ID);
            Broadcast(string.Format("{0}上线了,共有{1}人在线", ID, Sessions.Count));
        }
        protected override void OnClose(CloseEventArgs e)
        {
            Console.WriteLine("连接关闭" + ID);
            Broadcast(string.Format("{0}下线,共有{1}人在线", ID, Sessions.Count));
        }

        protected override void OnError(WebSocketSharp.ErrorEventArgs e)
        {
            Console.WriteLine("错误!");
        }
        protected override void OnMessage(MessageEventArgs e)
        {
            Console.WriteLine("收到消息:" + e.Data);
            Send(ID+":" +e.Data);
        }

        private void Broadcast(string msg)
        {
            Sessions.Broadcast(msg);
        }
    }

HTML测试



    测试WebSocket


内容:

Windows系统服务+C#WebSocket服务+C#调用ActiveX实现多种浏览器调用ActiveX插件_第9张图片

三、C#调用ActiveX

可建控制台应用测试

using System;
using System.Reflection;
        private static Type type;
        private static object activexobj;
        static void Main(string[] args)
        {
            try {
                if (type == null) {
                    Console.WriteLine("查找插件");
                    //根据classId获取ActiveX类
                    type = Type.GetTypeFromCLSID(new Guid("881BF978-EE89-4D08-9396-D5BE3F253615"));
                    if (type == null)
                    {
                        Console.WriteLine("插件不存在");
                        return;
                    }
                    Console.WriteLine("插件存在");
                }
                if (activexobj == null) {
                    Console.WriteLine("初始化插件");
                    //创建类的实例,第二个参数是object数组,就是你的构造方法里面的参数,
                    //null即为无参构造方法,也可以这么写:
                    //activexobj = Activator.CreateInstance(type);
                    activexobj = Activator.CreateInstance(type, null);
                    if (activexobj == null)
                    {
                        Console.WriteLine("插件初始化失败");
                        return;
                    }
                    Console.WriteLine("插件初始化成功");
                }
                //获取实例的指定方法,根据方法名,还有其他重载,也可以根据参数找
                MethodInfo methodInfo = type.GetMethod("GetStr");
                if (methodInfo == null) {
                    Console.WriteLine("方法错误");
                    return;
                }
                Console.WriteLine("方法正确");
                //调用该方法的参数,按顺序
                object[] GetComPortStr_para = new object[] { "测试参数" };
                //调用方法,返回值是object
                String operate_result = (String)methodInfo.Invoke(activexobj, GetComPortStr_para);
                operate_result = operate_result.Replace("\"", "\\\"");
                Console.WriteLine(operate_result);
            }
            catch (Exception exception)
            {
                Console.WriteLine(exception);
            }
            Console.ReadKey();
        }

Windows系统服务+C#WebSocket服务+C#调用ActiveX实现多种浏览器调用ActiveX插件_第10张图片

常见错误

System.Runtime.InteropServices.COMException (0x80040154): 检索 COM 类工厂中 CLSID 为 {881BF978-EE89-4D08-9396-D5BE3F253615} 的组件时失败,原因是出现以下错误: 80040154。

-->

不存在插件。

或项目右键属性-生成-平台目标x86。

Windows系统服务+C#WebSocket服务+C#调用ActiveX实现多种浏览器调用ActiveX插件_第11张图片

将websocket服务和调用ActiveX插件集成到Windows服务里就可以实现多种浏览器网页调用ActiveX插件了。

ActiveX插件实现的功能也可以直接在Windows服务里实现,只是已经开发完ActiveX只是为了适应其他浏览器就直接调用了。

四、通配传参调用

以参数及返回类型都为字符串为例。

特殊的可以switch。

网页发送方法和参数(可多个参数)的json字符串


		function sendMsg(operatemethod, operateparameter){
		    console.info("operatemethod="+operatemethod +" operateparameter="+operateparameter);
			
			var send_object = {};
			$(send_object).attr("operatemethod", operatemethod);
			var operateparameter_object = {};
			if(operateparameter!=null && operateparameter!=""){
				$(operateparameter_object).attr("arg0", operateparameter);
			}
			$(send_object).attr("operateparameter", operateparameter_object);
			websocket.send(JSON.stringify(send_object));
		}

C#使用 Json.Net35和Newtonsoft.Json(之前用的Json.Net35文件小,但实现不了嵌套JSON的解析,换Newtonsoft之前实现的序列化也没改。)

Windows系统服务+C#WebSocket服务+C#调用ActiveX实现多种浏览器调用ActiveX插件_第12张图片

Windows系统服务+C#WebSocket服务+C#调用ActiveX实现多种浏览器调用ActiveX插件_第13张图片


                JObject rece_JObj = JObject.Parse(e.Data);
                operatemethod_str = rece_JObj["operatemethod"].ToString();
                methodInfo = type.GetMethod(operatemethod_str);
                if (methodInfo == null)
                {
                    SendErrorMsg(operatemethod_str, "方法错误");
                    isTesting = false; return;
                }
                //调用该方法的参数,按顺序
                //object[] GetComPortStr_para = new object[] { };
                List operateparameterList = new List();

                var operateparameter_obj = rece_JObj["operateparameter"];
                if (operateparameter_obj == null)
                {
                    //SendDebugMsg(operatemethod_str, "无参");
                }
                else
                {
                    JObject operateparameter = JObject.Parse(operateparameter_obj.ToString());
                    foreach (JProperty jProperty in operateparameter.Properties())
                    {
                        SendDebugMsg(operatemethod_str, "key:" + jProperty.Name + " value:" + jProperty.Value);
                        operateparameterList.Add(jProperty.Value.ToString());
                    }
                }
                //调用方法,返回值是object,我的方法返回void,所以不写
                String operate_result = (String)methodInfo.Invoke(activexobj, operateparameterList.ToArray());
                operate_result = operate_result.Replace("\"", "\\\"");
                SendSuccMsg(operatemethod_str, operate_result);



        private void SendMsg(string code, string operatemethod, string msg)
        {
            fileOperate.WriteMessage("发送消息:" + msg);
            var data = new JsonDto() { code = code, msg = msg, operatemethod = operatemethod };
            Send(Json.JsonParser.Serialize(data));
        }

        private void SendSuccMsg(string operatemethod, string msg)
        {
            SendMsg("1", operatemethod, msg);
        }




    class JsonDto
    {
        public string code { get; set; }
        public string msg { get; set; }
        public string operatemethod { get; set; }
        public object operateparameter { get; set; }
    }

Windows系统服务+C#WebSocket服务+C#调用ActiveX实现多种浏览器调用ActiveX插件_第14张图片

你可能感兴趣的:(软件开发,C#Windows系统服务,C#WebSocket服务,C#调用ActiveX)