簡體   English   中英

使用C#使用ActiveX對象運行DLL

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

嗨,我有以下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
    }
}

我已經創建了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>

現在,當我在Internet Explorer瀏覽器中運行html頁面時,出現以下錯誤:

對象不支持屬性或方法開放

你能幫我解決這些問題嗎

等待您的寶貴意見和回應

在IE中打開測試頁的情況下,從工具欄上的工具按鈕(在IE9中)打開“ Internet選項”,選擇“ 安全性”頁面,單擊“ 自定義”按鈕,然后向下滾動到“ ActiveX控件和插件”部分。 您可以在此處啟用提示/啟用ActiveX控件並對其進行腳本編寫。

默認情況下,未簽名的ActiveX控件在IE中被阻止,並且已簽名的ActiveX控件將引發提示。

我將嘗試注銷DLL,更改GUID並重新注冊您的類。 由於設置MyParam 似乎可以工作,因此可能是在以后添加了Open() ,並且接口定義沒有重新注冊。

您必須使用Microsoft .Net Framework regasm.exe工具注冊ActiveX控件。

要注冊您的ActiveX控件,請使用以下步驟:

  1. 打開命令提示符。
  2. 瀏覽您要定位的.Net框架的安裝目錄(例如c:\\ windows \\ Microsoft.NET \\ Framework)
  3. 輸入以下命令

    regasm.exe / tlb / codebase“您的ActiveX.dll的路徑”

  4. 請注意,如果您在x64位操作系統上運行,則必須為x86和x64 Internet Explorer注冊ActiveX控件。 對於x64 Internet Explorer,您必須導航到要定位的.Net Framework的x64目錄,並執行以下命令:

    regasm.exe / tlb / codebase“ x64 ActiveX.dll的路徑”

在ActiveX dll的注冊過程中,您應該看到一個消息框,其中顯示消息“已注冊”。 請不要,如果使用平台目標“任何CPU”編譯dll,則可以使用相同的dll進行注冊。

從方法名稱中刪除static,就可以了!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM