Hello:
For my project, I have to automatically run some JavaScript every minute in WebView2. Even I can manually click on the button to run the JavaScript and get the result, but I can’t figure out how to use timer to run the job automatically.
I have done the following:
I created one Windows Forms App (.NET) and set target to .NET 5.0; then I install WebView2 Nuget package: Install-Package Microsoft.Web.WebView2 -Version 1.0.664.37
I didn’t use Windows Forms Designer, but I write the following code by hand:
I use Visual Studio 2019 Version 16.8.4, my OS is Windows 10 (Version 20H2)
using Microsoft.Web.WebView2.WinForms;
using System;
using System.Diagnostics;
using System.Drawing;
using System.Threading.Tasks;
using System.Windows.Forms;
using Timer = System.Timers.Timer;
namespace WebView2Buttons
{
public partial class Form1 : Form
{
private readonly WebView2 BingWebView = new WebView2();
private readonly Button MinuteButton = new Button();
private readonly Button Button1 = new Button();
private static Timer MinuteTimer;
private async void MinuteTimerElapsedAsync(Object source, System.Timers.ElapsedEventArgs e)
{
try
{
MinuteButton.PerformClick();
}
catch (TimeoutException ex)
{
Debug.WriteLine("[MinuteTimerElapsedAsync]: " + ex.Message);
await Task.Delay(1);
}
}
private async void MinuteButton_Click(object sender, EventArgs e)
{
string xhr_request =
@"function reqXHR() { let r = new XMLHttpRequest();
r.open('GET', 'https://www.bing.com/', false);
r.send(); var reply = r.responseText; return reply;}; reqXHR(); ";
string raw_data =
await BingWebView.CoreWebView2.ExecuteScriptAsync(xhr_request);
Debug.WriteLine(raw_data);
}
private async void Button1_Click(object sender, EventArgs e)
{
string xhr_request =
@"function reqXHR() { let r = new XMLHttpRequest();
r.open('GET', 'https://www.bing.com/', false);
r.send(); var reply = r.responseText; return reply;}; reqXHR(); ";
string raw_data =
await BingWebView.CoreWebView2.ExecuteScriptAsync(xhr_request);
Debug.WriteLine(raw_data);
}
public Form1()
{
InitializeComponent();
Control.CheckForIllegalCrossThreadCalls = false;
BingWebView.CreationProperties = null;
BingWebView.Location = new Point(10, 65);
BingWebView.Name = "BingWebView";
BingWebView.Size = new Size(1750, 780);
BingWebView.Source = new Uri("https://www.bing.com/", UriKind.Absolute);
BingWebView.TabIndex = 0;
BingWebView.Text = "BingWebView";
BingWebView.ZoomFactor = 1D;
BingWebView.Visible = true;
this.SuspendLayout();
MinuteButton.Location = new Point(1500, 10);
MinuteButton.Name = "MinuteButton";
MinuteButton.Size = new Size(250, 50);
MinuteButton.TabIndex = 1;
MinuteButton.Text = "MinuteButton";
MinuteButton.UseVisualStyleBackColor = true;
MinuteButton.Click += new EventHandler(MinuteButton_Click);
Button1.Location = new Point(50, 10);
Button1.Name = "Button1";
Button1.Size = new Size(250, 50);
Button1.TabIndex = 2;
Button1.Text = "Button1";
Button1.UseVisualStyleBackColor = true;
Button1.Click += new EventHandler(Button1_Click);
ClientSize = new Size(1800, 800);
Controls.Add(BingWebView);
Controls.Add(MinuteButton);
Controls.Add(Button1);
Name = "Form1";
Text = "Form1";
Load += new EventHandler(Form1_Load);
ResumeLayout(false);
}
private void Form1_Load(object sender, EventArgs e)
{
MinuteTimer = new Timer(60000);
MinuteTimer.Elapsed += MinuteTimerElapsedAsync;
MinuteTimer.AutoReset = true;
MinuteTimer.Enabled = true;
MinuteTimer.Start();
}
}
}
If I click on either buttons of “Button1” or “MinuteButton”, my code works. But in the minute timer to automatically click “MinuteButton” did NOT work.
I saw the error:
System.InvalidCastException
HResult=0x80004002
Message=Unable to cast COM object of type 'System.__ComObject' to interface type 'Microsoft.Web.WebView2.Core.Raw.ICoreWebView2Controller'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{4D00C0D1-9434-4EB6-8078-8697A560334F}' failed due to the following error: No such interface supported (0x80004002 (E_NOINTERFACE)).
Source=System.Private.CoreLib
StackTrace:
at System.StubHelpers.StubHelpers.GetCOMIPFromRCW(Object objSrc, IntPtr pCPCMD, IntPtr& ppTarget, Boolean& pfNeedsRelease)
at Microsoft.Web.WebView2.Core.Raw.ICoreWebView2Controller.get_CoreWebView2()
at Microsoft.Web.WebView2.Core.CoreWebView2Controller.get_CoreWebView2()
at Microsoft.Web.WebView2.WinForms.WebView2.get_CoreWebView2()
at WebView2Buttons.Form1.<MinuteButton_Click>d__5.MoveNext() in C:\WebView2Buttons\WebView2Buttons\Form1.cs:line 37
I don’t understand the difference between I click on the button by mouse and the statement MinuteButton.PerformClick()
Let me know if I can do this or not.
By the way, I don’t necessarily have to use click button code, but I think I have to use a Timer, as I have to run some JavaScript code every minute.
Thanks,