【问题标题】:how to click button in c# webview如何在 c# webview 中单击按钮
【发布时间】:2021-04-03 17:47:00
【问题描述】:

我正在尝试编写一个可以自动单击网页上的按钮的 c# 程序。我知道我可以使用 chrome 驱动程序,但我不希望它变成浏览器和特定版本的应用程序。

这是我目前想出的,但我在确定如何在找到正确按钮后触发该按钮被点击时遇到了一些困难。

    WebView webView = new WebView();
    var func = string.Format(@"document.getElementsByClassName('size-grid-button').innerText = '{0}';", size);            
    await webView.InvokeScriptAsync("eval", new string[] { func });

编辑 This 是我目前项目的基础,但我找不到基于 innerText 的按钮,然后模拟按钮点击。

【问题讨论】:

标签: c# webview


【解决方案1】:

这是使用 NuGet 包 Microsoft.Web.WebView2(v. 1.0.721-prerelease)的完整代码示例。有关要求,请参阅 Webview2 发行说明。

资源

注意:本示例将使用 WinForms--Windows Forms App (.NET Framework)。使用 .NET Framework 时,支持 >= 4.6.2 的版本(以前需要 4.6.2 或更高版本。但是,如果查看 NuGet 包文件夹,似乎现在所需的最低版本可能是 4.5。请参阅发行说明以获取更多信息)。请参阅其他支持的 SDK 的文档。

支持 Visual Studio 版本 2017 和 2019。如果你没有,你可以Download Visual Studio Community——这是免费的。

下载并安装 Microsoft Edge Dev(又名“Dev Channel”):Microsoft Edge Insider Channels -- 有关其他选项,请参阅文档。

打开 Visual Studio -(2017 或 2019)

默认包管理格式设置为PackageReference(这是可选的,但建议使用)。请参阅Migrate from packages.config to PackageReference 了解更多信息。

2019

  • 点击无代码继续
  • 在 Visual Studio (VS) 菜单中,单击 工具
  • 选择选项
  • 展开 NuGet 包管理器
  • 点击常规
  • 包管理下,将Default package management format: 设置为PackageReference

2017

  • 在 Visual Studio (VS) 菜单中,单击 工具
  • 选择选项
  • 展开 NuGet 包管理器
  • 点击常规
  • 包管理下,将Default package management format: 设置为PackageReference

创建新项目

2019

  • 在VS菜单中,点击文件
  • 选择新建
  • 选择项目
  • 可选:使用以下选项来限制显示的选择:C# Windows 桌面
  • 单击Windows 窗体应用程序(.NET Framework)
  • 点击下一步
  • 为您的项目输入名称(例如:WebView2Test),选择所需位置,并将 Framework 设置为 >= 4.6.2 版本
  • 点击创建

2017

  • 在VS菜单中,点击文件
  • 选择新建
  • 选择项目
  • 展开Visual C#
  • 点击Windows桌面
  • 单击Windows 窗体应用程序(.NET Framework)
  • 为您的项目输入名称(例如:WebView2Test),选择所需位置,并将 Framework 设置为 >= 4.6.2 版本
  • 点击确定

Microsoft.Web.WebView2 NuGet 包添加到项目(2019/2017)

  • 在VS菜单中,点击查看
  • 选择解决方案资源管理器
  • 在解决方案资源管理器中,右键单击
  • 选择管理 NuGet 包...
  • 点击浏览
  • 检查包括预发布
  • 搜索:Microsoft.Web.WebView2
  • 选择版本1.0.721-prerelease
  • 通过单击左侧旁边的向下箭头设置任何所需的选项 “选项”显示可用选项(即:安装和更新选项 和卸载选项)
  • 点击安装
  • 如果弹出窗口,点击确定

可选:将 MenuStrip 添加到表单 (Form1)

  • 在解决方案资源管理器中,单击 Form1.cs 将其选中
  • 在VS菜单中,点击查看
  • 选择工具箱
  • 展开所有 Windows 窗体
  • 选择菜单条
  • 点击Form (Form1) 将控件添加到Form中

可选:将 StatusStrip 添加到表单 (Form1)

  • 在解决方案资源管理器中,单击 Form1.cs 将其选中
  • 在VS菜单中,点击查看
  • 选择工具箱
  • 展开所有 Windows 窗体
  • 选择StatusStrip
  • 点击Form (Form1) 将控件添加到Form中

将 SplitContainer 添加到表单(Form1)

  • 在解决方案资源管理器中,单击 Form1.cs 将其选中
  • 在VS菜单中,点击查看
  • 选择工具箱
  • 展开所有 Windows 窗体
  • 选择SplitContainer
  • 点击Form (Form1) 将控件添加到Form中

将按钮添加到SplitContainer(splitContainer1)的左侧面板

  • 在解决方案资源管理器中,单击 Form1.cs 将其选中
  • 在VS菜单中,点击查看
  • 选择工具箱
  • 展开所有 Windows 窗体
  • 选择按钮
  • 单击窗体 (Form1) 将控件添加到窗体。如有必要,将按钮移动到 SplitContainer 的左侧面板 (panel1)。

更改按钮属性

  • 在VS菜单中,点击查看
  • 选择属性窗口
  • 在“属性”窗口中,使用下拉菜单选择按钮 (button1)
  • 将(名称)更改为所需的名称(例如:btnClickJSButton)
  • 将文本更改为所需文本(例如:单击 JS 按钮)

将 WebView2 控件添加到 SplitContainer(panel2)

  • 在解决方案资源管理器中,单击 Form1.cs 将其选中
  • 在VS菜单中,点击查看
  • 选择工具箱
  • 展开WebView2 Windows 窗体控件

注意:如果工具箱中没有“WebView2 Windows 窗体控件”,请在工具箱的空白处单击鼠标右键,然后选择“选择项”。然后单击“浏览”。转到 %UserProfile%.nuget\packages\microsoft.web.webview2\1.0.721-prerelease\lib\net45(例如:C:\Users\\.nuget\packages\microsoft.web.webview2\1.0. 721-预发布\lib\net45)。选择“Microsoft.Web.WebView2.WinForms.dll”

  • 选择WebView2
  • 单击窗体 (Form1) 将控件添加到窗体。如有必要,将 WebView2 控件移动到 SplitContainer 的右侧面板(panel2)。

更改 WebView2 属性

  • 在“属性”窗口中,使用下拉菜单选择 WebView2 控件实例 (webView21)
  • Dock 属性设置为 Fill

将 Load 事件处理程序添加到 Form (Form1)

  • 在解决方案资源管理器中,单击 Form1.cs 将其选中
  • 双击窗体顶部,将添加事件处理程序:Form1_Load

添加按钮点击事件处理程序

  • 在解决方案资源管理器中,单击 Form1.cs 将其选中
  • 在窗体(Form1)上,双击按钮(btnClickJSButton),创建点击事件处理程序(btnClickJSButton_Click)

为 HTML 代码创建一个文件夹

  • 在解决方案资源管理器中,右键单击
  • 选择添加
  • 选择新建文件夹。该文件夹将被选中。如果没有,请右键单击该文件夹并选择“重命名”。将名称设置为“HTML”。

创建 index.html

  • 在解决方案资源管理器中,右键单击
  • 右键单击HTML文件夹
  • 选择添加
  • 选择新项目
  • 点击HTML页面(名称:index.html)
  • 点击添加

更改 index.html 属性

  • 在解决方案资源管理器中,单击 index.html 将其选中
  • 在属性窗口中,将 Build Action 设置为 Embedded Resource

将代码添加到:index.html

index.html

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title></title>

    <script>
        function btnClickAction(name) {
            alert('button ' + name + ' was clicked');
        }
    </script>
</head>
<body>

    <button type="button" class="size-grid-button" id="size-grid-button1" onclick="btnClickAction('size-grid-button1')">Click Me 1</button>
    <button type="button" class="size-grid-button" id="size-grid-button2" onclick="btnClickAction('size-grid-button2')">Click Me 2</button>
    <button type="button" class="size-grid-button" id="size-grid-button3" onclick="btnClickAction('size-grid-button3')" value="Click Me 3">Click Me 3</button>

    <input type="button" class="size-grid-button" id="size-grid-button4" onclick="btnClickAction('size-grid-button4')" value="Click Me 4" />

</body>
</html>

为 JavaScript 代码创建一个文件夹

  • 在解决方案资源管理器中,右键单击
  • 选择添加
  • 选择新建文件夹。该文件夹将被选中。如果没有,请右键单击该文件夹并选择“重命名”。将名称设置为“JavaScript”。

创建 TestButtonClick.js

  • 在解决方案资源管理器中,右键单击
  • 右键单击 JavaScript 文件夹
  • 选择添加
  • 选择新项目
  • 点击JavaScript文件(名称:TestButtonClick.js)
  • 点击添加

更改 TestButtonClick.js 属性

  • 在解决方案资源管理器中,单击 TestButtonClick.js 将其选中
  • 在属性窗口中,将 Build Action 设置为 Embedded Resource

选项 1(所需的 HTML 元素是“按钮”)

例子:

<button type="button" class="size-grid-button" id="size-grid-button1" onclick="btnClickAction('size-grid-button1')">Click Me 1</button>

将代码添加到:TestButtonClick.js

TestButtonClick.js(选项 1)

function clickDesiredButtonByInnerText(btnInnerText) {

    //let buttons = document.getElementByTagName('button');
    let buttons = document.querySelectorAll('button');
    let i = 0;
    let result = null;

    if (buttons) {
        
        for (i = 0; i < buttons.length; i++) {
            //window.chrome.webview.postMessage("button[" + i + "].innerText: " + buttons[i].innerText);

            if (buttons[i].innerText === btnInnerText) {
                buttons[i].click();
                result = btnInnerText + ' clicked';
                break; //exit loop
            }
        }
    }

    //window.chrome.webview.postMessage("result:" + result);
    return result;
}

选项 2(所需的 HTML 元素是“输入”)

例子:

<input type="button" class="size-grid-button" id="size-grid-button4" onclick="btnClickAction('size-grid-button4')" value="Click Me 4" />

将代码添加到:TestButtonClick.js

TestButtonClick.js(选项 2)

function clickDesiredInputButtonByTextValue(btnValue) {

    let i = 0;
    let result = null;

    buttons = document.querySelectorAll('input');

    if (buttons) {

        for (i = 0; i < buttons.length; i++) {
            //window.chrome.webview.postMessage("button[" + i + "].value: " + buttons[i].value + ' type: ' + buttons[i].type);

            if (buttons[i].type === 'button' && buttons[i].value === btnValue) {
                buttons[i].click();
                result = btnValue + ' clicked';
                break; //exit loop
            }
        }
    }

    //window.chrome.webview.postMessage("result:" + result);
    return result;
}

选项 3(所需的 HTML 元素是 ('button' OR 'input') AND 元素具有具有唯一值的 'id' 属性)

将代码添加到:TestButtonClick.js

TestButtonClick.js(选项 3)

function clickDesiredButtonById(btnId) {
    let result = null;
    let desiredButton = document.getElementById(btnId);

    if (desiredButton) {
        desiredButton.click();
        result = 'button with id = ' + btnId + ' clicked';
    }

    //window.chrome.webview.postMessage("result:" + result);
    return result;
}

创建一个新类 (HelperLoadResource.cs)

  • 在解决方案资源管理器中,右键单击
  • 选择添加
  • 选择类...(名称:HelperLoadResource.cs)

添加 using 语句 (HelperLoadResource.cs):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Reflection;
using System.Diagnostics;

将代码添加到:HelperLoadResource.cs

注意HelperLoadResource.ReadResource 将从嵌入文件(HTML 和 JavaScript)中读取文本并将文本放入字符串变量中。

HelperLoadResource.cs

public static class HelperLoadResource
{
    public static string ReadResource(string filename)
    {
        //use UTF8 encoding as the default encoding
        return ReadResource(filename, Encoding.UTF8);
    }

    public static string ReadResource(string filename, Encoding fileEncoding)
    {
        string fqResourceName = string.Empty;
        string result = string.Empty;

        //get executing assembly
        Assembly execAssembly = Assembly.GetExecutingAssembly();

        //get resource names
        string[] resourceNames = execAssembly.GetManifestResourceNames();

        if (resourceNames != null && resourceNames.Length > 0)
        {
            foreach (string rName in resourceNames)
            {
                if (rName.EndsWith(filename))
                {

                    //set value to 1st match
                    //if the same filename exists in different folders,
                    //the filename can be specified as <folder name>.<filename>
                    //or <namespace>.<folder name>.<filename>
                    fqResourceName = rName;

                    //exit loop
                    break;
                }
            }

            //if not found, throw exception
            if (String.IsNullOrEmpty(fqResourceName))
            {
                throw new Exception($"Resource '{filename}' not found.");
            }

            //get file text
            using (Stream s = execAssembly.GetManifestResourceStream(fqResourceName))
            {
                using (StreamReader reader = new StreamReader(s, fileEncoding))
                {
                    //get text
                    result = reader.ReadToEnd();
                }
            }
        }

        return result;
    }

}

将代码添加到:Form1.cs

  • 在解决方案资源管理器中,单击
  • 右键单击Form1.cs
  • 选择查看代码

添加 using 语句(Form1.cs):

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.Web.WebView2.Core;
using Microsoft.Web.WebView2.WinForms;
using System.Diagnostics;

添加方法InitializeCoreWebView2Async (Form1.cs)

InitializeCoreWebView2Async (Form1.cs)

private async Task InitializeCoreWebView2Async()
{
    //initialize CorewWebView2
    await webView21.EnsureCoreWebView2Async();
}

将代码添加到Form1_Load (Form1.cs)

注意:将async关键字添加到Form_Load

Form1_Load (Form1.cs)

private async void Form1_Load(object sender, EventArgs e)
{
    //show MS Edge version -- also ensures that an exception will be raised if proper MS Edge version isn't installed
    Debug.WriteLine(CoreWebView2Environment.GetAvailableBrowserVersionString());

    //initialized CorewWebView2
    await InitializeCoreWebView2Async();

    //get HTML
    string html = HelperLoadResource.ReadResource("index.html");
    
    //display HTML in WebView2
    webView21.NavigateToString(html);
    
}

订阅 WebView2 CoreWebView2InitializationCompleted 事件

  • 在“属性”窗口中,使用下拉菜单选择 WebView2 实例 (webView21)
  • 点击橙色闪电图标查看可用事件
  • 双击CoreWebView2InitializationCompleted将事件处理程序添加到Form (Form1.cs)

将以下代码添加到 CoreWebView2InitializationCompleted

CoreWebView2InitializationCompleted (Form1.cs)

private void webView21_CoreWebView2InitializationCompleted(object sender, Microsoft.Web.WebView2.Core.CoreWebView2InitializationCompletedEventArgs e) 
{

    //subscribe to CoreWebView2 events (add event handlers)
    webView21.CoreWebView2.WebMessageReceived += CoreWebView2_WebMessageReceived;         
}

CoreWebView2_WebMessageReceived (Form1.cs)

private void CoreWebView2_WebMessageReceived(object sender, CoreWebView2WebMessageReceivedEventArgs e)
{
    Debug.WriteLine("Info: MSG (JSON): " + e.WebMessageAsJson);
    Debug.WriteLine("Info: MSG (String): " + e.TryGetWebMessageAsString());
}

如果使用上面的选项 1(所需的 HTML 元素是“按钮”),请添加方法 ClickWebView2ButtonByInnerText

ClickWebView2ButtonByInnerText (Form1.cs)

private async Task ClickWebView2ButtonByInnerText(string btnInnerText)
{
    if (webView21 != null && webView21.CoreWebView2 != null)
    {
        string jsCode = HelperLoadResource.ReadResource("TestButtonClick.js");
        jsCode += System.Environment.NewLine;
        jsCode += "clickDesiredButtonByInnerText('" + btnInnerText + "');";

        var result = await webView21.CoreWebView2.ExecuteScriptAsync(jsCode);

        Debug.WriteLine("result: " + result);
    }
}

将以下代码添加到按钮单击事件处理程序btnClickButton_Click(选项 1)

注意:添加async关键字。

private async void btnClickButton_Click(object sender, EventArgs e)
{
    await ClickWebView2ButtonByInnerText("Click Me 3");
}

如果使用上面的选项2(所需的HTML元素是'input'),添加方法ClickWebView2InputButton

ClickWebView2InputButton (Form1.cs)

private async Task ClickWebView2InputButton(string btnValue)
{
    if (webView21 != null && webView21.CoreWebView2 != null)
    {
        string jsCode = HelperLoadResource.ReadResource("TestButtonClick.js");
        jsCode += System.Environment.NewLine;
        jsCode += "clickDesiredInputButtonByTextValue('" + btnValue + "');";

        var result = await webView21.CoreWebView2.ExecuteScriptAsync(jsCode);

        Debug.WriteLine("result: " + result);
    }
}

将以下代码添加到按钮单击事件处理程序btnClickButton_Click(选项 2)

注意:添加async关键字。

private async void btnClickButton_Click(object sender, EventArgs e)
{
    await ClickWebView2InputButton("Click Me 4");
}

如果使用上面的选项 3(所需的 HTML 元素是 ('button' OR 'input') AND 元素具有具有唯一值的 'id' 属性),添加方法 ClickWebView2ButtonById

ClickWebView2ButtonById (Form1.cs)

private async Task ClickWebView2ButtonById(string btnId)
{
    if (webView21 != null && webView21.CoreWebView2 != null)
    {
        string jsCode = HelperLoadResource.ReadResource("TestButtonClick.js");
        jsCode += System.Environment.NewLine;
        jsCode += "clickDesiredButtonById('" + btnId + "');";

        var result = await webView21.CoreWebView2.ExecuteScriptAsync(jsCode);

        Debug.WriteLine("result: " + result);
    }
}

将以下代码添加到按钮单击事件处理程序btnClickButton_Click(选项 3)

注意:添加async关键字。

private async void btnClickButton_Click(object sender, EventArgs e)
{
     await ClickWebView2ButtonById("size-grid-button2");
     await ClickWebView2ButtonById("size-grid-button4");
}

运行程序。 点击表单上的按钮进行测试。

其他资源

【讨论】:

    猜你喜欢
    • 2015-07-18
    • 1970-01-01
    • 2021-12-12
    • 2013-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多