因项目需要,需要开发一个功能:在IE中点击转跳,并打开chorme浏览器继续浏览指定页面。
分析需求后,参考了:
后,了解得知可从修改本地注册表配置和IE的actived控件两种方式实现,考虑到本地修改注册表无法使用js脚本打开链接,只能使用超链接转跳,与项目本身情况不符,故考虑自定义一个actived控件实现相关功能。
根据参考文献https://www.cnblogs.com/yilin/p/csharp-activex.html,我开始进行相关尝试:
1.创建接口IObjectSafety,以便让客户端信任自定义控件,其中Guid按照参考文件的要求固定为CB5BDC81-93C1-11CF-8F20-00805F2CD064,没有做修改。
    [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);
    }
2.创建基类ActiveXControl
    public abstract class ActiveXControl : 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.创建具体控件OpenChormeActiveX。指定的Guid值“a8d0d357-df7e-41a4-b963-1db5cfa67873”即为该ActiveX控件的唯一标识,保证其唯一性。
[Guid("a8d0d357-df7e-41a4-b963-1db5cfa67873")]
    public class OpenChormeActiveX:ActiveXControl,IIEProperty
    {
        public void OpenChorme()
        {
            System.Diagnostics.Process.Start("Chrome.exe", "https://blog.csdn.net/sinat_23338865/article/details/65447387");
        }
   }
4.设置集的COM可见,设置类库项目属性->程序集信息->使程序集COM可见
5.在VS2017中下载扩展:Microsoft Visual Studio 2017 Installer Project,并创建一个单独的安装项目工程
6.右键点击新添加的安装项目,依次选择“添加->项目输出”菜单,打开添加项目输出组对话框,并选择ActiveX控件类库“CSharpActiveX”作为主输出
7.双击安装项目检测到的依赖项“Microsoft .NET Framework”,打开安装项目的启动条件界面,选中“.NET Framework”项,打开属性窗口,设置.NET Framework项的Version为“.NET Framework 4.0”
8.选中“主输出来自CSharpActiveX(活动)”项,设置主输出项内容的Register属性值为vsdrpCOM。
9.生成OpenChormeFormIE.msi
10.创建一个新文件夹makecab
11.将以下内容,放在cab.ddf中,放在makecab下
.OPTION   EXPLICIT
.Set Cabinet=on
.Set Compress=on
.Set MaxDiskSize=CDROM
.Set ReservePerCabinetSize=6144
.Set DiskDirectoryTemplate="."
.Set CompressionType=MSZIP
.Set CompressionLevel=7
.Set CompressionMemory=21
.Set CabinetNameTemplate="OpenChormeFormIE.CAB"
"installer.inf"
"OpenChormeFormIE.msi"
12.将以下内容,放在installer.inf,放在makecab下
[Setup Hooks]
hook1=hook1
 
[hook1]
run=msiexec /i %EXTRACT_DIR%\OpenChormeFormIE.msi /qn
 
[Version]
Signature= "$CHICAGO$"
AdvancedInf=2.0
13.将OpenChormeFormIE.msi放在makecab下
14.在放在makecab下,启动cmd,执行makecab.exe  /f "cab.ddf",生成OpenChormeFormIE.CAB
15.在html页面中,添加:
<object id="cSharpActiveX" classid="clsid:a8d0d357-df7e-41a4-b963-1db5cfa67873" codebase="dll/OpenChormeFormIE.CAB#version=1,0,0" style="display: none;"></object>
 
var o = document.getElementById("cSharpActiveX");
o.OpenChorme();
 
 
 

在IE中点击转跳,并打开chorme浏览器继续浏览指定页面,IE自定义ocx控件开发的更多相关文章

  1. 阻止iOS Web APP中点击链接跳转到Safari 浏览器新标签页

    问题:ios封装完之后,点击里边的按钮会跳转到网页上 ——小卡遇到这个问题就是这样解决的↓↓↓ 解决方法:建议将代码放到</head>标签前,当然,另外存为一个js 文件引用也是可以的呦~ ...

  2. iOS中点击按钮跳转到外部浏览器和内部打开

    如图所示,需要实现点击一个按钮,跳转到指定网页: -(void)pushBtnCellClickDeleate{ NSLog(@"跳转"); //在APP内部打开指定网页 UIWe ...

  3. android 小工具:pc 上用 curl 命令打开手机浏览器,浏览指定网址

    测试 API 时或其它情况经常需要在手机浏览器中输入 url 一长串的 url 输起来真是麻烦 AirDroid 很强大也不用数据线,但有时老断开连接,不是很爽.发到手机 qq 吧还得手动粘贴 所以自 ...

  4. 微信不支持App下载的解决方案 微信跳转打开外部浏览器下载(苹果跳转商店下载)

    在微信中,打开app下载链接,或者使用微信扫一扫app下载二维码,都是无法下载app的. 因为腾讯为了自身利益,屏蔽了其他app直接在微信中下载.下面给分享下,找到的2种有效的解决方案. 方案:点击链 ...

  5. android 点击桌面图标,打开手机浏览器进入对应的站点

    做一个假的adnroid app.要实现点击桌面图标.打开手机浏览器进入对应的站点,实现方法非常easy import android.app.Activity; import android.con ...

  6. android一个app打开另一个app的指定页面

    一个app打开另一个app的指定页面方法 有以下几种 1.通过包名.类名 2.通过intent的 action 3.通过Url 方案1. ComponentName componentName = n ...

  7. electron-vue中点击按钮,实现打开程序目录里面的某个文件

    设计到的知识点: explorer.exe /select 打开文件夹并把焦点放到指定文件 nodejs中的process模块--child_process.exec 我这里是根据需求,点击按钮后打开 ...

  8. IE浏览器打开chorme浏览器,如何打开其他浏览器

    看到这个标题是否感觉奇怪,为什么要用IE浏览器打开chorme或者火狐浏览器等,这个功能从开发者来说不是一个好的需求,但确实是真实存在的,有用公司的背景历史比较复杂,而且公司有过长期的开发历史,这导致 ...

  9. 程序中打开IE浏览器并访问指定地址

    最简单的方法 Process.Start("iexplore.exe");  //直接打开IE浏览器(打开默认首页)            Process.Start(" ...

随机推荐

  1. SpringMVC结果参数转换XSS攻击安全处理

    首先在sprigMvc的配置文件中配置返回结果集使用的类 <!-- 参数转码 --> <mvc:annotation-driven> <!-- 注册处理 JSON 的转换 ...

  2. python requests访问https的链接,不打开fiddler的情况下不报错;若是打开fiddler则报ssl错误,请求中添加verify=False,会报警告;若不想看到警告,有3种方式;

    import requests# import warnings# warnings.filterwarnings("ignore") #方法一#requests.packages ...

  3. 201871010125 王玉江 《面向对象程序设计(java)》 第四周学习总结

    项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/wswyj/ 作业学习目 ...

  4. VSCode变换python的调试解释器

    假如一个电脑上有多个Python的环境,想要设置不同的python解释器用于调试. VSCode 的设置,是通过.json的文本来配置的.打开文本的方式: 打开后的文件如下所示: 可以试试“new s ...

  5. Docker容器数据卷(七)

    Docker致力于: 将运用与运行的环境打包形成容器运行 ,运行可以伴随着容器,但是我们对数据的要求希望是持久化的 容器之间希望有可能共享数据 Docker容器产生的数据,如果不通过docker co ...

  6. Netty入门程序(四)

    maven创建project,引入依赖: <dependency> <groupId>io.netty</groupId> <artifactId>ne ...

  7. zz深度学习目标检测2014至201901综述

    论文学习-深度学习目标检测2014至201901综述-Deep Learning for Generic Object Detection A Survey  发表于 2019-02-14 |  更新 ...

  8. Spring Cloud微服务安全实战_3-8_API安全之登录

    前面的文章 https://www.cnblogs.com/lihaoyang/p/11967121.html  说了用过滤器实现HttpBasic 认证 ,在请求头里携带用户名和密码,存在的问题是, ...

  9. MySQL字段类型 约束

    目录 MySQL存储引擎 非空约束 字段类型 整形类型INT TINYINT 浮点类型float 字符类型char varchar 日期类型 枚举集合 约束条件 主键 自增 unsigned无符号 z ...

  10. MySQL实战45讲学习笔记:第六讲

    一.今日内容概要 今天我要跟你聊聊 MySQL 的锁.数据库锁设计的初衷是处理并发问题.作为多用户共享的资源,当出现并发访问的时候,数据库需要合理地控制资源的访问规则.而锁就是用来实现这些访问规则的重 ...