2017-06-02 64 views
11

CefSharp(Stable 57.0)を使用してC#でJavaScriptを実行しようとすると、エラーが発生します。私は単にアラート機能を実行しようとしているので、機能していることを確認して後で自分の機能でテストすることができます。しかし、私はそうしようとして間違っているようです。CefSharpでJavaScriptを実行するWPFによってエラーが発生する

public partial class WebBrowserWindow : Window 
{ 
    public WebBrowserWindow() 
    { 
     InitializeComponent(); 
     webBrowser.MenuHandler = new ContextMenuHandler(); 
     webBrowser.RequestHandler = new RequestHandler(); 
    } 

    //Trying to execute this with either method gives me an error. 
    public void ExecuteJavaScript() 
    { 
     //webBrowser.GetMainFrame().ExecuteJavaScriptAsync("alert('test')"); 

     //webBrowser.ExecuteScriptAsync("alert('test');"); 
    } 
} 

私は両方の方法でスクリプトを実行しようとしました。

最初の1に:

webBrowser.GetMainFrame().ExecuteJavaScriptAsync("alert('test')"); 

は私に、このエラーを与える:

enter image description here

秒:

webBrowser.ExecuteScriptAsync("alert('test');"); 

は私に、このエラーを与える:

enter image description here

私の目的は、CefSharpブラウザでJavaScript関数を実行できるC#関数を作成することです。

私は多くのリンク/参照を試しましたが、スタックオーバーフローでその多くはありませんでした。私もThe FAQ for CefSharpを読んで、JavaScriptをC#で自由に実行できるような簡単な例は見つかりませんでした。

さらに、フレームがロードされ(ロードが完了した)、アンロードされた(アンロードされていない)イベント、およびWebブラウザがnullの場合:

webBrowser.GetMainFrame().ExecuteJavaScriptAsync("alert('test')"); 

でも、最初のエラーが発生します。

私はGetMainFrame()をテストしました。常にnullを返します。常に。どれくらい待っているか、私が確認する条件は関係ありません。

重要

私は情報の一つの重要な部分を追加するのを忘れ、私は私のプロジェクトで2つのアセンブリを持っています。それらの両方が別々の実行ファイルにコンパイル:

Helper.exe MAIN.EXEに

MAIN.EXEは、ウィンドウ、ボタンがクリックされますと、それは私が「ExecuteJavaScriptを作成したメソッドを実行し、「CallUIを」()があります"、これは私のウィンドウ" BrowserWindow "の中にあります。 CallUIウィンドウはHelper.exeで宣言され、初期化されます。

私は基本的に別のプログラムを使用してウィンドウを開き、メソッドを呼び出してJavaScriptを実行するボタンをクリックしようとしています。だから私は彼らが異なるプロセスであると思う、それはブラウザがnullだと私に伝えます。しかし、私がMain.exeでそれをすべて実行すると、うまく動作します。別のプロセスを使用してHelper.exeからウィンドウを作成し、Main.exeからJavascriptを実行するための回避策がありますか?

+0

このMain.exeとHelper.exeのやり取りについて、再現性のある例(ソースコード)を作成してください。それがなければ、ソリューションを提供し、それが確実に機能することを確認するのは簡単ではありません。 –

+0

ちょっと、問題が解決したので、プロセスが互いに話す方法を実装しなければなりませんでした(私の長い答えは以下を参照してください)。私は私の答えについての余分な質問もしていました(私の答えのコメントの部分にあります)。 – Rafael

答えて

4

それは私が問題に間違った方法を処理していたことを私の注意に来ています。

私の問題は、すべてのコードをまとめた単一のプロセスであれば、実際には存在しません。しかし、私のプロジェクトが別のプロジェクトと通信しようとしていた実行可能ファイルを持っているということが問題でした。私は実際に私のhelper.exeが私のmain.exeと適切に対話する方法を持っていなかった。

私がこれから学んだのは、プロセスが共有アドレスアクセスなしでお互いに話そうとしていたことです。彼らは別のアドレス空間に住んでいるので、helper.exeがMain.exeに属するjavascript部分を実行しようとするたびに、自身のアドレス空間に属し、メインではないブラウザの初期化されていないバージョンでスクリプトを実行しようとしていました。EXE。

どのように問題を解決しましたか? helper.exeプロセスがmain.exeプロセスと通信できるようにする重要な部分を含める必要がありました。私はプロセスがお互いに話す方法を探って、私はMemoryMappedFilesについて知りました。だから私はHelper.exeがMain.exeにメッセージを送ることを可能にする私のプログラムに簡単な例を実装することに決めました。

これは例です。これは私がこれはMAIN.EXEとHelper.exeの両方を使用することができますdllファイルにコンパイルされ

public class MemoryMappedHandler 
{ 
    MemoryMappedFile mmf = MemoryMappedFile.CreateOrOpen("mmf1", 512); 
    MemoryMappedViewStream stream; 
    MemoryMappedViewAccessor accessor; 
    BinaryReader reader; 
    public static Message message = new Message(); 

    public MemoryMappedHandler() 
    { 
     stream = mmf.CreateViewStream(); 
     accessor = mmf.CreateViewAccessor(); 
     reader = new BinaryReader(stream); 

     new Thread(() => 
     { 
      while (stream.CanRead) 
      { 
       Thread.Sleep(500); 
       message.MyStringWithEvent = reader.ReadString(); 
       accessor.Write(0, 0); 
       stream.Position = 0; 
      } 
     }).Start(); 

    } 

    public static void PassMessage(string message) 
    { 
     try 
     { 
      using (MemoryMappedFile mmf = MemoryMappedFile.OpenExisting("mmf1")) 
      { 
       using (MemoryMappedViewStream stream = mmf.CreateViewStream(0, 512)) 
       { 
        BinaryWriter writer = new BinaryWriter(stream); 
        writer.Write(message); 
       } 
      } 
     } 
     catch (FileNotFoundException) 
     { 
      MessageBox.Show("Cannot Send a Message. Please open Main.exe"); 
     } 
    } 
} 

「MemoryMappedHandler.cs」と呼ばれる作成されたファイルです。

Helper.exeは、 "mmf1"というメモリマップファイルにメッセージを送信するためにPassMessage()メソッドを使用します。常に開いておく必要があるMain.exeは、Helper.exeからメッセージを受け取ることができるファイルを作成します。そのメッセージを保持しているクラスにそのメッセージを送信し、受信するたびにイベントをアクティブにします。ここで

は、メッセージクラスは次のようになります。

public partial class WebBrowserWindow : Window 
{ 
    public WebBrowserWindow() 
    { 
     InitializeComponent(); 
     webBrowser.MenuHandler = new ContextMenuHandler(); 
     webBrowser.RequestHandler = new RequestHandler(); 
     MemoryMappedHandler.message.HasMessage += Message_HasMessage; 
    } 

    private void Message_HasMessage(object sender, EventArgs e) 
    { 
     ExecuteJavaScript(MemoryMappedHandler.message.MyStringWithEvent); 
    } 

    public void ExecuteJavaScript(string message) 
    { 
     //webBrowser.GetMainFrame().ExecuteJavaScriptAsync("alert('test')"); 

     //webBrowser.ExecuteScriptAsync("alert('test');"); 
    } 
} 

そして今、それは私ではJavaScriptを実行することができます:

[Serializable] 
public class Message 
{ 
    public event EventHandler HasMessage; 

    public string _myStringWithEvent; 

    public string MyStringWithEvent 
    { 
     get { return _myStringWithEvent; } 
     set 
     { 
      _myStringWithEvent = value; 
      if (value != null && value != String.Empty) 
      { 
       if (HasMessage != null) 
        HasMessage(this, EventArgs.Empty); 
      } 
     } 
    } 
} 

は最後に、私はこのように私のWebBrowserWindowクラスにメッセージを初期化しなければなりませんでしたHelper.exeからMain.exeにメッセージを送信する必要があります。

+0

もう1つ:私は自分のMemoryMappedFileをより良くしたいです。今、Helper.exeから同じメッセージを送信すると、最初に(メッセージプロパティをどのように設定するかによって)初めて実行されるバグがあります。受信ストリーム(MemoryMappedViewStream)(MemoryMappedHandlerコンストラクタ内)をクリアするにはどうすればよいですか?私は "Flush()"のような多くのことを試み、mmf1に空のメッセージを書いていました(メッセージの最初の文字だけを削除します)。 – Rafael

+0

思考の少しの後で、私は上記の私のコメントに記載された問題を解決しました。 – Rafael

3

このリンクをお試しください。ブラウザが最初に初期化されているかどうかをチェックするスニペットを含みます。

cefsharp execute javascript

private void OnIsBrowserInitializedChanged(object sender, IsBrowserInitializedChangedEventArgs args) 
{ 
    if(args.IsBrowserInitialized) 
    { 
     browser.ExecuteScriptAsync("alert('test');"); 
    } 
} 
+1

はい、私はすでにそれを試みました。 CefSharpのバージョン57では、IsBrowserInitializedChangedイベントでIsBrowserInitializedChangedEventArgsを使用せず、依存関係プロパティーを使用します。それだけでなく、私はまだブラウザが初期化された/ nullでないことが確認された後、私のメソッドを独立して実行することができず、上記の同じエラーメッセージを出します。 – Rafael

関連する問題