[英]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控件,請使用以下步驟:
輸入以下命令
regasm.exe / tlb / codebase“您的ActiveX.dll的路徑”
請注意,如果您在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.