Appelez un script dans WebBrowser et attendez qu'il finisse son exécution (synchronisé)

J'utilise webBrowser.Document.InvokeScript("Function") pour exécuter un javascript, situé dans un fichier local ouvert avec Winforms WebBrowser.

Le problème est que j'ai besoin de javascript pour terminer l'exécution avant de continuer. Comment puis-je attendre / écouter cela?

C'est mon code C #:

  private void Button1_ItemClick_1(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { webBrowser.Document.InvokeScript("Script_A"); Method_A(); DialogResult = System.Windows.Forms.DialogResult.OK; } 

Code Javascript:

 <script>function Script_A() { Script_B(); }</script> 

Comment puis-je m'assurer que Method_A n'est pas exécuté avant que Script_B ne soit terminé?

En utilisant async / attendez vous pouvez attendre que le script soit exécuté sans bloquer l'interface utilisateur.

 public async void AMethod() { string script = @"<script> function Script_A() { Script_B(); window.external.Completed(); //call C#: CallbackObject's Completed method } function Script_B(){ alert('in script'); } </script>"; TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>(); webBrowser1.ObjectForScripting = new CallbackObject(tcs); //Ensure DocumentText is loaded before invoking "InvokeScript", //by extension method "SetDocumentTextAsync" (below) await webBrowser1.SetDocumentTextAsync(script); webBrowser1.Document.InvokeScript("Script_A"); await tcs.Task; MessageBox.Show("Script executed"); } [ComVisible(true)] public class CallbackObject { TaskCompletionSource<bool> _tcs = null; public CallbackObject(TaskCompletionSource<bool> tcs) { _tcs = tcs; } public void Completed() { _tcs.TrySetResult(true); } } public static class BrowserExtensions { public static Task SetDocumentTextAsync(this WebBrowser wb, string html) { TaskCompletionSource<object> tcs = new TaskCompletionSource<object>(); WebBrowserDocumentCompletedEventHandler completedEvent = null; completedEvent = (sender, e) => { wb.DocumentCompleted -= completedEvent; tcs.SetResult(null); }; wb.DocumentCompleted += completedEvent; wb.ScriptErrorsSuppressed = true; wb.DocumentText = html; return tcs.Task; } } 

Vous devriez implémenter une méthode de rappel (n'oubliez pas ComVisible-Attribute ) que vous appelez à partir de votre script en utilisant

 window.mymethod(); 

De cette façon, vous devriez vraiment "diviser" votre méthode.

Voici une bonne publication de SO.


Et voici un tutoriel:

Appelez une méthode C # à partir de JavaScript hébergé dans un WebBrowser

Par AspDotNetDev, le 6 mai 2011

Cet exemple montre comment appeler C # à partir de JavaScript. Il montre également que les paramètres peuvent être transmis aux méthodes C #.

Tout d'abord, créez une application Windows Forms. Ensuite, ajoutez un contrôle WebBrowser à votre formulaire. Ensuite, modifiez le code du formulaire pour qu'il ressemble à ceci:

  namespace WindowsFormsApplication6 { // This first namespace is required for the ComVisible attribute used on the ScriptManager class. using System.Runtime.InteropServices; using System.Windows.Forms; // This is your form. public partial class Form1 : Form { // This nested class must be ComVisible for the JavaScript to be able to call it. [ComVisible(true)] public class ScriptManager { // Variable to store the form of type Form1. private Form1 mForm; // Constructor. public ScriptManager(Form1 form) { // Save the form so it can be referenced later. mForm = form; } // This method can be called from JavaScript. public void MethodToCallFromScript() { // Call a method on the form. mForm.DoSomething(); } // This method can also be called from JavaScript. public void AnotherMethod(string message) { MessageBox.Show(message); } } // This method will be called by the other method (MethodToCallFromScript) that gets called by JavaScript. public void DoSomething() { // Indicate success. MessageBox.Show("It worked!"); } // Constructor. public Form1() { // Boilerplate code. InitializeComponent(); // Set the WebBrowser to use an instance of the ScriptManager to handle method calls to C#. webBrowser1.ObjectForScripting = new ScriptManager(this); // Create the webpage. webBrowser1.DocumentText = @"<html> <head> <title>Test</title> </head> <body> <input type=""button"" value=""Go!"" onclick=""window.external.MethodToCallFromScript();"" /> <br /> <input type=""button"" value=""Go Again!"" onclick=""window.external.AnotherMethod('Hello');"" /> </body> </html>"; } } } 

Notez que votre application peut faire partie d'un espace de noms autre que WindowsFormsApplication6, mais le reste du code devrait fonctionner si vous suivez explicitement les instructions ci-dessus. J'ai créé ce conseil / truc parce que quelqu'un m'a posé une question et ils n'ont pas compris cet échantillon auquel je les ai envoyés. Cette astuce rend l'échantillon plus compréhensible en fixant les deux bugs que j'ai repérés, en ajoutant les déclarations utilisables qui n'ont pas été mentionnées et en commentant fortement le code. J'espère que le reste d'entre vous trouvera cela aussi utile. Licence