原创

Vs2019使用C#开发ActiveX插件

本文主要介绍:

1、用C#制作Activex控件,并发布为msi安装文件
2、将Activex应用到网页上

1、用C#制作Activex控件,并发布为msi安装文件

1.1 新建项目

打开VS2019,新建Windows窗体控件库

file

填好项目名、选择项目地址,点击创建

file

然后在项目中添加IObjectSafety接口

file
IObjectSafety接口代码如下,注意guid值不能随意更改

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;

namespace HYHCService
{
    [ComImport, Guid("CB5BDC81-93C1-11CF-8F20-00805F2CD064")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IObjectSafety
    {
        [PreserveSig]
        int GetInterfaceSafetyOptions(ref Guid riid, [MarshalAs(UnmanagedType.U4)] ref int pdwSupportedOptions, [MarshalAs(UnmanagedType.U4)] ref int pdwEnabledOptions);

        [PreserveSig()]
        int SetInterfaceSafetyOptions(ref Guid riid, [MarshalAs(UnmanagedType.U4)] int dwOptionSetMask, [MarshalAs(UnmanagedType.U4)] int dwEnabledOptions);
    }
}
修改创建项目后生成的UserControl1.cs,没有的话自己见一个用户控件,需要继承IObjectSafety接口

UserControl1.cs代码如下

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace ActiveXDemo
{
    [Guid("1E53E6CD-20B3-4AB0-8293-B8A99611F548"), ProgId("ActiveXDemo.UserControl1"), ComVisible(true)]
    public partial class UserControl1 : UserControl, IObjectSafety
    {

        public UserControl1()
        {
            InitializeComponent();
        }

        private void HYVoiceControl_Load(object sender, EventArgs e)
        {

        }

        #region IObjectSafety 成员

        private const string _IID_IDispatch = "{00020400-0000-0000-C000-000000000046}";
        private const string _IID_IDispatchEx = "{a6ef9860-c720-11d0-9337-00a0c90dcaa9}";
        private const string _IID_IPersistStorage = "{0000010A-0000-0000-C000-000000000046}";
        private const string _IID_IPersistStream = "{00000109-0000-0000-C000-000000000046}";
        private const string _IID_IPersistPropertyBag = "{37D84F60-42CB-11CE-8135-00AA004BB851}";

        private const int INTERFACESAFE_FOR_UNTRUSTED_CALLER = 0x00000001;
        private const int INTERFACESAFE_FOR_UNTRUSTED_DATA = 0x00000002;
        private const int S_OK = 0;
        private const int E_FAIL = unchecked((int)0x80004005);
        private const int E_NOINTERFACE = unchecked((int)0x80004002);

        private bool _fSafeForScripting = true;
        private bool _fSafeForInitializing = true;

        public int GetInterfaceSafetyOptions(ref Guid riid, ref int pdwSupportedOptions, ref int pdwEnabledOptions)
        {
            int Rslt = E_FAIL;

            string strGUID = riid.ToString("B");
            pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA;
            switch (strGUID)
            {
                case _IID_IDispatch:
                case _IID_IDispatchEx:
                    Rslt = S_OK;
                    pdwEnabledOptions = 0;
                    if (_fSafeForScripting == true)
                        pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER;
                    break;
                case _IID_IPersistStorage:
                case _IID_IPersistStream:
                case _IID_IPersistPropertyBag:
                    Rslt = S_OK;
                    pdwEnabledOptions = 0;
                    if (_fSafeForInitializing == true)
                        pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA;
                    break;
                default:
                    Rslt = E_NOINTERFACE;
                    break;
            }

            return Rslt;
        }

        public int SetInterfaceSafetyOptions(ref Guid riid, int dwOptionSetMask, int dwEnabledOptions)
        {
            int Rslt = E_FAIL;
            string strGUID = riid.ToString("B");
            switch (strGUID)
            {
                case _IID_IDispatch:
                case _IID_IDispatchEx:
                    if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_CALLER) && (_fSafeForScripting == true))
                        Rslt = S_OK;
                    break;
                case _IID_IPersistStorage:
                case _IID_IPersistStream:
                case _IID_IPersistPropertyBag:
                    if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_DATA) && (_fSafeForInitializing == true))
                        Rslt = S_OK;
                    break;
                default:
                    Rslt = E_NOINTERFACE;
                    break;
            }

            return Rslt;
        }

        #endregion

        #region 自己的方法

        public string Work(string msg)
        {

            try
            {
                return "接收到:" + msg;
            }
            catch (Exception exp)
            {
                return "-99|Work_" + exp.Message;

            }

        }

        #endregion
    }
}

提示:UserControl代码的Guid可以用VS自带的Guid生成工具生成
file

将项目属性改为COM可见

file
file
file
以上步骤就增加好了ActiveX控件,但是我们使用过程中需要将程序改为安装程序,方便后续使用

1.2、发布成MSI

VS2019发布安装程序需要安装一个InstallerProjects插件,可以在VS>扩展>管理扩展中搜索后安装
file
也可以在官网下载,注意,没有安装插件是无法新建SetUp Project 项目的。

右键解决方案,添加新建SetUp Project 项目

file

将项目生成的ActiveXDemo.dll添加到安装项目中

file

将安装项目中,ActiveXDemo.dll文件属性改为vsdraCOM

file
完成以上步骤,生成后即可得到msi安装文件

2、在网页中调用ActiveX插件

2.1 安装MSI文件

双击上面生成的MSI文件,直接下一步到文成
然后新建网页

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />


    <title>CSharpActiveX测试</title>
</head>
<body>
<object id="cSharpActiveX" classid="clsid:1E53E6CD-20B3-4AB0-8293-B8A99611F548" codebase="CSharpActiveX.CAB#version=1,0,0" ></object>
    <script type="text/javascript" language="javascript" defer="defer">

        function click(){
            var activeX = document.getElementById("cSharpActiveX");
            console.info(activeX);
            console.info(activeX.Work("点击按钮"));
        }
    </script>
</body>
<button onclick="click()">测试按钮</button>
</html>

点击按钮能后看到返回的信息。
大功告成!!!!!!!!!

正文到此结束