http://www.cnblogs.com/yjmyzz/archive/2009/12/14/1623396.html

1.为什么要用ActiveX?

网页本身的功能是有限的,要想实现一些网页本身不支持的功能,比如:网页上的p2p视频播放,就得靠ActiveX这种古老的技术。

2.c#能开发ActiveX吗?

严格意义上讲,c#是不能生成纯正ocx控件的,我们在vs.net中新建项目时,也找不到专门的"ActiveX项目"新建项,最多也只就能新 建"类库"得到一个dll而非ocx(因此我们也无法用传统的regsvr32来注册该dll),但是c#能开发com组件,activeX控件本质上讲 跟com是一类技术,所以用c#开发"能够让网页调用的com类库"还是可行的。

3.开发步骤:

(1)新建一个类库
(2)修改项目的"属性",在“生成”选项中把“输出”中的“为com互操作注册”勾中,然后再到“应用程序”选项中找到“程序集信息”按钮,点击它,在弹出的界面中勾中“使程序集COM可见(M)”

(3)修改AssemblyInfo.cs,增加[assembly: AllowPartiallyTrustedCallers()],完整内容类似下面这样:

  1.  
  2.  1 using System.Reflection;
  3.  2 using System.Runtime.CompilerServices;
  4.  3 using System.Runtime.InteropServices;
  5.  4 using System.Security;
  6.  5 
  7.  6 // General Information about an assembly is controlled through the following 
  8.  7 // set of attributes. Change these attribute values to modify the information
  9.  8 // associated with an assembly.
  10.  9 [assembly: AssemblyTitle("ActiveXDemo")]
  11. 10 [assembly: AssemblyDescription("")]
  12. 11 [assembly: AssemblyConfiguration("")]
  13. 12 [assembly: AssemblyCompany("Microsoft")]
  14. 13 [assembly: AssemblyProduct("ActiveXDemo")]
  15. 14 [assembly: AssemblyCopyright("Copyright ? Microsoft 2009")]
  16. 15 [assembly: AssemblyTrademark("")]
  17. 16 [assembly: AssemblyCulture("")]
  18. 17 [assembly: AllowPartiallyTrustedCallers()]
  19. 18 
  20. 19 // Setting ComVisible to false makes the types in this assembly not visible 
  21. 20 // to COM components.  If you need to access a type in this assembly from 
  22. 21 // COM, set the ComVisible attribute to true on that type.
  23. 22 [assembly: ComVisible(true)]
  24. 23 
  25. 24 // The following GUID is for the ID of the typelib if this project is exposed to COM
  26. 25 [assembly: Guid("bd585d12-7f22-4b3f-959f-18efbfc53f94")]
  27. 26 
  28. 27 // Version information for an assembly consists of the following four values:
  29. 28 //
  30. 29 //      Major Version
  31. 30 //      Minor Version 
  32. 31 //      Build Number
  33. 32 //      Revision
  34. 33 //
  35. 34 // You can specify all the values or you can default the Build and Revision Numbers 
  36. 35 // by using the '*' as shown below:
  37. 36 // [assembly: AssemblyVersion("1.0.*")]
  38. 37 [assembly: AssemblyVersion("1.0.0.0")]
  39. 38 [assembly: AssemblyFileVersion("1.0.0.0")]

(4)新建一个IObjectSafety接口文件IObjectSafety.cs,内容如下:

  1.  
  2.  1 using System;
  3.  2 using System.Collections.Generic;
  4.  3 using System.Text;
  5.  4 using System.Runtime.InteropServices;
  6.  5 
  7.  6 namespace ActiveXDemo
  8.  7 {
  9.  8     [ComImport, GuidAttribute("CB5BDC81-93C1-11CF-8F20-00805F2CD064")]
  10.  9     [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
  11. 10     public interface IObjectSafety
  12. 11     {
  13. 12         [PreserveSig]
  14. 13         int GetInterfaceSafetyOptions(ref Guid riid, [MarshalAs(UnmanagedType.U4)] ref int pdwSupportedOptions, [MarshalAs(UnmanagedType.U4)] ref int pdwEnabledOptions);
  15. 14 
  16. 15         [PreserveSig()]
  17. 16         int SetInterfaceSafetyOptions(ref Guid riid, [MarshalAs(UnmanagedType.U4)] int dwOptionSetMask, [MarshalAs(UnmanagedType.U4)] int dwEnabledOptions);
  18. 17     }
  19. 18 
  20. 19 }

该内容除命名空间可以更改外,其它内容都是固定的,不要修改
(5)新建一个:Windows Forms-->“用户控件”,我们的主要逻辑就写在这里(还可以在它上面随便放置其它windows常用控件,跟winForm开发一样),不过首先要修改类定义,让其实现我们刚才定义的接口

  1.  
  2.   1 using System;
  3.   2 using System.Runtime.InteropServices;
  4.   3 using System.Threading;
  5.   4 using System.Windows.Forms;
  6.   5 
  7.   6 
  8.   7 namespace ActiveXDemo
  9.   8 {
  10.   9     [Guid("8d7d8518-ca58-4863-b94d-3c616fda7b35")]
  11.  10     public partial class MyActiveX : UserControl,IObjectSafety
  12.  11     {
  13.  12         delegate void D(object obj);
  14.  13 
  15.  14         public MyActiveX()
  16.  15         {
  17.  16             InitializeComponent();
  18.  17         }
  19.  18 
  20.  19         #region IObjectSafety 成员
  21.  20 
  22.  21         private const string _IID_IDispatch = "{00020400-0000-0000-C000-000000000046}";
  23.  22         private const string _IID_IDispatchEx = "{a6ef9860-c720-11d0-9337-00a0c90dcaa9}";
  24.  23         private const string _IID_IPersistStorage = "{0000010A-0000-0000-C000-000000000046}";
  25.  24         private const string _IID_IPersistStream = "{00000109-0000-0000-C000-000000000046}";
  26.  25         private const string _IID_IPersistPropertyBag = "{37D84F60-42CB-11CE-8135-00AA004BB851}";
  27.  26 
  28.  27         private const int INTERFACESAFE_FOR_UNTRUSTED_CALLER = 0x00000001;
  29.  28         private const int INTERFACESAFE_FOR_UNTRUSTED_DATA = 0x00000002;
  30.  29         private const int S_OK = 0;
  31.  30         private const int E_FAIL = unchecked((int)0x80004005);
  32.  31         private const int E_NOINTERFACE = unchecked((int)0x80004002); 32  33         private bool _fSafeForScripting = true; 34         private bool _fSafeForInitializing = true; 35  36         public int GetInterfaceSafetyOptions(ref Guid riid, ref int pdwSupportedOptions, ref int pdwEnabledOptions) 37         { 38             int Rslt = E_FAIL; 39  40             string strGUID = riid.ToString("B"); 41             pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA; 42             switch (strGUID) 43             { 44                 case _IID_IDispatch: 45                 case _IID_IDispatchEx: 46                     Rslt = S_OK; 47                     pdwEnabledOptions = 0; 48                     if (_fSafeForScripting == true) 49                         pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER; 50                     break; 51                 case _IID_IPersistStorage: 52                 case _IID_IPersistStream: 53                 case _IID_IPersistPropertyBag: 54                     Rslt = S_OK; 55                     pdwEnabledOptions = 0; 56                     if (_fSafeForInitializing == true) 57                         pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA; 58                     break; 59                 default: 60                     Rslt = E_NOINTERFACE; 61                     break; 62             } 63  64             return Rslt; 65         } 66  67         public int SetInterfaceSafetyOptions(ref Guid riid, int dwOptionSetMask, int dwEnabledOptions) 68         { 69             int Rslt = E_FAIL; 70             string strGUID = riid.ToString("B"); 71             switch (strGUID) 72             { 73                 case _IID_IDispatch: 74                 case _IID_IDispatchEx: 75                     if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_CALLER) && (_fSafeForScripting == true)) 76                         Rslt = S_OK; 77                     break; 78                 case _IID_IPersistStorage: 79                 case _IID_IPersistStream: 80                 case _IID_IPersistPropertyBag: 81                     if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_DATA) && (_fSafeForInitializing == true)) 82                         Rslt = S_OK; 83                     break; 84                 default: 85                     Rslt = E_NOINTERFACE; 86                     break; 87             } 88  89             return Rslt; 90         } 91  92         #endregion 93  94         private void MyActiveX_Load(object sender, EventArgs e) 95         { 96              97         } 98  99 100         public void Start(object obj) 101         {102             for (int i = 0; i < 10; i++)103             {104                 Thread t = new Thread(new ParameterizedThreadStart(ShowTime));105                 t.Start(obj.ToString() + ",线程:" + i.ToString());                106             }        107         }108 109         private void button1_Click(object sender, EventArgs e)110         {111             Start("Hello World");112         }113 114         void ShowTime(object obj)115         {116             if (this.listBox1.InvokeRequired)117             {118                 D d = new D(DelegateShowTime);119                 listBox1.Invoke(d, obj);120             }121             else122             {123                 this.listBox1.Items.Add(obj);124             }125 126             127         }128 129 130         void DelegateShowTime(object obj)131         {132             this.listBox1.Items.Add(obj);133         }134 135 136     }137 }

#region IObjectSafety 成员 ... #endregion这一段的内容是固定的,不要修改,其它内容根据自己的业务要求自行修改,另外类前面要加上Guid的标识,以便网页调用时,能用CLSID="xxx"来调用

基本上这样弄完后,就可以在网页中,用类似下面这样的代码来本机调用了:

注意:c#定义的public方法,如果想直接让js调用,只能返回string,DateTime,int,double这一类基本值类型,其它返回类型比如array,object,在js中要么直接报错,要么得到null

  1.  
  2. 1 <object id="x" classid="clsid:8d7d8518-ca58-4863-b94d-3c616fda7b35"></object>
  3. 2 <hr />
  4. 3 <input type="button" value="调用ActiveX中的多线程方法" onclick="fnTest()" />
  5. 4 <script type="text/javascript">
  6. 5 var fnTest = function(){
  7. 6     var x = document.getElementById("x");
  8. 7     x.Start("这是js中的参数");
  9. 8 }
  10. 9 </script>

4.安装部署

前面已经提到了,c#开发的(伪)"ActiveX"控件并非纯正的ocx,所以只能用RegAsm.Exe
xxx.dll来进行程序集的注册,这里要注意一点:在开发机上,项目编译后vs.net会自动将bin\debug\xxx.dll调用regasm注
册,但在别人机器上就不行了,为了能在调试时模拟其它机器的运行结果,可以在编译后,手动用类似 regAsm.exe
D:\MyDoc\ActiveXDemo\output\ActiveXDemo.dll /u 来反注册(在vs.net命令行模式下)

然后在安装项目上,右键"添加"-->"项目输出"-->"主输出"-->在项目下拉框中选择activex所对应的项目即可.

注意:"主输出来自xxx"的属性栏中,有一个"Register"必须选择"vsdrpCOM"

另外还有一个问题,可能是我机器的个别现象,每次activex项目有修改时,建议最好手动清除安装项目debug目录下的文件,再重新生成安装项目,否则有时候会发现activex修改了,但是安装包中包含的dll还是未修改过的版本。

后话:c#开发的东西是运行于.net 框架之上的,就好比java开发的东西必须要java
runtime才能运行一样,利用本文方法开发出来的dll也必须要安装.net框架才能跑起来,幸好最新的win7中已经集成了.net框架,当然您如
果对于庞大的.net框架安装程序很敏感,仍然觉得纯正的ocx更好的话,建议还是用vb/delphi/c++这一类老牌的开发工具/语言实现。(可以
参考我的另一篇重温delphi之:如何快速开发原生ActiveX控件)

示例源代码下载:http://files.cnblogs.com/yjmyzz/ActiveXDemo.rar

c#中开发ActiveX的学习笔记【转】的更多相关文章

  1. c#中开发ActiveX的学习笔记

    1.为什么要用ActiveX? 网页本身的功能是有限的,要想实现一些网页本身不支持的功能,比如:网页上的p2p视频播放,就得靠ActiveX这种古老的技术. 2.c#能开发ActiveX吗? 严格意义 ...

  2. JavaSE中Collection集合框架学习笔记(2)——拒绝重复内容的Set和支持队列操作的Queue

    前言:俗话说“金三银四铜五”,不知道我要在这段时间找工作会不会很艰难.不管了,工作三年之后就当给自己放个暑假. 面试当中Collection(集合)是基础重点.我在网上看了几篇讲Collection的 ...

  3. JavaSE中Collection集合框架学习笔记(3)——遍历对象的Iterator和收集对象后的排序

    前言:暑期应该开始了,因为小区对面的小学这两天早上都没有像以往那样一到七八点钟就人声喧闹.车水马龙. 前两篇文章介绍了Collection框架的主要接口和常用类,例如List.Set.Queue,和A ...

  4. Python 开发与接口测试学习笔记

    这是我跟着虫师学习中积累下来的学习笔记,写得比较简单,适合想学习Python开发与接口测试的初学者学习. 一.开发投票系统 1.参考官网文档,创建投票系统. https://docs.djangopr ...

  5. 《疯狂前端开发讲义jQuery+Angular+Bootstrap前端开发实践》学习笔记

    <疯狂前端开发讲义jQuery+Angular+Bootstrap前端开发实践>学习笔记 二〇一九年二月十三日星期三2时28分54秒 前提:本书适合有初步HTML.CSS.JavaScri ...

  6. 【VS开发】在VS2010中开发ActiveX控件设置测试容器的方式

    在VS2010中开发ActiveX控件设置测试容器的方式 借鉴文章http://blog.csdn.net/waxgourd0/article/details/7374669 在VS2010中开发MF ...

  7. 浏览器中js执行机制学习笔记

    浏览器中js执行机制学习笔记 RiverSouthMan关注 0.0772019.05.15 20:56:37字数 872阅读 291 同步任务 当一个脚本第一次执行的时候,js引擎会解析这段代码,并 ...

  8. ASP.Net开发基础温故知新学习笔记

    申明:本文是学习2014版ASP.Net视频教程的学习笔记,仅供本人复习之用,也没有发布到博客园首页. 一.一般处理程序基础 (1)表单提交注意点: ①GET通过URL,POST通过报文体: ②需在H ...

  9. lua游戏开发实践指南学习笔记1

    本文是依据lua游戏开发实践指南做的一些学习笔记,仅用于继续自己学习的一些知识. Lua基础 1.  语言定义: 在lua语言中,标识符有非常大的灵活性(变量和函数名),只是用户不呢个以数字作为起始符 ...

随机推荐

  1. NetCore 2.0 应用程序在centos 7上通过docker发布

    一  安装netcore 2.0 SDK 在centos 上面安装netcore 2.0 与window上面是不太一样的,注意,linux是不支持同时安装两个版本的.netcore SDK的,由于我之 ...

  2. luogu4001 [BJOI2006]狼抓兔子

    裸dinic就跑过去了,哪用得着平面图最小割=最短路-- #include <iostream> #include <cstring> #include <cstdio& ...

  3. day03_04 文件后缀及系统环境变量

    进入cmd,如果想直接切换盘符的话,操作如下 dir命令---查看目录下的文件及文件夹 cd命令---想进入某个目录,就是是双击文件夹进入目录的命令,按table键有神奇效果哦 cd ..命令---类 ...

  4. 听说你的模型损失是NaN

    听说你的模型损失是NaN 有时候,模型跑着跑着,损失就莫名变NaN了.不过,经验告诉我们,大部分NaN主要是因为除数是0或者传给log的数值不大于0.下面说说是log出NaN的几种常见解决方法. 毕竟 ...

  5. Uiautomator ---(1) 封装代码

    http://www.cnblogs.com/by-dream/p/4996000.html  上面是别人的写法 我自己的写法: package qq.test; import android.con ...

  6. 用CSV库一行行插入数据

    语料团队之前都是手动标注文字的定位位置,今天写了个小脚本,帮他们批量生成文字对应的定位. 其中数据生成后,要生成csv文件,查看了下使用csv库. import csv row1 = [1,2,3,4 ...

  7. POJ 1145 Tree Summing

    Tree Summing Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7698   Accepted: 1737 Desc ...

  8. 【转】简要分析unity3d中剪不断理还乱的yield

    在学习unity3d的时候很容易看到下面这个例子: 1 void Start () { 2 StartCoroutine(Destroy()); 3 } 4 5 IEnumerator Destroy ...

  9. background-position-x和background-position-y的兼容性问题

    一.语法: background-position-x : length | left | center | right background-position-y : length | left | ...

  10. Codeforces 899D Shovel Sale

    题目大意 给定正整数 $n$($2\le n\le 10^9$). 考虑无序整数对 $(x, y)$($1\le x,y\le n, x\ne y$). 求满足 「$x+y$ 结尾连续的 9 最多」的 ...