gpt4 book ai didi

c# - 在 C# 中创建 COM/ActiveXObject,从 JScript 使用,使用简单的事件

转载 作者:太空狗 更新时间:2023-10-29 17:39:26 26 4
gpt4 key购买 nike

我想在 C# 中创建一个 COM 对象,并通过 JScript 中的 IDispatch 使用它。这部分非常简单。

我还想在 COM 对象上实现简单的回调,类似于由可在浏览器中使用的 XmlHttpRequest 对象公开的事件。该模型允许 Javascript 像这样附加事件处理程序:

var xmlhttp = new ActiveXObject("MSXML.XMLHTTP"); 
xmlhttp.onReadyStateChange = function() {
...
};

我希望我的客户端 JScript 代码如下所示:

var myObject = new ActiveXObject("MyObject.ProgId");
myObject.onMyCustomEvent = function(..args here..) {
...
};

C# 代码是什么样的?我喜欢一般情况 - 我希望能够将参数传递回 Javascript fn。


我看过 How can I make an ActiveX control written with C# raise events in JavaScript when clicked? ,但那里的答案看起来实现起来真的很复杂,使用起来也很复杂。


this article 看来,XMLHttpRequest 事件似乎不是 COM 事件。 onreadystatechangeIDispatch 类型的属性。当脚本客户端将该属性设置为函数时,JScript 将其作为 IDispatch 对象进行编码。

剩下的唯一问题就是从 C# 调用 IDispatch。

最佳答案

既然是COM,那就从定义接口(interface)开始吧。让我们保持简单。

[Guid("a5ee0756-0cbb-4cf1-9a9c-509407d5eed6")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IGreet
{
[DispId(1)]
string Hello(string name);

[DispId(2)]
Object onHello { get; set; }
}

然后,实现:

[ProgId("Cheeso.Greet")]
[ComVisible(true)]
[Guid("bebcfaff-d2f4-4447-ac9f-91bf63b770d8")]
[ClassInterface(ClassInterfaceType.None)]
public partial class Greet : IGreet
{
public Object onHello { get; set; }

public String Hello(string name)
{
var r = FireEvent();
return "Why, Hello, " + name + "!!!" + r;
}
}

主要技巧是 FireEvent 方法。这对我有用。

    private string FireEvent()
{
if (onHello == null) return " (N/A)";
onHello
.GetType()
.InvokeMember
("",
BindingFlags.InvokeMethod,
null,
onHello,
new object [] {});

return "ok";
}

一起编译,用regasm注册:

%NET64%\regasm.exe Cheeso.Greet.dll /register /codebase

...然后像这样在 JScript 中使用它:

var greet = new ActiveXObject("Cheeso.Greet"), response;
greet.onHello = function() {
WScript.Echo("onHello (Javascript) invoked.");
};
response = greet.Hello("Fred");
WScript.Echo("response: " + response);

它有效。

您也可以从 VBScript 中调用它:

Sub onHello ()
WScript.Echo("onHello (VBScript) invoked.")
End Sub

Dim greet
Set greet = WScript.CreateObject("Cheeso.Greet")
greet.onHello = GetRef("onHello")
Dim response
response = greet.Hello("Louise")
WScript.Echo("response: " & response)

要使用这种方法将参数从 C# 传回 JScript,我认为对象需要是 IDispatch,但当然你可以发回简单的值,这些值被编码为 string、int 等,它们的编码方式与你预期的一样。

例如,修改 C# 代码以发送回对自身的引用,以及数字 42。

        onHello
.GetType()
.InvokeMember
("",
BindingFlags.InvokeMethod,
null,
onHello,
new object [] { this, 42 });

然后,您可以像这样在 jscript 中获取它:

greet.onHello = function(arg, num) {
WScript.Echo("onHello (Javascript) invoked.");
WScript.Echo(" num = " + num + " stat=" + arg.status);
};

或者像这样在 VBScript 中:

Sub onHello (obj, num)
WScript.Echo("onHello (VBScript) invoked. status=" & obj.status )
WScript.Echo(" num= " & num)
End Sub

注意:您可以定义 jscript 事件处理程序函数,以接受比调用“事件”时 C# 对象发送的参数更少的参数。根据我的经验,您需要在 VBScript 中设计事件处理程序以明确接受正确数量的参数。

关于c# - 在 C# 中创建 COM/ActiveXObject,从 JScript 使用,使用简单的事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11175145/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com