MSHTML:调用 javascript 对象的成员?

发布于 2025-01-05 00:51:27 字数 389 浏览 2 评论 0原文

使用 .NET WebBrowser 控件,执行 HtmlElement 的成员相当简单。

假设有一个名为“player”的 JavaScript 对象,其成员名为“getLastSongPlayed”;从 .NET WebBrowser 控件调用它会像这样:

HtmlElement elem = webBrowser1.Document.getElementById("player");
elem.InvokeMember("getLastSongPlayed");

现在我的问题是:如何使用 mshtml 来实现这一点?

提前致谢, 奥尔丁

编辑:

我已经启动并运行了它,请参阅下面的答案!

Using the .NET WebBrowser control, it is fairly simple to execute a member of an HtmlElement.

Assuming there is a JavaScript object called "player" with a member called "getLastSongPlayed"; calling this from the .NET WebBrowser control would go something like this:

HtmlElement elem = webBrowser1.Document.getElementById("player");
elem.InvokeMember("getLastSongPlayed");

Now my question is: How do I accomplish that using mshtml ?

Thanks in advance,
Aldin

EDIT:

I got it up and running, see my answer below !

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

痴意少年 2025-01-12 00:51:27

最后 !!我已经启动并运行了!

每当我尝试引用 mshtml.IHTMLDocument2 的parentWindow 和/或将其分配给 mshtml.IHTMLWindow2 窗口对象时,引发该问题的原因都

System.InvalidCastException

与线程有关。

对于某些我不知道的原因,mshtml.IHTMLWindow 的 COM 对象似乎在另一个必须处于单线程单元 (STA) 状态的线程上运行。

所以诀窍是,在具有 STA 状态的另一个线程上调用/执行所需的代码段。

下面是一个示例代码:

SHDocVw.InternetExplorer IE = new SHDocVw.InternetExplorer

bool _isRunning = false;

private void IE_DocumentComplete(object pDisp, ref obj URL)
{
    //Prevent multiple Thread creations because the DocumentComplete event fires for each frame in an HTML-Document
    if (_isRunning) { return; }

    _isRunning = true;

    Thread t = new Thread(new ThreadStart(Do))
    t.SetApartmentState(ApartmentState.STA);
    t.Start();
}

private void Do()
{
    mshtml.IHTMLDocument3 doc = this.IE.Document;

    mshtml.IHTMLElement player = doc.getElementById("player");

    if (player != null)
    {
        //Now we're able to call the objects properties, function (members)
        object value = player.GetType().InvokeMember("getLastSongPlayed", System.Reflection.BindingFlags.InvokeMethod, null, player, null);

        //Do something with the returned value in the "value" object above.
    }
}

我们现在还可以引用 mshtml.IHTMLDocument2 对象的parentWindow 并执行站点脚本和/或我们自己的脚本(记住它必须在 STA 线程上):

mshtml.IHTMLWindow2 window = doc.parentWindow;

window.execScript("AScriptFunctionOrOurOwnScriptCode();", "javascript");

这可能会让人免于在未来。哈哈

FINALLY !! I got it up and running !

The reason for the

System.InvalidCastException

that was thrown, whenever I tried to reference the parentWindow of an mshtml.IHTMLDocument2 and / or assign it to an mshtml.IHTMLWindow2 window object had to do with Threading.

For some, unknown to me, reason it seems that the COM objects of mshtml.IHTMLWindow are operating on another Thread that must be of Single-Threaded Apartment (STA) state.

So the trick was, calling / executing the required piece of code on another Thread with STA state.

Here's a sample code:

SHDocVw.InternetExplorer IE = new SHDocVw.InternetExplorer

bool _isRunning = false;

private void IE_DocumentComplete(object pDisp, ref obj URL)
{
    //Prevent multiple Thread creations because the DocumentComplete event fires for each frame in an HTML-Document
    if (_isRunning) { return; }

    _isRunning = true;

    Thread t = new Thread(new ThreadStart(Do))
    t.SetApartmentState(ApartmentState.STA);
    t.Start();
}

private void Do()
{
    mshtml.IHTMLDocument3 doc = this.IE.Document;

    mshtml.IHTMLElement player = doc.getElementById("player");

    if (player != null)
    {
        //Now we're able to call the objects properties, function (members)
        object value = player.GetType().InvokeMember("getLastSongPlayed", System.Reflection.BindingFlags.InvokeMethod, null, player, null);

        //Do something with the returned value in the "value" object above.
    }
}

We're now also able to reference the parentWindow of an mshtml.IHTMLDocument2 object and execute a sites script and / or our own (remember it must be on an STA thread):

mshtml.IHTMLWindow2 window = doc.parentWindow;

window.execScript("AScriptFunctionOrOurOwnScriptCode();", "javascript");

This might save someone from headaches in the future. lol

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文