使用VS2010 C#开发ActiveX控件

简介:


    在网上查了一些资料也实际操作了一下,在此自己再作一次详细记录。

  功能:将对机具操作的FK.dll封装成fk.ocx,注册后能在网页上对机器操作。

使用Visual Studio 2010 .NET Framework 2.0(C#)

开发ActiveX步骤:

  1. 创建一个应用程序解决方案,并添加一个Windows控件库项目

    

  2. 更改“项目属性-应用程序-程序集信息”设置,勾选“使程序集 COM 可见”

    

  3.更改“项目属性-生成”设置,勾选“为 COM Interop 注册”(注意,此处如果实在debug状态下修改的,那在调到release状态下还需要再设置一次):

    

  4.修改AssemblyInfo.cs文件,添加[assembly: AllowPartiallyTrustedCallers()]项(需要引用System.Security名称空间):

    

  5.添加一个Windows用户控件名称:DHFkAttendOCX(自已定义,可以将已有的更改名称)

  6.为控件类添加GUID,这个编号将用于B/S系统的客户端调用时使用(可以使用 工具-创建GUID 菜单创建一个GUID,再复制):

    

  7.为了让ActiveX控件获得客户端的信任,控件类还需要实现一个名为“IObjectSafety”的接口,要创建该接口(注意,不能修改该接口的GUID值),IObjectSafety.cs代码如下:

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

  8.然后在控件类中继承并实现该接口,可以直接复制不用作任何更改:

复制代码
 1   ////IObjectSafety 成员
 2         #region IObjectSafety 成员
 3 
 4         private const string _IID_IDispatch = "{00020400-0000-0000-C000-000000000046}";
 5         private const string _IID_IDispatchEx = "{a6ef9860-c720-11d0-9337-00a0c90dcaa9}";
 6         private const string _IID_IPersistStorage = "{0000010A-0000-0000-C000-000000000046}";
 7         private const string _IID_IPersistStream = "{00000109-0000-0000-C000-000000000046}";
 8         private const string _IID_IPersistPropertyBag = "{37D84F60-42CB-11CE-8135-00AA004BB851}";
 9 
10         private const int INTERFACESAFE_FOR_UNTRUSTED_CALLER = 0x00000001;
11         private const int INTERFACESAFE_FOR_UNTRUSTED_DATA = 0x00000002;
12         private const int S_OK = 0;
13         private const int E_FAIL = unchecked((int)0x80004005);
14         private const int E_NOINTERFACE = unchecked((int)0x80004002);
15 
16         private bool _fSafeForScripting = true;
17         private bool _fSafeForInitializing = true;
18 
19         public int GetInterfaceSafetyOptions(ref Guid riid, ref int pdwSupportedOptions, ref int pdwEnabledOptions)
20         {
21             int Rslt = E_FAIL;
22 
23             string strGUID = riid.ToString("B");
24             pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA;
25             switch (strGUID)
26             {
27                 case _IID_IDispatch:
28                 case _IID_IDispatchEx:
29                     Rslt = S_OK;
30                     pdwEnabledOptions = 0;
31                     if (_fSafeForScripting == true)
32                         pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER;
33                     break;
34                 case _IID_IPersistStorage:
35                 case _IID_IPersistStream:
36                 case _IID_IPersistPropertyBag:
37                     Rslt = S_OK;
38                     pdwEnabledOptions = 0;
39                     if (_fSafeForInitializing == true)
40                         pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA;
41                     break;
42                 default:
43                     Rslt = E_NOINTERFACE;
44                     break;
45             }
46 
47             return Rslt;
48         }
49 
50         public int SetInterfaceSafetyOptions(ref Guid riid, int dwOptionSetMask, int dwEnabledOptions)
51         {
52             int Rslt = E_FAIL;
53             string strGUID = riid.ToString("B");
54             switch (strGUID)
55             {
56                 case _IID_IDispatch:
57                 case _IID_IDispatchEx:
58                     if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_CALLER) && (_fSafeForScripting == true))
59                         Rslt = S_OK;
60                     break;
61                 case _IID_IPersistStorage:
62                 case _IID_IPersistStream:
63                 case _IID_IPersistPropertyBag:
64                     if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_DATA) && (_fSafeForInitializing == true))
65                         Rslt = S_OK;
66                     break;
67                 default:
68                     Rslt = E_NOINTERFACE;
69                     break;
70             }
71 
72             return Rslt;
73         }
74 
75 
76         #endregion
复制代码

  9.引用自己想要封装的FK.dll

1     #region 引用dll方法
2         [DllImport("FK.dll")]
3         public static extern int FK_ConnectComm(int nMachineNo, int nComPort, int nBaudRate,
4             string pstrTelNumber, int nWaitDialTime, int nLicense, int nComTimeOut);
5   #endregion

  10.封装

复制代码
1      #region 封装方法
2         [SecurityCritical]
3         public int IDFK_ConnectNet(int nMachineNo, string strIpAddress, int nNetPort, int nTimeOut, int nProtocolType, int nNetPassword, int nLicense)
4         {
5             int result = FK_ConnectNet(nMachineNo, strIpAddress, nNetPort, nTimeOut, nProtocolType, nNetPassword, nLicense);
6             return result;
7         }
8       #endregion 
复制代码

  11.打包并发布ActiveX,与普通的Windows Form应用程序的安装部署几乎一样,只有一个地方需要注意,将前面创建的用户控件项目作为主输出项目,并设置其Register属性为vsdrpCOM

 

  12.给应用程序文件夹添加项目输出时,我们将DHFkAttendOCX项目添加进来,在项目中选择DHFkAttendOCX控件项目

  13.将FK.dll和其它引用的dll都一并作为文件添加

    

  14.在系统文件夹system32文件夹中将msiexec.exe(卸载控件时用到)地址找到也添加至上面文件夹

  15.在“用户的程序菜单”中,新建文件夹后加入主程序与msiexec.exe快捷方式

  16.点击安装项目工程,在属性中将ProductCode复制,点击msiexec.exe快捷方式,在属性Arguments中 加入"/x+一个空隔+ProductCode"

  

  17.生成项目,打包文件就生成了,打开..\Debug看到生成了2个文件,一个是xx.exe,一个是xx.msi,执行exe安装到系统。

  18.安装成功后, 在页面中添加<object id="csocx" classid="clsid:FE7EC23B-78A6-45B9-B61E-945970D963B6"></object>

       "FE7EC23B-78A6-45B9-B61E-945970D963B6"为第6步生成的GUID

  19.页面中js中引用

复制代码
 <script language="javascript" type="text/javascript">
        //操作
        function OnOpearOnMachion(opearValue) {
            var ocxKq = document.getElementById("csocx");
             var bolResult = ocxKq.IDFK_ConnectNet(1, "192.168.0.123", 5005, 3000, 0, 0, 123);           
    }
  </script>
复制代码

  20.大功造成。

  21.附代码

复制代码
  1 using System;
  2 using System.Collections.Generic;
  3 using System.ComponentModel;
  4 using System.Drawing;
  5 using System.Data;
  6 using System.Text;
  7 using System.Windows.Forms;
  8 using System.Runtime.InteropServices;
  9 using System.Security;
 10 
 11 namespace DHFkAttendOCX
 12 {
 13     [Guid("FE7EC23B-78A6-45B9-B61E-945970D963B6")]
 14     [ProgId("DHFkAttend")]
 15     public partial class DHFkAttendOCX : UserControl
 16     {
 17         public DHFkAttendOCX()
 18         {
 19             InitializeComponent();
 20         }
 21         ////IObjectSafety 成员
 22         #region IObjectSafety 成员
 23 
 24         private const string _IID_IDispatch = "{00020400-0000-0000-C000-000000000046}";
 25         private const string _IID_IDispatchEx = "{a6ef9860-c720-11d0-9337-00a0c90dcaa9}";
 26         private const string _IID_IPersistStorage = "{0000010A-0000-0000-C000-000000000046}";
 27         private const string _IID_IPersistStream = "{00000109-0000-0000-C000-000000000046}";
 28         private const string _IID_IPersistPropertyBag = "{37D84F60-42CB-11CE-8135-00AA004BB851}";
 29 
 30         private const int INTERFACESAFE_FOR_UNTRUSTED_CALLER = 0x00000001;
 31         private const int INTERFACESAFE_FOR_UNTRUSTED_DATA = 0x00000002;
 32         private const int S_OK = 0;
 33         private const int E_FAIL = unchecked((int)0x80004005);
 34         private const int E_NOINTERFACE = unchecked((int)0x80004002);
 35 
 36         private bool _fSafeForScripting = true;
 37         private bool _fSafeForInitializing = true;
 38 
 39         public int GetInterfaceSafetyOptions(ref Guid riid, ref int pdwSupportedOptions, ref int pdwEnabledOptions)
 40         {
 41             int Rslt = E_FAIL;
 42 
 43             string strGUID = riid.ToString("B");
 44             pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA;
 45             switch (strGUID)
 46             {
 47                 case _IID_IDispatch:
 48                 case _IID_IDispatchEx:
 49                     Rslt = S_OK;
 50                     pdwEnabledOptions = 0;
 51                     if (_fSafeForScripting == true)
 52                         pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER;
 53                     break;
 54                 case _IID_IPersistStorage:
 55                 case _IID_IPersistStream:
 56                 case _IID_IPersistPropertyBag:
 57                     Rslt = S_OK;
 58                     pdwEnabledOptions = 0;
 59                     if (_fSafeForInitializing == true)
 60                         pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA;
 61                     break;
 62                 default:
 63                     Rslt = E_NOINTERFACE;
 64                     break;
 65             }
 66 
 67             return Rslt;
 68         }
 69 
 70         public int SetInterfaceSafetyOptions(ref Guid riid, int dwOptionSetMask, int dwEnabledOptions)
 71         {
 72             int Rslt = E_FAIL;
 73             string strGUID = riid.ToString("B");
 74             switch (strGUID)
 75             {
 76                 case _IID_IDispatch:
 77                 case _IID_IDispatchEx:
 78                     if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_CALLER) && (_fSafeForScripting == true))
 79                         Rslt = S_OK;
 80                     break;
 81                 case _IID_IPersistStorage:
 82                 case _IID_IPersistStream:
 83                 case _IID_IPersistPropertyBag:
 84                     if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_DATA) && (_fSafeForInitializing == true))
 85                         Rslt = S_OK;
 86                     break;
 87                 default:
 88                     Rslt = E_NOINTERFACE;
 89                     break;
 90             }
 91 
 92             return Rslt;
 93         }
 94 
 95 
 96         #endregion
 97 
 98         #region 引用dll方法
 99         [DllImport("FK.dll")]
100         public static extern int FK_ConnectComm(int nMachineNo, int nComPort, int nBaudRate,
101             string pstrTelNumber, int nWaitDialTime, int nLicense, int nComTimeOut);
102         #endregion
103 
104         #region 封装方法
105         [SecurityCritical]
106         public int IDFK_ConnectNet(int nMachineNo, string strIpAddress, int nNetPort, int nTimeOut, int nProtocolType, int nNetPassword, int nLicense)
107         {
108             int result = FK_ConnectNet(nMachineNo, strIpAddress, nNetPort, nTimeOut, nProtocolType, nNetPassword, nLicense);
109             return result;
110         }
111         #endregion
112     }
113 }
复制代码

 

   22.要注意的是,浏览器要设置以下控件才能正常运行

安装所需要的控件后:

打开IE浏览器,在菜单栏点击“工具”—“Internet选项”—“安全”选项卡。

   1. 点击“受信任站点”  

    

   2.然后点击“站点”弹出如下图片:

    

  3.按照上图填写内容后,点击“添加”然后点“确定”. 

  4. 设置自定义安全级别(internet本地、受信任站点均需要)   

    5.点击“自定义级别”,弹出如下图片,选择“安全级 – 低” 然后将组件全部“启用”:

 

   

本文转自欢醉博客园博客,原文链接http://www.cnblogs.com/zhangs1986/archive/2013/01/18/2866734.html如需转载请自行联系原作者


欢醉

相关文章
|
9天前
|
缓存 算法 安全
精选10款C#/.NET开发必备类库(含使用教程),工作效率提升利器!
精选10款C#/.NET开发必备类库(含使用教程),工作效率提升利器!
44 12
|
2月前
|
前端开发 JavaScript 安全
C#一分钟浅谈:Blazor WebAssembly 开发
Blazor WebAssembly 是一个客户端框架,允许开发者使用C#和Razor语法构建Web应用。本文介绍了Blazor WebAssembly的基本概念、常见问题及解决方案,包括路由配置、数据绑定、异步操作、状态管理和性能优化等方面的内容,并分享了一些易错点及如何避免的方法。希望这些内容能帮助你在Blazor WebAssembly开发中少走弯路,提高开发效率。
119 51
|
2月前
|
开发框架 缓存 .NET
C# 一分钟浅谈:Blazor Server 端开发
Blazor Server 是基于 ASP.NET Core 的框架,允许使用 C# 和 Razor 语法构建交互式 Web 应用。本文介绍 Blazor Server 的基本概念、快速入门、常见问题及解决方案,帮助开发者快速上手。涵盖创建应用、基本组件、数据绑定、状态管理、跨组件通信、错误处理和性能优化等内容。
60 1
|
2月前
|
缓存 C# 开发者
C# 一分钟浅谈:Blazor Server 端开发
本文介绍了 Blazor Server,一种基于 .NET 的 Web 开发模型,允许使用 C# 和 Razor 语法构建交互式 Web 应用。文章从基础概念、创建应用、常见问题及解决方案、易错点及避免方法等方面详细讲解,帮助开发者快速上手并提高开发效率。
68 2
|
2月前
|
测试技术 Go C#
C#一分钟浅谈:ReSharper 插件增强开发效率
【10月更文挑战第25天】ReSharper 是 JetBrains 开发的一款 Visual Studio 插件,旨在提高 .NET 开发者的生产力。它通过代码分析、重构、导航等功能,帮助开发者避免常见错误,提升代码质量和开发效率。本文将通过具体代码案例,详细介绍 ReSharper 的常见功能及其应用。
53 1
|
2月前
|
C# Python
使用wxpython开发跨平台桌面应用,对wxpython控件实现类似C#扩展函数处理的探究
【10月更文挑战第30天】使用 `wxPython` 开发跨平台桌面应用时,可以通过创建辅助类来模拟 C# 扩展函数的功能。具体步骤包括:1. 创建辅助类 `WxWidgetHelpers`;2. 在该类中定义静态方法,如 `set_button_color`;3. 在应用中调用这些方法。这种方法提高了代码的可读性和可维护性,无需修改 `wxPython` 库即可为控件添加自定义功能。但需要注意显式调用方法和避免命名冲突。
|
3月前
|
JSON C# 开发者
C#语言新特性深度剖析:提升你的.NET开发效率
【10月更文挑战第15天】C#语言凭借其强大的功能和易用性深受开发者喜爱。随着.NET平台的演进,C#不断引入新特性,如C# 7.0的模式匹配和C# 8.0的异步流,显著提升了开发效率和代码可维护性。本文将深入探讨这些新特性,助力开发者在.NET开发中更高效地利用它们。
45 1
|
2月前
|
C# 开发者
C# 一分钟浅谈:Code Contracts 与契约编程
【10月更文挑战第26天】本文介绍了 C# 中的 Code Contracts,这是一个强大的工具,用于通过契约编程增强代码的健壮性和可维护性。文章从基本概念入手,详细讲解了前置条件、后置条件和对象不变量的使用方法,并通过具体代码示例进行了说明。同时,文章还探讨了常见的问题和易错点,如忘记启用静态检查、过度依赖契约和性能影响,并提供了相应的解决建议。希望读者能通过本文更好地理解和应用 Code Contracts。
44 3
|
16天前
|
存储 安全 编译器
学懂C#编程:属性(Property)的概念定义及使用详解
通过深入理解和使用C#的属性,可以编写更清晰、简洁和高效的代码,为开发高质量的应用程序奠定基础。
65 12
|
2月前
|
设计模式 C# 图形学
Unity 游戏引擎 C# 编程:一分钟浅谈
本文介绍了在 Unity 游戏开发中使用 C# 的基础知识和常见问题。从 `MonoBehavior` 类的基础用法,到变量和属性的管理,再到空引用异常、资源管理和性能优化等常见问题的解决方法。文章还探讨了单例模式、事件系统和数据持久化等高级话题,旨在帮助开发者避免常见错误,提升游戏开发效率。
74 4