visual studio 2012 的制作ActiveX、打包和发布

开发环境是Vs 2012  Framework 4.0

源码和制作工具在文章最下边

一. ActiveX控件Demo

新建一个Window窗体控件库项目

在自动生成的UserControl1页面上添加一个button

点击事件里我们只弹出一个MesageBox

        private void button1_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Click!!!!");
        }

IE怎么知道一个插件是脚本安全的?它是通过以下两个办法。一是查询ActiveX组件是否实现了IObjectSafety接口,并且

返回脚本安全;二是查询ActiveX组件是否在注册表的Component  Category Manager里表明自己实现了

CATID_SafeForInitializing和CATID_SafeForScripting。

这里我们只说第一种实现IObjectSafety接口

接口格式是固定的不要修改

using System;
using System.Runtime.InteropServices;
namespace ActiveXDemo
{
    

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

在UserControl1控件的后台代码我们要实现这个接口

看一下代码

using System;
using System.Windows.Forms;

namespace ActiveXDemo
{
    using System.Runtime.InteropServices;

    [Guid("6169E98E-DA08-4E87-81B6-EE3A5034C0E2"), ProgId("ActiveXDemo.UserControl1"), ComVisible(true)]
    public partial class UserControl1: UserControl,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
        

        public UserControl1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Click!!!!");
        }
    }
}

这里要做一下修改

[Guid("6169E98E-DA08-4E87-81B6-EE3A5034C0E2"), ProgId("ActiveXDemo.UserControl1"), ComVisible(true)]

这个guid是我自己生成的还有ProgId里的ActiveXDemo.UserControl1是我自己工程里的,修改成你自己的 gui生成是在 菜单 工具 下边

打开项目属性,

在应用程序里 点击程序集信息 勾选 使程序集COM可见

在生成里边,勾选  为Com互操作注册

做到这里我们的ActiveX控件就做完了接下来我们把它发布

先是把它打包

Vs2012 打包我之前有些不同

新项目——其他项目 安装和部署

选择application information:基本配置,自定义填写

 接下来先把Application Files,点击MyCompany下的第一个节点可以自己重命名

 点击 Add Project OutPuts

选择主输出点ok

因为我们的demo就一个dll所以不用再有别的操作

如果想修改一下安装的窗体可以在Installation Interview里设置

在Express\DVD-5\DiskImages\DISK1文件夹下就是我们的安装软件了

一个exe一个mis我们只用mis的

还要一个cabarc.exe这个我会在下载里给大家提供

  cabarc.exe:微软提供的cab打包工具

     ActiveXSetup.msi:  项目生成的部署安装文件

    install.inf : 需要跟ActiveXSetup.msi打包在一起的文件

    build.bat:  打包的批处理命令

install.inf

[version]
signature="$CHICAGO$"
AdvancedINF=2.0

[Setup Hooks]
hook1=hook1

[hook1]
run=msiexec.exe /i "%EXTRACT_DIR%\ActiveXSetup.msi" /qn

 build.bat 

"cabarc.exe"  n test.cab ActiveXSetup.msi install.inf 

运行一下bat就可以生成一个 cab

我们随便建一个webfrom网站

在debug下边建一下dll文件夹

把test.cab放到文件夹里

在首页上这样写

<body>
    <form id="form1" runat="server">
    <div>
    <object id="mytt" classid="clsid:6169E98E-DA08-4E87-81B6-EE3A5034C0E2"  
        codebase="/DLL/test.cab"></object>
    </div>
    </form>
</body>
</html>

这个Classid就是我们在UserControl1.cs的Guid里的序列号 看一下效果吧

Active源码.rar

cab制作工具.rar

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏宋凯伦的技术小栈

【小结】IIS7下的Http Native Module开发

  今天接到Product Manager的通知,Exchange 2007环境下的Native Module不再需要开发(详情可见上篇),但最近几天一直在做P...

25590
来自专栏数据和云

推陈出新:12C 推进 SCN 新方法实践

在数据库异常恢复中,经常需要修改数据库的 SCN 值,在 12C 之前,我们常用的方法有如下几个: oradebug poke 直接修改内存中的值; event...

434100
来自专栏我的博客

filter_input()详解,$_GET,$_POST,$_ENV,$_SERVER,$_SESSION,$_REQUEST

filter_input() 函数从脚本外部获取输入,并进行过滤。 本函数用于对来自非安全来源的变量进行验证,比如用户的输入。 本函数可从各种来源获取输入: I...

35550
来自专栏张善友的专栏

使用MongoDB存储访问者信息

网站的访问者信息的存储一般都是海量的,通常使用关系数据库,现在NoSQL运动火热,满足这样的需求使用NoSQL数据库会更好,网站访问者信息主要是两个功能: 1、...

240100
来自专栏乐沙弥的世界

Oracle数据恢复顾问(Data Recovery Advisor)

Oracle数据恢复顾问用于当数据发生错误或故障时,进行自动收集数据故障信息,并生成恢复脚本,用于完成数据恢复。数据恢复顾问也可以主动检查故障。 在这种模式下,...

9520
来自专栏linux驱动个人学习

基于input子系统的sensor驱动调试(二)

继上一篇:https://cloud.tencent.com/developer/article/1054078 一、驱动流程解析: 1、模块加载: 1 st...

68370
来自专栏Kotlin入门系列

win7基础 cmd 查看当前已经启动的服务列表

84660
来自专栏ASP.NET MVC5 后台权限管理系统

ASP.NET MVC5+EF6+EasyUI 后台管理系统(75)-微信公众平台开发-用户管理

前言 本节主要是关注者(即用户)和用户组的管理,微信公众号提供了用户和用户组的管理,我们可以在微信公众号官方里面进行操作,添加备注和标签,以及移动用户组别,同...

60960
来自专栏乐沙弥的世界

使用 SQLNET.EXPIRE_TIME 清除僵死连接

    数据库连接的客户端异常断开后,其占有的相应并没有被释放,如从v$session视图中依旧可以看到对应的session处于inactive,且对应的服务器...

36120
来自专栏乐沙弥的世界

自定义 RMAN 显示的日期时间格式

      缺省情况下,使用RMAN备份与恢复界面仅仅显示的是日期,而没有具体的时间。有时候需要查看具体的时间,如查看当天多个Incarnation的情形。对于...

12040

扫码关注云+社区

领取腾讯云代金券