3
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

public static class Program
{
    [STAThread]
    public static void Main()
    {
        using (var browser = new WebBrowser())
        {
            browser.Navigate(string.Empty);

            browser.Document.InvokeScript("execScript", new object[] { "function set_obj(obj) { window.obj = obj }" });
            browser.Document.InvokeScript("execScript", new object[] { "function say_hello() { window.obj.WriteLine('Hello world') }" });

            browser.Document.InvokeScript("set_obj", new object[] { new Obj() });
            browser.Document.InvokeScript("say_hello");

            browser.Document.InvokeScript("setTimeout", new object[] { "say_hello()", 100 });
            Console.ReadKey();
        }
    }
}

[ComVisible(true)]
public sealed class Obj
{
    public void WriteLine(string message)
    {
        Console.WriteLine(message);
    }
}

メソッドsay_helloの即時呼び出しは正常に機能しますが、setTimeoutを使用して延期すると、呼び出されません。なんで?回避策はありますか?

4

3 に答える 3

4

ユーザー@controlflowが指摘したように、setTimeoutを機能させるには、アプリケーションにメッセージループが必要です。次の行を追加すると、次のようになります。

Application.Run(new Form { Controls = { browser }, WindowState = FormWindowState.Minimized, ShowInTaskbar = false });
于 2011-07-05T20:36:38.270 に答える
2

say_helloを呼び出そうとしているのではないので、say_helloの後に括弧を付けないでください。ただし、関数へのデリゲートとして渡します。だから試してみてください:

browser.Document.InvokeScript("setTimeout", new object[] { "say_hello", 100 });

また、コンソールにエラーはありますか?

更新

試す:

browser.Document.InvokeScript("setTimeout(say_hello, 100);");

また、試してみてください:

browser.Document.InvokeScript("setTimeout", new object[] { "say_hello", "100" });

問題が何であれ、JavaScriptエラーがどこかに飲み込まれている可能性があります。レンダリングされたマークアップとスクリプトを書き出して、ブラウザの通常のWebページで実行してみてください。

于 2011-07-05T18:33:14.977 に答える
0

次の行を変更する必要があります

browser.Document.InvokeScript("say_hello");

browser.Document.InvokeScript("say_hello()");

これはjavascript例外をスローし、おそらくそれが次のコマンドが実行されない理由です。

于 2011-07-05T19:10:34.740 に答える