zoukankan      html  css  js  c++  java
  • C#开发ActiveX控件一

     前一段时间因项目需要,要把C#开发的Winfrom应用程序做成一个ActiveX控件,以便在IE中运行。网上关于C#ActiveX控件的文章也不少,尽管用C#开发ActiveX控件有不少弊端,但项目的改写势在必行,也没有什么好的方法可以取代,用C#来改写还可以减少工作量,所以只好老老实实做下去。经过几天总算是完成任务了,中间也走了不少弯路,我把在项目改写过程中出现的问题记录下来,以供参考。
        用C#开发ActiveX控件我主要参考红马的三篇文章,入门都是按照其文章上的步骤来的,几乎没有什么问题。但是要注意的是文章中的实现IObjectSafety接口有些问题,实现其接口后还是弹出窗口说ActiveX控件不是安全的。网上有正确的实现方法,我将其整理如下如下:

     1[ComImport, GuidAttribute("CB5BDC81-93C1-11CF-8F20-00805F2CD064")]
     2[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
     3interface IObjectSafety
     4{
     5    [PreserveSig]
     6    int GetInterfaceSafetyOptions(ref Guid riid, [MarshalAs(UnmanagedType.U4)] ref int pdwSupportedOptions, [MarshalAs(UnmanagedType.U4)] ref int pdwEnabledOptions);
     7    [PreserveSig()]
     8    int SetInterfaceSafetyOptions(ref Guid riid, [MarshalAs(UnmanagedType.U4)] int dwOptionSetMask, [MarshalAs(UnmanagedType.U4)] int dwEnabledOptions);
     9}

    10

        然后让你的ActiveX控件实现其接口,代码如下:

     1#region 实现IObjectSafety接口
     2private const string _IID_IDispatch = "{00020400-0000-0000-C000-000000000046}";
     3private const string _IID_IDispatchEx = "{a6ef9860-c720-11d0-9337-00a0c90dcaa9}";
     4private const string _IID_IPersistStorage = "{0000010A-0000-0000-C000-000000000046}";
     5private const string _IID_IPersistStream = "{00000109-0000-0000-C000-000000000046}";
     6private const string _IID_IPersistPropertyBag = "{37D84F60-42CB-11CE-8135-00AA004BB851}";
     7
     8private const int INTERFACESAFE_FOR_UNTRUSTED_CALLER = 0x00000001;
     9private const int INTERFACESAFE_FOR_UNTRUSTED_DATA = 0x00000002;
    10private const int S_OK = 0;
    11private const int E_FAIL = unchecked((int)0x80004005);
    12private const int E_NOINTERFACE = unchecked((int)0x80004002);
    13
    14private bool _fSafeForScripting = true;
    15private bool _fSafeForInitializing = true;
    16//使ActiveX控件成为安全的控件
    17public int GetInterfaceSafetyOptions(ref Guid riid, ref int pdwSupportedOptions, ref int pdwEnabledOptions)
    18{
    19        int Rslt = E_FAIL;
    20        string strGUID = riid.ToString("B");
    21        pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA;
    22        switch (strGUID)
    23        {
    24                case _IID_IDispatch:
    25                case _IID_IDispatchEx:
    26                    Rslt = S_OK;
    27                    pdwEnabledOptions = 0;
    28                    if (_fSafeForScripting == true)
    29                        pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER;
    30                    break;
    31                case _IID_IPersistStorage:
    32                case _IID_IPersistStream:
    33                case _IID_IPersistPropertyBag:
    34                    Rslt = S_OK;
    35                    pdwEnabledOptions = 0;
    36                    if (_fSafeForInitializing == true)
    37                        pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA;
    38                    break;
    39                default:
    40                    Rslt = E_NOINTERFACE;
    41                    break;
    42         }

    43
    44        return Rslt;
    45    }

    46
    47    public int SetInterfaceSafetyOptions(ref Guid riid, int dwOptionSetMask, int dwEnabledOptions)
    48    {
    49            int Rslt = E_FAIL;
    50
    51            string strGUID = riid.ToString("B");
    52            switch (strGUID)
    53            {
    54                case _IID_IDispatch:
    55                case _IID_IDispatchEx:
    56                    if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_CALLER) && (_fSafeForScripting == true))
    57                        Rslt = S_OK;
    58                    break;
    59                case _IID_IPersistStorage:
    60                case _IID_IPersistStream:
    61                case _IID_IPersistPropertyBag:
    62                    if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_DATA) && (_fSafeForInitializing == true))
    63                        Rslt = S_OK;
    64                    break;
    65                default:
    66                    Rslt = E_NOINTERFACE;
    67                    break;
    68            }

    69
    70            return Rslt;
    71    }

    72#endregion

    73
        另外需要注意的是,项目属性中,在“程序集信息”对话框中将“使程序集COM可见”复选框选上。属性“生成”卡中选中“为COM interop 注册”。
       
    到此为止,用C#开发ActiveX控件基本上算是完成了,通过IE查看,可以看到效果。细节部分我没有写全,如有需要,可以参考红马文章:
        http://www.cnblogs.com/homer/archive/2005/01/04/86473.html
        http://www.cnblogs.com/homer/archive/2005/01/08/88780.html
           http://www.cnblogs.com/homer/archive/2005/01/26/97822.html
  • 相关阅读:
    [每日一题]:小猫爬山
    [每日一题]:Wannafly挑战赛1 -- Treepath
    JavaWeb学习(19): 文件的上传和下载
    [每日一题]:牛客练习赛61 A:打怪
    [十二省联考2019]春节十二响——长链剖分+堆
    BZOJ4977[Lydsy1708月赛]跳伞求生——贪心+堆+模拟费用流
    BZOJ4003[JLOI2015]城池攻占——可并堆
    BZOJ1823[JSOI2010]满汉全席——2-SAT+tarjan缩点
    BZOJ3876[Ahoi2014&Jsoi2014]支线剧情——有上下界的最小费用最大流
    BZOJ2738矩阵乘法——整体二分+二维树状数组
  • 原文地址:https://www.cnblogs.com/meiproject/p/1327974.html
Copyright © 2011-2022 走看看