GVKun编程网logo

html 中的 Javascript 脚本未从 winform webBrowser 控件触发(活动脚本javascript未开启)

14

对于html中的Javascript脚本未从winformwebBrowser控件触发感兴趣的读者,本文将会是一篇不错的选择,我们将详细介绍活动脚本javascript未开启,并为您提供关于.net–

对于html 中的 Javascript 脚本未从 winform webBrowser 控件触发感兴趣的读者,本文将会是一篇不错的选择,我们将详细介绍活动脚本javascript未开启,并为您提供关于.net – 没有WebBrowser控件的Windows.Forms中的主机Silverlight、.NET中WebBrowser控件调用HTML页面中Frame内部的JavaScript代码、C# Winform中WebBrowser给网页中的input控件赋值/设置值、C# winform嵌入HTML执行Javascript报错的有用信息。

本文目录一览:

html 中的 Javascript 脚本未从 winform webBrowser 控件触发(活动脚本javascript未开启)

html 中的 Javascript 脚本未从 winform webBrowser 控件触发(活动脚本javascript未开启)

如何解决html 中的 Javascript 脚本未从 winform webBrowser 控件触发?

使用以下 html 文件,该文件被加载到 winform webbrowser 的文档中,脚本中的函数和事件不会触发。当 winform 显示时,它只显示带有 id=paybutton 的按钮(参见表单定义)。它不运行第一个脚本(window.YocoSDK 等),该脚本引用了一个在线 sdk(如在 src 中),并在表单上添加了更多字段。这适用于在线 java 测试,但不适用于 c# winforms。任何人都可以提供帮助。

其次,ShowMessage() 函数也不会在单击按钮时触发。

我对两者的猜测是将在线 sdk 包含在“src”字段中没有发生。

HTMLPageSample.html 文件:

<!DOCTYPE html>
<html>
<head>
    <script type=''text/javascript'' src=''https://js.yoco.com/sdk/v1/yoco-sdk-web.js''></script>
</head>
<body>
    <form id=''payform'' method=''POST'' >
        <divone-liner''>
            <div id=''card-frame''>
            </div>
            <button id=''paybutton'' onclick=''ShowMessage()''>
                PAY ZAR 2.00
            </button>
        </div>
        <psuccess-payment-message'' />
    </form>
    <script>
        
            var sdk = new window.YocoSDK({
                publicKey: ''pk_test_blahblah''
            });
            var inline = sdk.inline({
                layout: ''field'',amountInCents: 2000,currency: ''ZAR''
            });
            inline.mount(''#card-frame'');
        
    </script>
    <script>
        function ShowMessage() {
            var form = document.getElementById(''payform'');
            var submitButton = document.getElementById(''paybutton'');

            form.addEventListener(''submit'',function (event) {
                event.preventDefault()
                submitButton.disabled = true;

                inline.createtoken().then(function (result) {

                    submitButton.disabled = false;
                    if (result.error) {
                        const errorMessage = result.error.message;
                        errorMessage && alert(''error occured: '' + errorMessage);
                    } else {
                        const token = result;
                        alert(''card successfully tokenised: '' + token.id);
                    }
                }).catch(function (error) {
                    submitButton.disabled = false;
                    alert(''error occured: '' + error);
                });
            });
        };
    </script>
</body>
</html>





//c# code for the windows form  
    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 System.Runtime.InteropServices;
    namespace WindowsFormsApp1
    {
        [System.Runtime.InteropServices.ComVisibleAttribute(true)]
        public partial class Form1 : Form
        {
            //Class example
            //[ComVisible(true)]
           
            public Form1()
            {
                InitializeComponent();           
                webbrowser1.ScriptErroRSSuppressed = true;
            }
    
            void Form1_Load(object sender,EventArgs e)
            {           
                string path = System.IO.Path.Combine(System.IO.Directory.GetCurrentDirectory(),@"..\..\");
//load the html into the webbrowser document. only the paybutton displays,the referenced library in "src" should call an online sdk that adds the payment fields to the form. these fields do not get added. so it seems the src reference is not working,or the script and form deFinitions cannot "see" each other?
                webbrowser1.Navigate(System.IO.Path.Combine(path,"HTMLPageSample.html"));
            }
            
            void webbrowser1_DocumentCompleted(object sender,WebbrowserDocumentCompletedEventArgs e)
            {
                webbrowser1.ObjectForScripting = this;            
            }
    
            private void button1_Click(object sender,EventArgs e)
            {
//on button click,invoke the script that processes payment (does nothing)
                webbrowser1.Document.InvokeScript("ShowMessage" );
            }
    
            private void button2_Click(object sender,locate paybutton and invoke click method (does nothing)
                foreach (HtmlElement element in webbrowser1.Document.All)
                {
                    if (element.InnerText != null && element.InnerText.ToLower().StartsWith("pay zar"))
                    {
                        element.InvokeMember("click");
                    }
    
                }
            }
        }
    }

解决方法

使用 WebBrowser 时,默认为 IE7,除非注册表中有条目。

如果进程以 64 位运行,则搜索以下注册表项:

  1. HKLM\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION
  2. HKCU\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION

如果进程以 32 位运行,则搜索以下注册表项:

  1. HKLM\SOFTWARE\WOW6432Node\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION
  2. HKCU\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION

注意:虽然在 HKLM 中搜索不同的注册表项,但在搜索 HKCU 时,32 位和 64 位搜索相同的子项。

这是一个模拟 IE11 的名为“MyApp.exe”的程序的示例注册表项。

enter image description here


下面的分步说明显示了如何在 C# 中单击按钮时运行 JavaScript 函数。它使用了 OP 中 HTML 的修改版本。

VS 2019

创建一个新项目:Windows Forms App (.NET Framework)(名称:WebBrowserTest)

创建一个类(名称:HelperRegistry.cs)

注意:以下代码可用于在表单加载时在注册表中添加所需条目。它改编自here。

HelperRegistry

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Win32;
using System.Diagnostics;

namespace WebBrowserTest
{
    public enum BrowserEmulationVersion
    {
        Default = 0,Version7 = 7000,Version8 = 8000,Version8Standards = 8888,Version9 = 9000,Version9Standards = 9999,Version10 = 10000,Version10Standards = 10001,Version11 = 11000,Version11Edge = 11001
    };

    public class HelperRegistry
    {
        public static BrowserEmulationVersion GetBrowserEmulationVersion()
        {
            //get browser emmulation version for this program (if it exists)

            BrowserEmulationVersion result =  BrowserEmulationVersion.Default;

            try
            {
                string programName = System.IO.Path.GetFileName(Environment.GetCommandLineArgs()[0]);

                object data = GetValueFromRegistry(RegistryHive.CurrentUser,@"Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION",programName);
                
                if (data != null)
                {
                    result = (BrowserEmulationVersion)Convert.ToInt32(data);
                }
            }
            catch (System.Security.SecurityException ex)
            {
                // The user does not have the permissions required to read from the registry key.
                LogMsg("Error: (GetBrowserEmulationVersion - SecurityException) - " + ex.Message);
            }
            catch (UnauthorizedAccessException ex)
            {
                // The user does not have the necessary registry rights.
                LogMsg("Error: (GetBrowserEmulationVersion - UnauthorizedAccessException) - " + ex.Message);
            }
            catch (Exception ex)
            {
                LogMsg("Error: (GetBrowserEmulationVersion) - " + ex.Message);
            }

            return result;
        }

        public static int GetInternetExplorerMajorVersion()
        {
            //get IE version

            int result = 0;
            string version = string.Empty;

            try
            {
                string programName = System.IO.Path.GetFileName(Environment.GetCommandLineArgs()[0]);

                object data = GetValueFromRegistry(RegistryHive.LocalMachine,@"Software\Microsoft\Internet Explorer","svcVersion");

                if (data == null)
                    data = GetValueFromRegistry(RegistryHive.CurrentUser,"Version");

                if (data != null)
                {
                    version = data.ToString();
                    int separator = version.IndexOf(''.'');

                    if (separator != -1)
                    {
                        int.TryParse(version.Substring(0,separator),out result);
                    }
                }
            }
            catch (System.Security.SecurityException ex)
            {
                // The user does not have the permissions required to read from the registry key.
                LogMsg("Error: (GetInternetExplorerMajorVersion - SecurityException) - " + ex.Message);
            }
            catch (UnauthorizedAccessException ex)
            {
                // The user does not have the necessary registry rights.
                LogMsg("Error: (GetInternetExplorerMajorVersion - UnauthorizedAccessException) - " + ex.Message);
            }
            catch (Exception ex)
            {
                LogMsg("Error: (GetInternetExplorerMajorVersion) - " + ex.Message);
            }

            return result;
        }

        private static object GetValueFromRegistry(RegistryHive hive,string subkey,string regValue)
        {
            
            //if running as 64-bit,get value from 64-bit registry
            //if running as 32-bit,get value from 32-bit registry
            RegistryView rView = RegistryView.Registry64;
            object data = null;

            if (!Environment.Is64BitProcess)
            {
                //running as 32-bit
                rView = RegistryView.Registry32;
            }

            using (RegistryKey regBaseKey = RegistryKey.OpenBaseKey(hive,rView))
            {
                using (RegistryKey sKey = regBaseKey.OpenSubKey(subkey))
                {
                    if (sKey != null)
                    {
                        data = sKey.GetValue(regValue,null);

                        if (data != null)
                        {
                            LogMsg("data: " + data.ToString());
                        }
                        else
                        {
                            LogMsg("data is null (" + data + ")");
                        }
                    }
                }
            }

            return data;
        }

        public static bool IsBrowserEmulationSet()
        {
            return GetBrowserEmulationVersion() != BrowserEmulationVersion.Default;
        }

        private static void LogMsg(string msg)
        {
            string logMsg = String.Format("{0} {1}",DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss:fff"),msg);
            System.Diagnostics.Debug.WriteLine(logMsg);
        }

        public static bool SetBrowserEmulationVersion()
        {
            BrowserEmulationVersion emulationCode;
            
            int ieVersion = GetInternetExplorerMajorVersion();

            if (ieVersion >= 11)
            {
                emulationCode = BrowserEmulationVersion.Version11;
            }
            else
            {
                switch (ieVersion)
                {
                    case 10:
                        emulationCode = BrowserEmulationVersion.Version10;
                        break;
                    case 9:
                        emulationCode = BrowserEmulationVersion.Version9;
                        break;
                    case 8:
                        emulationCode = BrowserEmulationVersion.Version8;
                        break;
                    default:
                        emulationCode = BrowserEmulationVersion.Version7;
                        break;
                }
            }

            return SetBrowserEmulationVersion(emulationCode);
        }

        public static bool SetBrowserEmulationVersion(BrowserEmulationVersion browserEmulationVersion)
        {
            bool result = false;

            //if running as 64-bit,get value from 32-bit registry
            RegistryView rView = RegistryView.Registry64;

            if (!Environment.Is64BitProcess)
            {
                //running as 32-bit
                rView = RegistryView.Registry32;
            }

            try
            {
                string programName = System.IO.Path.GetFileName(Environment.GetCommandLineArgs()[0]);

                using (RegistryKey regBaseKey = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser,rView))
                {
                    using (RegistryKey sKey = regBaseKey.OpenSubKey(@"Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION",true))
                    {
                        if (sKey != null)
                        {
                            if (browserEmulationVersion != BrowserEmulationVersion.Default)
                            {
                                // if it''s a valid value,update or create the value
                                sKey.SetValue(programName,(int)browserEmulationVersion,Microsoft.Win32.RegistryValueKind.DWord);
                            }
                            else
                            {
                                // otherwise,remove the existing value
                                sKey.DeleteValue(programName,false);
                            }

                            result = true;
                        }
                    }
                }
            }
            catch (System.Security.SecurityException ex)
            {
                // The user does not have the permissions required to read from the registry key.
                LogMsg("Error: (SetBrowserEmulationVersion - SecurityException) - " + ex.Message);
            }
            catch (UnauthorizedAccessException ex)
            {
                // The user does not have the necessary registry rights.
                LogMsg("Error: (SetBrowserEmulationVersion - UnauthorizedAccessException) - " + ex.Message);
            }
            catch (Exception ex)
            {
                LogMsg("Error: (SetBrowserEmulationVersion) - " + ex.Message);
            }

            return result;
        }
    }
}

在表单“加载”事件处理程序中添加以下内容:

HelperRegistry.SetBrowserEmulationVersion();

如果需要,可以将 HTML 嵌入到程序中。

打开解决方案资源管理器

  • 在 VS 菜单中,点击查看
  • 选择解决方案资源管理器

打开属性窗口

  • 在 VS 菜单中,点击查看
  • 选择属性窗口

创建 HTML 文件夹

  • 在解决方案资源管理器中,右键单击

  • 选择添加

  • 选择新建文件夹(重命名为所需名称;例如:HTML)

  • 右键单击您刚刚创建的文件夹(例如:HTML)并选择添加

  • 选择新建项目...

  • 选择HTML 页面(名称:HTMLPageSample.html)

  • 点击添加

注意:如果没有看到“HTML 页面”作为选项,则需要打开 Visual Studio 安装程序并添加包含 HTML 的工作负载。

设置 HTMLPageSample.html 的属性

  • 在解决方案资源管理器中,单击 HTMLPageSample.html
  • 在属性窗口中,设置Build Action = Embedded Resource

HTMLPageSample.html

<!DOCTYPE html>
<html>
    <head>
        <script type=''text/javascript'' src=''https://js.yoco.com/sdk/v1/yoco-sdk-web.js''></script>

        <script type="text/javascript">

            var sdk = new window.YocoSDK({
                publicKey: ''pk_test_blahblah''
            });
            var inline = sdk.inline({
                layout: ''field'',amountInCents: 2000,currency: ''ZAR''
            });

            inline.mount(''#card-frame'');
        </script>

        <script type="text/javascript">
            function ShowMessage() {

                try {
                    //alert(''in ShowMessage...'');

                    var form = document.getElementById(''payform'');
                    var submitButton = document.getElementById(''paybutton'');

                    form.addEventListener(''submit'',function (event) {
                        event.preventDefault()
                        submitButton.disabled = true;

                        inline.createToken().then(function (result) {

                            submitButton.disabled = false;

                            if (result.error) {
                                const errorMessage = result.error.message;
                                errorMessage && alert(''error occured: '' + errorMessage);
                            } else {
                                const token = result;
                                alert(''card successfully tokenised: '' + token.id);
                            }
                        }).catch(function (error) {
                            submitButton.disabled = false;
                            alert(''error occured: '' + error);
                        });
                    });
                }
                catch (err) {
                    alert(err.message);
                }
            };
        </script>
    </head>
    <body>
        <form id=''payform'' method=''POST''>
            <divone-liner''>
                <div id=''card-frame''>
                </div>
                <button id=''paybutton'' onclick=''ShowMessage()''>
                    PAY ZAR 2.00
                </button>
            </div>
            <psuccess-payment-message'' />
        </form>
    </body>
</html>

现在,我们需要一些代码来读取嵌入的 HTML 文件。我们将使用来自 here 的代码。

创建一个类(名称:HelperLoadResource.cs)

HelperLoadResource

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;

namespace WebBrowserTest
{
    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;
        }
    }
}

用法

string html = HelperLoadResource.ReadResource("HTMLPageSample.html");

接下来,我们将处理我们的表单(名称:Form1)。

  • 在解决方案资源管理器中,右键单击 Form1.cs
  • 选择视图设计器

打开工具箱

  • 在 VS 菜单中,点击查看
  • 选择工具箱

将 WebBrowser 添加到表单

  • 在工具箱中,点击 WebBrowser 并将其拖到表单顶部

向表单添加按钮

  • 在工具箱中,单击按钮并将其拖到表单顶部
  • 在属性窗口中,重命名按钮(名称:btnSubmit)

向表单添加加载事件处理程序

  • 在“属性”窗口中,单击 enter image description here
  • 双击加载,添加事件处理程序

每当在 WebBrowser 中加载页面时,无论是使用 Navigate 还是设置 DocumentText,重要的是要等到它完全加载。我们将为等待操作创建一个方法。我通常避免使用“DoEvents”,但这次我们会使用它。

private void WaitForBrowserToBeReady(int sleepTimeInMs = 125)
{
    do
    {
        System.Threading.Thread.Sleep(sleepTimeInMs);
        Application.DoEvents();
    } while (webBrowser1.ReadyState != WebBrowserReadyState.Complete);
}

现在在 Form1_Load 中,添加以下代码:

private void Form1_Load(object sender,EventArgs e)
{
    //set browser emulation in registry
    HelperRegistry.SetBrowserEmulationVersion();

    //suppress script errors
    webBrowser1.ScriptErrorsSuppressed = true;
    
    //string path = System.IO.Path.Combine(System.IO.Directory.GetCurrentDirectory(),@"..\..\");
    //load the html into the webbrowser document. only the paybutton displays,the referenced library in "src"
    //should call an online sdk that adds the payment fields to the form. these fields do not get added. so
    //it seems the src reference is not working,or the script and form definitions cannot "see" each other?
    //webBrowser1.Navigate(System.IO.Path.Combine(path,"HTMLPageSample.html"));

    string html = HelperLoadResource.ReadResource("HTMLPageSample.html");

    if (Environment.Is64BitProcess)
    {
        Debug.WriteLine("Running as 64-bit");
    }
    else
    {
        Debug.WriteLine("Running as 32-bit");
    }

    //initialize WebBrowser
    webBrowser1.Navigate("about:blank");
    WaitForBrowserToBeReady();

    //set HTML
    webBrowser1.DocumentText = html;
    WaitForBrowserToBeReady();

    //Debug.WriteLine(webBrowser1.DocumentText);
}

如 OP 中所述,当单击按钮时,需要调用 ShowMessage() javascript 函数。由于 JavaScript 函数的编写方式,我们将执行以下操作:

HtmlElementCollection col = webBrowser1.Document.GetElementsByTagName("button");
foreach (HtmlElement element in col)
{
    if (element.GetAttribute("id").Equals("paybutton"))
    {
        element.InvokeMember("click");   // Invoke the "Click" member of the button
    }
}

注意:虽然下面的代码也会调用 ShowMessage()

object result = webBrowser1.Document.InvokeScript("ShowMessage");

由于需要“点击”的 form.addEventListener(''submit''...,它不会给出预期的结果。

这是 Form1.cs 的完整代码。

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.Security.Permissions;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace WebBrowserTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender,EventArgs e)
        {
            //set browser emulation in registry
            HelperRegistry.SetBrowserEmulationVersion();

            //suppress script errors
            webBrowser1.ScriptErrorsSuppressed = true;
            
            //string path = System.IO.Path.Combine(System.IO.Directory.GetCurrentDirectory(),@"..\..\");
            //load the html into the webbrowser document. only the paybutton displays,the referenced library in "src"
            //should call an online sdk that adds the payment fields to the form. these fields do not get added. so
            //it seems the src reference is not working,or the script and form definitions cannot "see" each other?
            //webBrowser1.Navigate(System.IO.Path.Combine(path,"HTMLPageSample.html"));

            string html = HelperLoadResource.ReadResource("HTMLPageSample.html");

            if (Environment.Is64BitProcess)
            {
                Debug.WriteLine("Running as 64-bit");
            }
            else
            {
                Debug.WriteLine("Running as 32-bit");
            }

            //initialize WebBrowser
            webBrowser1.Navigate("about:blank");
            WaitForBrowserToBeReady();

            //set HTML
            webBrowser1.DocumentText = html;
            WaitForBrowserToBeReady();

            //Debug.WriteLine(webBrowser1.DocumentText);
        }

        private void LogMsg(string msg)
        {
            string logMsg = String.Format("{0} {1}",msg);
            System.Diagnostics.Debug.WriteLine(logMsg);
        }

        private void btnSubmit_Click(object sender,EventArgs e)
        {
            //object result = webBrowser1.Document.InvokeScript("ShowMessage",null);
            //object result = webBrowser1.Document.InvokeScript("ShowMessage");

            HtmlElementCollection col = webBrowser1.Document.GetElementsByTagName("button");
            foreach (HtmlElement element in col)
            {
                if (element.GetAttribute("id").Equals("paybutton"))
                {
                    element.InvokeMember("click");   // Invoke the "Click" member of the button
                }
            }
        }

        private void WaitForBrowserToBeReady(int sleepTimeInMs = 125)
        {
            do
            {
                System.Threading.Thread.Sleep(sleepTimeInMs);
                Application.DoEvents();
            } while (webBrowser1.ReadyState != WebBrowserReadyState.Complete);
        }

        private void webBrowser1_DocumentCompleted(object sender,WebBrowserDocumentCompletedEventArgs e)
        {
            
        }
    }
}

资源

  • How to Click A Button Programmatically - Button in WebBrowser (IE)
  • Calling JavaScript functions in the Web Browser Control
  • Execute a JS function in WebBrowser C#
  • Configuring the Emulation Mode of an Internet Explorer WebBrowser Control
  • How to read embedded resource text file
  • C# WebBrowser control: window.external access sub object
,

这是一个使用 WebView2 的版本。下面的分步说明显示了如何在 C# 中单击按钮时运行 JavaScript 函数。它使用了 OP 中 HTML 的修改版本。

VS 2019

创建一个新项目:Windows Forms App (.NET Framework)(名称:WebView2SM)

如果需要,可以将 HTML 嵌入到程序中。

打开解决方案资源管理器

  • 在 VS 菜单中,点击查看
  • 选择解决方案资源管理器

打开属性窗口

  • 在 VS 菜单中,点击查看
  • 选择属性窗口

创建 HTML 文件夹

  • 在解决方案资源管理器中,右键单击

  • 选择添加

  • 选择新建文件夹(重命名为所需名称;例如:HTML)

  • 右键单击您刚刚创建的文件夹(例如:HTML)并选择添加

  • 选择新建项目...

  • 选择HTML 页面(名称:HTMLPageSample.html)

  • 点击添加

注意:如果没有看到“HTML 页面”作为选项,则需要打开 Visual Studio 安装程序并添加包含 HTML 的工作负载。

设置 HTMLPageSample.html 的属性

  • 在解决方案资源管理器中,单击 HTMLPageSample.html
  • 在属性窗口中,设置Build Action = Embedded Resource

HTMLPageSample.html

<!DOCTYPE html>
<html>
    <head>
        <script type=''text/javascript'' src=''https://js.yoco.com/sdk/v1/yoco-sdk-web.js''></script>

        <script type="text/javascript">

            var sdk = new window.YocoSDK({
                publicKey: ''pk_test_blahblah''
            });
            var inline = sdk.inline({
                layout: ''field'',function (event) {
                        event.preventDefault()
                        submitButton.disabled = true;

                        inline.createToken().then(function (result) {

                            submitButton.disabled = false;

                            if (result.error) {
                                const errorMessage = result.error.message;
                                errorMessage && alert(''error occured: '' + errorMessage);
                            } else {
                                const token = result;
                                alert(''card successfully tokenised: '' + token.id);
                            }
                        }).catch(function (error) {
                            submitButton.disabled = false;
                            alert(''error occured: '' + error);
                        });
                    });
                }
                catch (err) {
                    alert(err.message);
                }
            };
        </script>
    </head>
    <body>
        <form id=''payform'' method=''POST''>
            <divone-liner''>
                <div id=''card-frame''>
                </div>
                <button id=''paybutton'' onclick=''ShowMessage()''>
                    PAY ZAR 2.00
                </button>
            </div>
            <psuccess-payment-message'' />
        </form>
    </body>
</html>

现在,我们需要一些代码来读取嵌入的 HTML 文件。我们将使用来自 here 的代码。

创建一个类(名称:HelperLoadResource.cs)

HelperLoadResource

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;

namespace WebView2SM
{
    public static class HelperLoadResource
    {
        public static string ReadResource(string filename)
        {
            //use UTF8 encoding as the default encoding
            return ReadResource(filename,fileEncoding))
                    {
                        //get text
                        result = reader.ReadToEnd();
                    }
                }
            }

            return result;
        }
    }
}

用法

string html = HelperLoadResource.ReadResource("HTMLPageSample.html");

更改/验证 NuGet 包管理器设置(.NET Framework 可选;.NET 需要)

  • 在 VS 菜单中,点击工具
  • 选择选项
  • 双击NuGet 包管理器
  • 在“包管理”下,设置默认包管理格式:PackageReference
  • 点击确定

有关详细信息,请参阅以下内容:

  • Package references (PackageReference) in project files
  • Migrate from packages.config to PackageReference

添加 WebView2 NuGet 包

  • 在解决方案资源管理器中,右键单击(例如:WebView2SM)
  • 选择管理 NuGet 包...
  • 点击浏览
  • 可选:选中搜索框旁边的包括预发行框
  • 在搜索框中,输入:Microsoft.Web.WebView2
  • 选择想要的版本
  • 点击安装
  • 如果您看到一个弹出窗口,请点击确定

注意:要将 WebView2 添加到项目而不是解决方案,请右键单击 而不是 。

接下来,我们将处理我们的表单(名称:Form1)。

  • 在解决方案资源管理器中,右键单击 Form1.cs
  • 选择视图设计器

打开工具箱

  • 在 VS 菜单中,点击查看
  • 选择工具箱

将 WebView2 添加到表单

  • 在工具箱中,点击WebView2 Windows Control Form将其展开
  • 点击 WebView2 并将其拖到表单顶部
  • 根据需要调整 WebView2 控件的大小

向表单添加按钮

  • 在工具箱中,单击按钮并将其拖到表单顶部
  • 在属性窗口中,重命名按钮(名称:btnSubmit)
  • 在“属性”窗口中,单击 enter image description here
  • 双击单击,添加事件处理程序

向表单添加加载事件处理程序

  • 在“属性”窗口中,单击 enter image description here
  • 双击加载,添加事件处理程序

添加 CoreWebView2InitializationCompleted 事件处理程序

  • 在解决方案资源管理器中,右键单击 Form1.cs
  • 选择视图设计器
  • 在属性窗口中,点击 enter image description here
  • 点击下拉菜单并选择 WebView2 控件(例如:webView21)
  • 双击CoreWebView2InitializationCompleted
  • 可选:双击NavigationCompleted(对任何其他所需的事件处理程序重复此操作)

现在,我们将处理表单的代码。

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

为了测试,我们将添加一个名为 LogMsg 的方法。

private void LogMsg(string msg)
{
    string logMsg = String.Format("{0} {1}",msg);
    System.Diagnostics.Debug.WriteLine(logMsg);
}

可以根据需要修改此方法。如果需要,可以将信息写入日志文件。如果您已经有一种记录方法,则可以改用它。我已经包含了这个,因为它在代码中使用。

为了为将要创建的 Web 缓存设置所需的位置,我们将显式初始化 WebView2。我们将其称为 InitializeCoreWebView2Async。我们还将创建一个可用于使用 AddScriptToExecuteOnDocumentCreatedAsync 添加代码的方法。

注意:使用async时必须使用await。请注意使用 Task 而不是 void。如果使用 void,将继续执行而无需等待。

AddScriptToExecuteOnDocumentCreatedAsync

private async Task AddExecuteOnDocumentCreatedAsyncCode()
{
    if (webView21 != null && webView21.CoreWebView2 != null)
    {
        string jsCode = string.Empty;

        //ToDo: add desired code using ''AddScriptToExecuteOnDocumentCreatedAsync''

        if (!String.IsNullOrEmpty(jsCode))
        {
            await webView21.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(jsCode);
        }
    }
}

InitializeCoreWebView2Async

public async Task InitializeCoreWebView2Async(WebView2 wv,string webCacheDir = "")
{
    CoreWebView2EnvironmentOptions options = null;
    string tempWebCacheDir = string.Empty;
    CoreWebView2Environment webView2Environment = null;

    //set value
    tempWebCacheDir = webCacheDir;

    if (String.IsNullOrEmpty(tempWebCacheDir))
    {
        //use temp folder
        //get fully-qualified path to user''s temp folder
        tempWebCacheDir = System.IO.Path.GetTempPath();

        //create a randomly named folder - this will create a new web cache folder each time
        //creating a new web cache folder takes time. By re-using an existing web cache,//the load time will be shorter. However,one may need to manage (clean-up) 
        //objects in the web cache that are no longer needed
        //tempWebCacheDir = System.IO.Path.Combine(tempWebCacheDir,System.Guid.NewGuid().ToString("N"));
    }

    //webView2Environment = await CoreWebView2Environment.CreateAsync(@"C:\Program Files (x86)\Microsoft\Edge Dev\Application\1.0.902.49",tempWebCacheDir,options);
    webView2Environment = await CoreWebView2Environment.CreateAsync(null,options);

    //wait for CoreWebView2 initialization
    await wv.EnsureCoreWebView2Async(webView2Environment);

    //add desired code using AddScriptToExecuteOnDocumentCreatedAsync
    await AddExecuteOnDocumentCreatedAsyncCode();

    LogMsg("Info: Cache data folder set to: " + tempWebCacheDir);
}

用法

await InitializeCoreWebView2Async(webView21);

现在在 Form1_Load 中,添加以下代码:

private async void Form1_Load(object sender,EventArgs e)
{
    //initialize
    await InitializeCoreWebView2Async(webView21);

    string html = HelperLoadResource.ReadResource("HTMLPageSample.html");
    webView21.NavigateToString(html);
}

WebView2 初始化完成后,我们将为 CoreWebView2 添加任何所需的事件处理程序。我们将在 CoreWebView2InitializationCompleted 中添加它们。

private void webView21_CoreWebView2InitializationCompleted(object sender,Microsoft.Web.WebView2.Core.CoreWebView2InitializationCompletedEventArgs e)
{
    //subscribe to events (add event handlers)
    webView21.CoreWebView2.DOMContentLoaded += CoreWebView2_DOMContentLoaded;
}

注意:不要在事件处理程序中放置任何可能导致“阻塞”的代码。

如 OP 中所述,当单击按钮时,需要调用 ShowMessage() javascript 函数。由于 JavaScript 函数的编写方式,我们将执行以下操作:

var result = await webView21.CoreWebView2.ExecuteScriptAsync("document.getElementById(''paybutton'').click();");

注意:虽然下面的代码也会调用 ShowMessage()

var result = await webView21.CoreWebView2.ExecuteScriptAsync("ShowMessage();");

由于需要“点击”的 form.addEventListener(''submit''...,它不会给出预期的结果。

这是 Form1.cs 的完整代码。

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;

namespace WebView2SM
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private async void Form1_Load(object sender,EventArgs e)
        {
            //initialize
            await InitializeCoreWebView2Async(webView21);

            string html = HelperLoadResource.ReadResource("HTMLPageSample.html");
            webView21.NavigateToString(html);
        }

        private async Task AddExecuteOnDocumentCreatedAsyncCode()
        {
            if (webView21 != null && webView21.CoreWebView2 != null)
            {
                string jsCode = string.Empty;

                //ToDo: add desired code using ''AddScriptToExecuteOnDocumentCreatedAsync''

                if (!String.IsNullOrEmpty(jsCode))
                {
                    await webView21.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(jsCode);
                }
            }
        }

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

            //add desired code using AddScriptToExecuteOnDocumentCreatedAsync
            await AddExecuteOnDocumentCreatedAsyncCode();
        }

        public async Task InitializeCoreWebView2Async(WebView2 wv,string webCacheDir = "")
        {
            CoreWebView2EnvironmentOptions options = null;
            string tempWebCacheDir = string.Empty;
            CoreWebView2Environment webView2Environment = null;

            //set value
            tempWebCacheDir = webCacheDir;

            if (String.IsNullOrEmpty(tempWebCacheDir))
            {
                //use temp folder
                //get fully-qualified path to user''s temp folder
                tempWebCacheDir = System.IO.Path.GetTempPath();

                //create a randomly named folder - this will create a new web cache folder each time
                //creating a new web cache folder takes time. By re-using an existing web cache,one may need to manage (clean-up) 
                //objects in the web cache that are no longer needed
                //tempWebCacheDir = System.IO.Path.Combine(tempWebCacheDir,System.Guid.NewGuid().ToString("N"));
            }

            //webView2Environment = await CoreWebView2Environment.CreateAsync(@"C:\Program Files (x86)\Microsoft\Edge Dev\Application\1.0.902.49",options);
            webView2Environment = await CoreWebView2Environment.CreateAsync(null,options);

            //wait for CoreWebView2 initialization
            await wv.EnsureCoreWebView2Async(webView2Environment);

            //add desired code using AddScriptToExecuteOnDocumentCreatedAsync
            await AddExecuteOnDocumentCreatedAsyncCode();

            LogMsg("Info: Cache data folder set to: " + tempWebCacheDir);
        }

        private void LogMsg(string msg)
        {
            string logMsg = String.Format("{0} {1}",msg);
            System.Diagnostics.Debug.WriteLine(logMsg);
        }

        private void webView21_CoreWebView2InitializationCompleted(object sender,Microsoft.Web.WebView2.Core.CoreWebView2InitializationCompletedEventArgs e)
        {
            //subscribe to events (add event handlers)
            webView21.CoreWebView2.DOMContentLoaded += CoreWebView2_DOMContentLoaded;
        }

        private void CoreWebView2_DOMContentLoaded(object sender,Microsoft.Web.WebView2.Core.CoreWebView2DOMContentLoadedEventArgs e)
        {
           
        }

        private void webView21_NavigationCompleted(object sender,Microsoft.Web.WebView2.Core.CoreWebView2NavigationCompletedEventArgs e)
        {

        }

        private async void btnSubmit_Click(object sender,EventArgs e)
        {
            
            //var result = await webView21.CoreWebView2.ExecuteScriptAsync("ShowMessage();");
            var result = await webView21.CoreWebView2.ExecuteScriptAsync("document.getElementById(''paybutton'').click();");
        }
    }
}

资源

  • Introduction to Microsoft Edge WebView2
  • Release notes for WebView2 SDK
  • Understand WebView2 SDK versions
  • Report An Issue With WebView2
  • Distribution of apps using WebView2
  • Get started with WebView2 in Windows Forms
  • Download the WebView2 Runtime
  • What is .NET Framework?
  • Introduction to .NET
  • .NET Core/5+ vs. .NET Framework for server apps

.net – 没有WebBrowser控件的Windows.Forms中的主机Silverlight

.net – 没有WebBrowser控件的Windows.Forms中的主机Silverlight

是否可以在没有Webbrowser控件的情况下在 Windows.Forms中托管Silverlight,以避免不必要的COM编组?

编辑:目标是在Windows 2000等旧平台上使用WPF或Silverlight等丰富的图形内容.

下面列出了在Windows应用程序等主机上托管Silverlight的所有可用选项:

Msdn Documentation

Rahul Gangwar技术顾问微软

.NET中WebBrowser控件调用HTML页面中Frame内部的JavaScript代码

.NET中WebBrowser控件调用HTML页面中Frame内部的JavaScript代码

我的操作系统版本为Win7,VS版本为VS2012。

之前的一篇博文中提到使用.NET中的WebBrowser控件,调用加载的HTML页面中的JS函数,博文地址在:

http://my.oschina.net/Tsybius2014/blog/643909

不过,最近又遇到了一个棘手的问题,就是如果JS代码在Frame内的HTML页面中,上述博文中调用JS的方法就不灵了。

因此,我今天琢磨了一个新的办法,调用这些JS代码,先贴一组HTML页面的代码:

1、test_page.html

<html>
  <head>
    <title>Frame测试页面</title>
  </head>
  <script>
    // TODO - 这里输入JS代码
  </script>
  <frameset cols="40%,60%" rows="2*,*">
    <frame name="top_left" src="top_left.html">
    <frame name="top_right" src="top_right.html">
    <frame name="bottom_left" src="bottom_left.html">
    <frame name="bottom_right" src="bottom_right.html">
  </frameset>
</html>

2、其下有四个Frame,分居页面的左上、右上、左下、右下四端,以top_left.html为例,代码为:

<html>
  <head>
    <title>测试子页面</title>
  </head>
  <body>
    <div id="bulletin">你好</div>
    <script>
      // TODO - 这里输入JS代码
    </script>
  </body>
</html>

我的Winform工程是用C#语言建立的,窗体结构如下:


代码结构如下:

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;

namespace WebBrowserFrameTest
{
    [System.Runtime.InteropServices.ComVisible(true)]
    public partial class FormMain : Form
    {
        public FormMain()
        {
            InitializeComponent();
        }

        private void FormMain_Load(object sender, EventArgs e)
        {
            try
            {
                string path = @"C:\Users\Tsybius\Desktop\测试页面\test_page.html";
                webBrowser.Navigate(path);
                webBrowser.ObjectForScripting = this;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
    }
}

我想到了三个方法调用Frame内部的JS函数,现在对它们进行逐一说明:

方法1:给定Frame的name和函数名,调用指定Frame中页面内指定名称的JS函数

C#程序为按钮btnTopLeft1定义单击事件代码:

private void btnTopLeft1_Click(object sender, EventArgs e)
{
    webBrowser.Document.InvokeScript("changeBulletin", new object[] { "top_left" });
}

在test_page.html的script标签下写入如下代码:

function changeBulletin(frameName) {
  window.frames[frameName].changeBulletin();
}

在top_left.html的script标签下写入如下代码:

function changeBulletin() {
  document.getElementById("bulletin").innerHTML = "TOP_LEFT";
}

此时单击按钮btnTopLeft1,就可以看到效果了(文字有变化)。

方法2:以参数的形式给定Frame的name和函数名,调用指定Frame中页面内指定名称的JS函数

方法1的问题很明显,方法1中,主页面的changeBulletin函数是写死的。在实际程序编写中,如果每个JS函数调用,我们都要在父页面实现一个同名的函数,那真是要累死人了。

优化的办法是,为C#程序为按钮btnTopLeft2定义单击事件代码:

private void btnTopLeft2_Click(object sender, EventArgs e)
{
    webBrowser.Document.InvokeScript("runJsInFrame", new object[] { "top_left", "changeBulletin" });
}

在test_page.html的script标签下写入如下代码:

function runJsInFrame(frameName, funcName) {
  window.frames[frameName][funcName]();
}

这样做达到的效果和方法1是一样的,不过好处是只定义一个函数就好了。

方法3:除以参数形式给定Frame的name和函数名外,还要支持调用函数的参数和返回值

方法2的缺点是,虽然实现了传入Frame的name和函数名灵活调用JS函数,但不能为JS函数添加参数并接收返回值。不能实现这一点,那这个方法就是个残缺的方法,因此我又想了方法3去修复这一问题。

为C#程序为按钮btnTopLeft3定义单击事件代码:

private void btnTopLeft3_Click(object sender, EventArgs e)
{
    object obj = webBrowser.Document.InvokeScript("runJsInFrame2", new object[] { "top_left", "addParams", "1", "2", "3" });
    if (obj != null)
    {
        MessageBox.Show(obj.ToString());
    }
    else
    {
        MessageBox.Show("null");
    }
}

在test_page.html的script标签下写入如下代码:

function runJsInFrame2(frameName, funcName) {
  var args = "";
  if (arguments.length > 2) {
    for (var i = 2; i < arguments.length; i++) {
      args += "\"" + arguments[i] + "\"";
      if (i < arguments.length - 1) {
        args += ",";
      }
    }
  }
  var command = "window.frames[\"" + frameName + "\"][\"" + funcName + "\"](" + args + ")";
  var result = eval(command);
  return result;
}

在top_left.html的script标签下写入如下代码:

function addParams() {
  var sum = 0;
  for (var i = 0; i < arguments.length; i++) {
    sum += parseInt(arguments[i]);
  }
  return sum;
}

这里调用了top_left.html中的addParams函数,将所有的输入参数做加法运算,并返回加法运算的和。

这里使用到了JS的可变参数,runJsInFrame2函数中,传入的第一个参数是Frame的name,传入的第二个参数是函数名,后面任意多个参数可根据实际使用自行添加。

这段代码的运行结果就是,返回一个6(1+2+3=6)。

END

C# Winform中WebBrowser给网页中的input控件赋值/设置值

C# Winform中WebBrowser给网页中的input控件赋值/设置值

订阅WebBrowser的DocumentCompleted事件,在里面写入

private void browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {            
            browser.Document.GetElementById("loginId").SetAttribute("value", "18271500040");
            browser.Document.GetElementById("passwd").SetAttribute("value", "da2qia1ku5");
        }

其中loginId和passwd分别是用户名对应DomId、密码对应的DomId

 

 程序运行后效果

 

C# winform嵌入HTML执行Javascript报错

C# winform嵌入HTML执行Javascript报错

System.Exception: ''Unable to execute javascript at this time, scripts can only be executed within a V8Context

关于html 中的 Javascript 脚本未从 winform webBrowser 控件触发活动脚本javascript未开启的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于.net – 没有WebBrowser控件的Windows.Forms中的主机Silverlight、.NET中WebBrowser控件调用HTML页面中Frame内部的JavaScript代码、C# Winform中WebBrowser给网页中的input控件赋值/设置值、C# winform嵌入HTML执行Javascript报错等相关知识的信息别忘了在本站进行查找喔。

本文标签: