历史最全的C#开发ActiveX

--资料来源互联网

第一步:创建C#类库项目,修改“名称”为HuaYun.ActiveX



 第二步:修改AssemblyInfo.cs,增加代码

//自定添加
[assembly: AllowPartiallyTrustedCallers()]

 

第三步:右键工程,“添加”-“用户控件”命名为“ActiveXControl.cs”


第四步:按照第三步的方法添加接口IObjectSafety.cs

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

namespace HuaYun.ActiveX
{
    [ComImport, GuidAttribute("CB5BDC81-93C1-11CF-8F20-00805F2CD064")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
    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);
    }
}

 第五步:添加调用JS的接口IOleClientSite.cs,IOleContainer.cs

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

namespace HuaYun.ActiveX
{
    [ComImport,Guid("00000118-0000-0000-C000-000000000046"),InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    interface IOleClientSite
    {
        void SaveObject();
        void GetMoniker(uint dwAssign, uint dwWhichMoniker, object ppmk);
        void GetContainer(out IOleContainer ppContainer);
        void ShowObject();
        void OnShowWindow(bool fShow);
        void RequestNewObjectLayout();
    }


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

namespace HuaYun.ActiveX
{

    [ComImport,Guid("0000011B-0000-0000-C000-000000000046"),InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
    interface IOleContainer
    {
        void EnumObjects([In, MarshalAs(UnmanagedType.U4)] int grfFlags,
        [Out, MarshalAs(UnmanagedType.LPArray)] object[] ppenum);
        void ParseDisplayName([In, MarshalAs(UnmanagedType.Interface)] object pbc,
        [In, MarshalAs(UnmanagedType.BStr)] string pszDisplayName,
        [Out, MarshalAs(UnmanagedType.LPArray)] int[] pchEaten,
        [Out, MarshalAs(UnmanagedType.LPArray)] object[] ppmkOut);
        void LockContainer([In, MarshalAs(UnmanagedType.I4)] int fLock);
    }
}

 第六步:编写ActiveXControl.cs代码,类上的GUID很关键这个就是“Object”的“classid”

ps:<object classid="clsid:de4479a4-af99-45b0-b0ce-d72bd4c2c37d" ></object>

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Reflection;
using mshtml;

namespace HuaYun.ActiveX
{
    [Guid("21209360-34E1-423E-A81F-BC80B62021B7")]
    public partial class ActiveXControl : UserControl, IObjectSafety
    {
        public ActiveXControl()
        {
            InitializeComponent();
        }

        #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

        private void button1_Click(object sender, EventArgs e)
        {
            this.CallJavaScript("sex");
        }

        private void ActiveXControl_Load(object sender, EventArgs e)
        {

        }

        // 被JS调用的ActiveX方法
        public void SayHi(string msg)
        {
            MessageBox.Show(msg);
        }

        // 调用JS方法
        private void CallJavaScript(string filename)
        {
            Type typeIOleObject = this.GetType().GetInterface("IOleObject", true);
            object oleClientSite = typeIOleObject.InvokeMember("GetClientSite",BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public, null,this,null);
            IOleClientSite oleClientSite2 = oleClientSite as IOleClientSite;
            IOleContainer pObj;
            oleClientSite2.GetContainer(out pObj);
            //参数数组
            object[] args = new object[1];
            args[0] = filename;

            //获取页面的Script集合
            IHTMLDocument pDoc2 = (IHTMLDocument)pObj;
            object script = pDoc2.Script;
            try
            {
                //调用JavaScript方法OnScaned并传递参数,因为此方法可能并没有在页面中实现,所以要进行异常处理
                script.GetType().InvokeMember("OnScaned",BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public, null, script, args);
            }
            catch
            {

            }
        }
    }
    
}

 ps:以上完成了编码工作,现在要生成项目,我使用的是VS2017没有安装部署工具需要在“工具”-“扩展和更新”找到“Mircrosoft Visual Studio 2017 Installer Projects”下载安装。

补充步骤:右键工程属性,“应用程序”-“程序集信息”勾选使程序集COM可见。“生成”勾选为COM互操作注册

第七步:创建安装项目命名为“TYacticeX”,ps:右键工程顶级菜单


第八步:修改工程属性,将“RemovePreviousVers”的值设置为True


第九步:右键安装项目,“Add”-“项目输出”-“主输出”,然后输出安装文件,一个exe和一个msi


 第十步:开始写对应的html代码与JS代码

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
	<head>
		<script type="text/javascript">
			function OnScaned (filename){
				document.getElementById("dx").value =filename; 
			}
		</script>
	</head>
	<body>
		<label for="jsCall">js call ActiveX:</label>
		<button id="jsCall" onclick="csharpActiveX.SayHi('hello word');">call</button>
		<br/>
		<label for="dx">activeX call JS:</label>
		<input name="dx" id="dx" type="text" />
		<object id="csharpActiveX" classid="clsid:21209360-34E1-423E-A81F-BC80B62021B7" codebase="lib/setup.exe"
        width="800" height="200" id="helloBossma">
		</object>
	</body>
</html>

 ps:已经可以开始测试了。

 

猜你喜欢

转载自blog.csdn.net/aa80303857/article/details/84921293
今日推荐