C# VS2010 编写 ActiveX

一、Win7下编写ActiveX控件,用作B/S插件。ActiveX只能用于ie内核的浏览器。

参考:

https://blog.****.net/hzh839900/article/details/54924944

https://www.cnblogs.com/boonya/p/8657369.html

二、创建方法

2.1 新建项目,选择Windows窗体控件,我选用的是.net 2.0 其它默认的窗体控件,

C# VS2010 编写 ActiveX

2.2 在新建的项目中点击右键进入项目配置界面,点击“程序集信息(I)”

C# VS2010 编写 ActiveX

2.3 在程序集信息界面里勾选“使程序集com可见”

C# VS2010 编写 ActiveX

2.4 点击项目配置界面“生成”,勾选“为com互操作注册”

C# VS2010 编写 ActiveX

2.5 打开项目的AssemblyInfo.cs 文件,加入[assembly: AllowPartiallyTrustedCallers()] 参数及using System.Security 引用。

三、ActiveX类库接口及成员继承及实现。

3.1 完成上述二的步骤已可生成一个可用作调试的dll及tld文件,据参考介绍要取得web浏览器的信任还必须实现一个名为“IObjectSafety”的接口及其成员。

3.2 创建IObjectSafety.cs接口文件及复制一下代码,并添加相关引用。

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

}

3.3 vs2010 工具 -->创建GUID 复制一个新建的GUID。

C# VS2010 编写 ActiveX

3.4 打开控件文件UserControl1.cs 把新建的GUID 复制到控件类的顶部并继承IObjectSafety接口

C# VS2010 编写 ActiveX

3.5 复制以下代码到控件类里头,实现IObjectSafety接口成员。

 #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

3.6 在UserControl1.cs 的可视化界面上拖进个button1。

C# VS2010 编写 ActiveX

 

3.7 双击button1 生成button1_Click事件,并创建一个名为Test1的测试方法,并在button1_Click中调用Test1函数。

C# VS2010 编写 ActiveX

3.8 点击“启动调试”运行如下

C# VS2010 编写 ActiveX

 

 

 

四、Asp.net 及js 调试并静态调用此ActiveX控件

4.1 在没有生成cab或msi文件前此控件可以用作一般的调试使用。

4.2 新建一个Asp.net 网站项目,在项目里添加一个dll文件夹,并把上述ActiveX 插件目录bin\Debug\里的ActiveXPf.dll及ActiveXPf.tlb文件添加到dll目录里头。

C# VS2010 编写 ActiveX

4.3 在一个Default.aspx 文件里添加一个object元素

id="Object1"

classid="clsid:6DB586EE-32F4-4C38-8D81-F2153D2DE72E"  即刚才用GUID生成并放置控件类顶头的那串字符

codebase="/dll/ActiveXPf.dll"

C# VS2010 编写 ActiveX

4.4  设置ie 浏览器 Internet 选项 -->安全 本地Intranet中的ActiveX控件和插件

"ActiveX 控件自动提示" 启用

“对未标记为可安全执行脚本的ActiveX控件初始化并....”启用

“下载未签名的ActiveX 控件” 启用

“运行 ActiveX 控件和插件” 启用 

4.5 启动调试Asp.net Default.aspx页面

C# VS2010 编写 ActiveX

4.6 js传参及调用ActiveX

4.6.1 在Asp.net的Scripts文件价加入一个js文件 名为Testjs.js,并复制如下代码

C# VS2010 编写 ActiveX
function Test1() {
    try {
        var p = document.getElementById("Object1");
        var s = p.Test1("你好!");
        alert(s);
    }
    catch (e) {
        alert('错误2 ' + e.message + ' 发生在 ' + e.lineNumber + ' 行 ' + s);
    }
}

4.6.2 在Default.aspx 页面中加入一个input button,并引入Testjs.js文件
    <input type="button" οnclick="Test1()" value="别按我" />
    <script src="Scripts/Testjs.js" type="text/javascript"></script>

C# VS2010 编写 ActiveX

4.6.3 启动调试Default.aspx页面 并点击 input 里的“别按我” button ,ie11弹出如下提示

C# VS2010 编写 ActiveX

查找原因原来是ie的ActiveX插件设置问题,要把“对未标记为可安全执行脚本的ActiveX 控件初始化并...”从提示设置为启动。

C# VS2010 编写 ActiveX

再次点击“别按我”button出现两个提示,表示js调用ActiveX成功。

C# VS2010 编写 ActiveX

五、生成cab文件及签名发布等操作。

略...