C# 使用c运行带有activex对象的dll#
您好,我有以下c#代码,用于将活动x组件配置为C# 使用c运行带有activex对象的dll#,c#,javascript,.net,com,activex,C#,Javascript,.net,Com,Activex,您好,我有以下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 { /// <sum
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
}
}
使用系统;
运用系统反思;
使用System.Runtime.InteropServices;
使用系统文本;
使用系统线程;
使用System.Windows.Forms;
使用Microsoft.Win32;
命名空间Kosmala.Michal.ActiveXTest
{
///
///1类的概要说明。
///
[ProgId(“Dendrite.WebForce.MMP.Web.OurActiveX”)]
[ClassInterface(ClassInterfaceType.AutoDual),ComSourceInterfaces(typeof(ControlEvents))]//实现从JS可见的接口
[Guid(“121C3E0E-DC6E-45dc-952B-A6617F0FAA32”)]
[ComVisible(true)]
公共类ActiveXObject
{
私有字符串myParam=“Empty”;
公共ActiveXObject()
{
}
公共事件控制事件处理程序OnClose;
///
///打开应用程序。从JS调用
///
[ComVisible(true)]
公开作废
{
//TODO:用下面的try-catch替换aspx中的try-catch。问题是js OnClose没有注册。
尝试
{
Show(myParam);//显示从JS传递的参数
Thread.Sleep(2000);//在关闭之前稍等片刻。这只是为了显示调用OnClose事件之间的间隔。
Close();//关闭应用程序
}
捕获(例外e)
{
//例外处理。例外情况(e);
投掷e;
}
}
///
///参数在JS中可见
///
[ComVisible(true)]
公共字符串MyParam
{
得到
{
返回myParam;
}
设置
{
myParam=值;
}
}
[ComVisible(true)]
公众假期结束()
{
if(OnClose!=null)
{
OnClose(“http://otherwebsite.com“”;//调用将在JS中捕获的事件
}
其他的
{
MessageBox.Show(“未附加任何事件”);//如果未附加任何事件,则发送消息。
}
}
///
///将类注册为控件并设置其代码基条目
///
///控件的注册表项
[ComRegisterFunction()]
公共静态无效注册表类(字符串键)
{
//从传递的密钥中删除HKEY\U CLASSES\U ROOT\因为我不需要它
StringBuilder sb=新的StringBuilder(键);
sb.替换(@“HKEY_CLASSES_ROOT\”,“”);
//打开CLSID\{guid}键进行写访问
RegistryKey k=Registry.ClassesRoot.OpenSubKey(sb.ToString(),true);
//并创建“控制”键-这允许它显示在
//ActiveX控件容器
注册表键ctrl=k.CreateSubKey(“控件”);
ctrl.Close();
//下一步创建代码基条目-如果不是字符串named和GACced,则为needed。
RegistryKey inprocServer32=k.OpenSubKey(“inprocServer32”,true);
inprocServer32.SetValue(“CodeBase”,Assembly.getExecutionGassembly().CodeBase);
inprocServer32.Close();
//最后关闭主键
k、 关闭();
MessageBox.Show(“已注册”);
}
///
///调用以注销控件
///
///Tke注册表项
[ComUnregisterFunction()]
公共静态void unregister类(字符串键)
{
StringBuilder sb=新的StringBuilder(键);
sb.替换(@“HKEY_CLASSES_ROOT\”,“”);
//打开HKCR\CLSID\{guid}进行写访问
RegistryKey k=Registry.ClassesRoot.OpenSubKey(sb.ToString(),true);
//删除“Control”键,但如果它不存在,请不要引发异常
k、 DeleteSubKey(“控制”,false);
//下一步在ProcServer32中打开
//注册表项inprocServer32=
k、 OpenSubKey(“InprocServer32”,true);
//并删除代码基密钥,如果丢失,则再次不抛出
k、 DeleteSubKey(“代码基”,false);
//最后关闭主键
k、 关闭();
MessageBox.Show(“未注册”);
}
}
///
///JavaScript中可见事件的事件处理程序
///
公共委托void ControlEventHandler(字符串重定向URL);
///
///此接口向javascript显示事件
///
[Guid(“68BD4E0D-D7BC-4cf6-BEB7-CAB950161E79”)]
[接口类型(ComInterfaceType.InterfaceIsIDispatch)]
公共接口控制事件
{
//向源接口中的任何成员添加DispIdAttribute以指定COM DispId。
[DispId(0x60020001)]
void OnClose(字符串重定向URL);//此方法将在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>
网络表单1
在IE中打开测试页面后,从工具栏上的工具按钮(在IE9中)打开Internet选项,选择安全页面,单击自定义按钮并向下滚动到“ActiveX控件和插件”部分。您可以在此处启用ActiveX控件的提示/启用以及它们的脚本编写
默认情况下,未签名的ActiveX控件在IE中被阻止,签名的ActiveX控件将发出提示。我将尝试取消注册DLL,更改GUID,然后重新注册您的类。由于设置MyParam
似乎有效,可能是后来添加了Open()
,并且没有重新注册接口定义。您必须使用
Microsoft.Net Framework regasm.exe工具
要注册ActiveX控件,请使用