简体   繁体   English

使用C#使用ActiveX对象运行DLL

[英]running a dll with activex objects with c#

Hi i have following c# code for configuring active x components as 嗨,我有以下c#代码用于将活动x组件配置为

using System;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using Microsoft.Win32;

namespace Kosmala.Michal.ActiveXTest
{
    /// <summary>
    /// Summary description for Class1.
    /// </summary>
    [ProgId("Dendrite.WebForce.MMP.Web.OurActiveX")]
    [ClassInterface(ClassInterfaceType.AutoDual), ComSourceInterfaces(typeof(ControlEvents))] //Implementing interface that will be visible from JS
    [Guid("121C3E0E-DC6E-45dc-952B-A6617F0FAA32")]
    [ComVisible(true)]
    public class ActiveXObject
    {
        private string myParam = "Empty"; 

        public ActiveXObject()
        {

        }

        public event ControlEventHandler OnClose;

        /// <summary>
        /// Opens application. Called from JS
        /// </summary>
        [ComVisible(true)]
        public void Open()
        {
            //TODO: Replace the try catch in aspx with try catch below. The problem is that js OnClose does not register.
            try
            {

                MessageBox.Show(myParam); //Show param that was passed from JS
                Thread.Sleep(2000); //Wait a little before closing. This is just to show the gap between calling OnClose event.
                Close(); //Close application

            }
            catch (Exception e)
            {
                //ExceptionHandling.AppException(e);
                throw e;
            }
        }

        /// <summary>
        /// Parameter visible from JS
        /// </summary>
        [ComVisible(true)]
        public string MyParam
        {
            get
            {
                return myParam;
            }
            set
            {
                myParam = value;
            }
        }


        [ComVisible(true)]
        public void Close()
        {
            if(OnClose != null)
            {
                OnClose("http://otherwebsite.com"); //Calling event that will be catched in JS
            }
            else
            {
                MessageBox.Show("No Event Attached"); //If no events are attached send message.
            }
        }



        /// <summary>
        /// Register the class as a control and set it's CodeBase entry
        /// </summary>
        /// <param name="key">The registry key of the control</param>
        [ComRegisterFunction()]
        public static void RegisterClass ( string key )
        {
            // Strip off HKEY_CLASSES_ROOT\ from the passed key as I don't need it
            StringBuilder   sb = new StringBuilder ( key ) ;

            sb.Replace(@"HKEY_CLASSES_ROOT\","") ;
            // Open the CLSID\{guid} key for write access
            RegistryKey k   = Registry.ClassesRoot.OpenSubKey(sb.ToString(),true);

            // And create   the 'Control' key - this allows it to show up in
            // the ActiveX control container
            RegistryKey ctrl = k.CreateSubKey   ( "Control" ) ;
            ctrl.Close ( ) ;

            // Next create the CodeBase entry   - needed if not string named and GACced.
            RegistryKey inprocServer32 = k.OpenSubKey   ( "InprocServer32" , true ) ;
            inprocServer32.SetValue (   "CodeBase" , Assembly.GetExecutingAssembly().CodeBase ) ;
            inprocServer32.Close ( ) ;
                // Finally close the main   key
            k.Close (   ) ;
            MessageBox.Show("Registered");
        }

        /// <summary>
        /// Called to unregister the control
        /// </summary>
        /// <param name="key">Tke registry key</param>
        [ComUnregisterFunction()]
        public static void UnregisterClass ( string key )
        {
            StringBuilder   sb = new StringBuilder ( key ) ;
            sb.Replace(@"HKEY_CLASSES_ROOT\","") ;

            // Open HKCR\CLSID\{guid} for write access
            RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(),true);

            // Delete the 'Control' key, but don't throw an exception if it does not exist
            k.DeleteSubKey ( "Control" , false ) ;

            // Next open up InprocServer32
            //RegistryKey   inprocServer32 = 
            k.OpenSubKey (  "InprocServer32" , true ) ;

            // And delete the CodeBase key, again not throwing if missing
            k.DeleteSubKey ( "CodeBase" , false ) ;

            // Finally close the main key
            k.Close ( ) ;
            MessageBox.Show("UnRegistered");
        }



    }

    /// <summary>
    /// Event handler for events that will be visible from JavaScript
    /// </summary>
    public delegate void ControlEventHandler(string redirectUrl); 


    /// <summary>
    /// This interface shows events to javascript
    /// </summary>
    [Guid("68BD4E0D-D7BC-4cf6-BEB7-CAB950161E79")]
    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    public interface ControlEvents
    {
        //Add a DispIdAttribute to any members in the source interface to specify the COM DispId.
        [DispId(0x60020001)]
        void OnClose(string redirectUrl); //This method will be visible from JS
    }
}

and i have created the testpage .html as 我已经创建了testpage .html作为

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" > 

<html>
  <head>
    <title>WebForm1</title>
    <meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
    <meta name="CODE_LANGUAGE" Content="C#">
    <meta name=vs_defaultClientScript content="JavaScript">
    <meta name=vs_targetSchema content="http://schemas.microsoft.com/intellisense/ie5">
  </head>
  <body onload="OpenActiveX()">

  <!-- Our activeX object -->
  <OBJECT id="OurActiveX" name=”OurActiveX" classid="clsid:121C3E0E-DC6E-45dc-952B-A6617F0FAA32" VIEWASTEXT codebase="OurActiveX.cab"></OBJECT> 

  <!-- Attaching to an ActiveX event-->
<script language="javascript">
           function OurActiveX::OnClose(redirectionUrl)
       {
        alert(redirectionUrl);   <!-- http://otherwebsite.com should be returned-->
                    //window.location = redirectionUrl;
           }
</script>


<script language="javascript">
    //Passing parameters to ActiveX object and starting application
function OpenActiveX()
{
    try
    {
        document.OurActiveX.MyParam = "Hi I am here." //Passing parameter to the ActiveX
        document.OurActiveX.Open(); //Running method from activeX
    }
    catch(Err)
    {
        alert(Err.description);
    }
}   


</script>

  </body>
</html>

now when i am running the html page in internet explorer browser i am getting following error as 现在,当我在Internet Explorer浏览器中运行html页面时,出现以下错误:

OBJECT DOES NOT SUPPORT PROPERTY OR METHOD OPEN 对象不支持属性或方法开放

can you help me to fix these problem 你能帮我解决这些问题吗

waiting for your valuable comments and responses 等待您的宝贵意见和回应

With your test page open in IE, open Internet Options from the tools button on the toolbar (in IE9), select the Security page, click the Custom button and scroll down to the "ActiveX Controls and plug-ins" section. 在IE中打开测试页的情况下,从工具栏上的工具按钮(在IE9中)打开“ Internet选项”,选择“ 安全性”页面,单击“ 自定义”按钮,然后向下滚动到“ ActiveX控件和插件”部分。 You can enable prompting / enabling of ActiveX controls and scripting of them here. 您可以在此处启用提示/启用ActiveX控件并对其进行脚本编写。

By default, unsigned ActiveX controls are blocked in IE and signed ActiveX controls will raise a prompt. 默认情况下,未签名的ActiveX控件在IE中被阻止,并且已签名的ActiveX控件将引发提示。

I would try un-registering the DLL, changing the GUID, and re-registering your class. 我将尝试注销DLL,更改GUID并重新注册您的类。 Since setting MyParam appears to work, it may be that Open() was added at a later time, and the interface definition is not getting re-registered. 由于设置MyParam 似乎可以工作,因此可能是在以后添加了Open() ,并且接口定义没有重新注册。

You have to register your ActiveX control using the Microsoft .Net Framework regasm.exe tool. 您必须使用Microsoft .Net Framework regasm.exe工具注册ActiveX控件。

To register your ActiveX control use the following steps: 要注册您的ActiveX控件,请使用以下步骤:

  1. Open a command prompt. 打开命令提示符。
  2. Navigate the installation directory of the .Net framework you are targeting (eg c:\\windows\\Microsoft.NET\\Framework) 浏览您要定位的.Net框架的安装目录(例如c:\\ windows \\ Microsoft.NET \\ Framework)
  3. Type the following command 输入以下命令

    regasm.exe /tlb /codebase "path to your ActiveX.dll" regasm.exe / tlb / codebase“您的ActiveX.dll的路径”

  4. Please note, if you are running on a x64 bit operating system you have to register your ActiveX control for x86 and x64 internet explorer. 请注意,如果您在x64位操作系统上运行,则必须为x86和x64 Internet Explorer注册ActiveX控件。 For x64 internet explorer you have to navigate to the x64 directory of the .Net Framework you are targeting and execute the following command: 对于x64 Internet Explorer,您必须导航到要定位的.Net Framework的x64目录,并执行以下命令:

    regasm.exe /tlb /codebase "path to your x64 ActiveX.dll" regasm.exe / tlb / codebase“ x64 ActiveX.dll的路径”

During registration of your ActiveX dll you should see a message box with the message "Registered". 在ActiveX dll的注册过程中,您应该看到一个消息框,其中显示消息“已注册”。 Please not, if you compile your dlls with platform target "Any CPU" you can use the same dll for registering. 请不要,如果使用平台目标“任何CPU”编译dll,则可以使用相同的dll进行注册。

从方法名称中删除static,就可以了!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM