C#开发Activex控件(1)
项目结构
创建Activex步骤:
1.选择创建类别(Windows 控件库或类库)
2.设置对应的com属性
AssemblyInfo.cs中须做以下设置:
a.引入命名空间:using System.Security;
b.[assembly: AllowPartiallyTrustedCallers()]
3.生成的证书能正常在IE下安装,需继承IObjectSafety,考虑到所有的生成的证书都需继承自该接口,需写一个基类,代码如下:
a.接口代码:
using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; namespace LamSoonActivex { [ComImport, Guid("CB5BDC81-93C1-11CF-8F20-00805F2CD064")] [InterfaceType(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); } }
b.基类代码
using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; using System.Windows.Forms; namespace LamSoonActivex { public class BaseActivex : UserControl, IObjectSafety { private Sunisoft.IrisSkin.SkinEngine skinEngine1; #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) { //pdwSupportedOptions = 1; //pdwEnabledOptions = 2; //throw new Exception("The method or operation is not implemented."); //以上代码亦能正常运行,SetInterfaceSafetyOptions设置即可 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) { //throw new Exception("The method or operation is not implemented."); 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 InitializeComponent() { this.skinEngine1 = new Sunisoft.IrisSkin.SkinEngine(((System.ComponentModel.Component)(this))); this.SuspendLayout(); // // skinEngine1 // this.skinEngine1.SerialNumber = ""; this.skinEngine1.SkinFile = "\\Resources\\SportsBlue.ssk";//null; // // BaseActivex // this.Name = "BaseActivex"; this.Load += new System.EventHandler(this.BaseActivex_Load); this.ResumeLayout(false); } private void BaseActivex_Load(object sender, EventArgs e) { //skinEngine1.SkinFile = LamSoonActivex.Properties.Resources.l.ssk;// @"\Resources\SportsBlue.ssk"; } } }
4.证书编码
a.需在证书的[Guid("527A380F-7E26-4fd3-AEA5-010D3E7B73BE")],是在Web页中调用的Id,必须是唯一
b.须引入命名空间 using System.Runtime.InteropServices;
using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices; namespace LamSoonActivex { [Guid("527A380F-7E26-4fd3-AEA5-010D3E7B73BE")] public partial class FrmLamSoon : BaseActivex { public FrmLamSoon() { InitializeComponent(); } private void btnLogin_Click(object sender, EventArgs e) { if (txtStaff_Id.Text.Length == 0 || txtPwd.Text.Length == 0) { MessageBox.Show("请输入有效的系统登陆信息!", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } } }
5.Web UI调用
2种调用方式: <object id="helloworld" classid="clsid:527A380F-7E26-4fd3-AEA5-010D3E7B73BE" codebase="LamSoonActivex.exe"> </object> <object id="helloworld" classid="clsid:527A380F-7E26-4fd3-AEA5-010D3E7B73BE" codebase="LamSoonActivex.cab#version=1,0,1,0"> </object>
示例:
<html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>TestActivex</title> </head> <body> <form id="form1" runat="server"> <div style=" text-align:center"> <object id="activex_test" classid="clsid:527A380F-7E26-4fd3-AEA5-010D3E7B73BE" codebase="LamSoonActivex.cab#version=1,0,1,0"> </object> </div> </form> </body> </html>