我有一个 winforms 应用程序,它有一个 ChromiumWebBrowser 控件和一些基本的 Windows 控件。我希望能够单击一个按钮,调用 javascript 以获取浏览器中文本框的值,并将返回的值复制到 winforms 应用程序中的文本框。这是我的代码:
string script = "(function() {return document.getElementById('Email');})();";
string returnValue = "";
var task = browser.EvaluateScriptAsync(script, new { });
await task.ContinueWith(t =>
{
if (!t.IsFaulted)
{
var response = t.Result;
if (response.Success && response.Result != null)
{
returnValue = (string)response.Result;
}
}
});
txtTarget.Text = returnValue;
Run Code Online (Sandbox Code Playgroud)
然而,返回的结果只是“{}”。我已经在 Chrome 中加载了相同的网页并在开发工具中执行了相同的 javascript,我得到了预期的文本框值。
我查看的演示有示例代码,只是“返回 1+1;”,当我尝试返回值“2”而不是“{}”时。有趣的是,当我尝试
string script = "(function() {return 'hello';})()";
Run Code Online (Sandbox Code Playgroud)
我仍然收到“{}”,几乎好像这不适用于字符串。
我一直在挠头一段时间,一直无法弄清楚如何解决这个问题。我是在犯一个非常基本的语法错误还是有更复杂的事情发生?
我最近将 nuget 中的 cefsharp 添加到 Visual Studio 中的一个项目中。它可以用于浏览和所有操作,但我需要我的用户能够通过右键单击它并单击复制快捷方式从浏览器复制他的电子邮件地址。
但 cefsharp 仅显示 4 个选项 - 后退、前进、打印、查看源代码。没有复制快捷方式选项。
我没有使用任何设置初始化浏览器。刚刚创建了一个 chromiumbrowser 项目并将其添加到表单上的控件中。
任何人都知道为什么会发生这种情况?我还尝试添加一个菜单项,但无法做到这一点,因为我不断收到错误 - “您必须使用新关键字”。此外,浏览器中没有我可以通过代码调用的复制快捷方式方法。
有人可以帮助我并解释如何实现这一目标吗?如何为右键单击添加更多选项以及如何右键单击并复制链接地址。或者推荐我一些其他的浏览器组件?我尝试过 awesomium,但有一半的网站无法加载。
如何在 Windows 窗体应用程序中从 JAVASCRIPT 调用 C# 函数(在 HTML 代码中,我通过 CefSharp 调用)
CefSharp 组件
public partial class Form1 : Form
{
public ChromiumWebBrowser chromeBrowser;
public Form1()
{
InitializeComponent();
// Start the browser after initialize global component
InitializeChromium();
}
public void InitializeChromium()
{
CefSettings settings = new CefSettings();
settings.CefCommandLineArgs.Add("enable-media-stream", "1");
Cef.Initialize(settings);
chromeBrowser = new ChromiumWebBrowser("localhost/myproject/index.html");
this.Controls.Add(chromeBrowser);
chromeBrowser.Dock = DockStyle.Fill;
}
}
Run Code Online (Sandbox Code Playgroud)
JS调用的函数
public void Test(String message)
{
MessageBox.Show(message, "Test");
}
Run Code Online (Sandbox Code Playgroud)
HTML 代码 我需要在 onclick 事件中调用 Test()
<span class="mySpan" onclick="<Some>.Test('It is working');"></span>
Run Code Online (Sandbox Code Playgroud)
我尝试过的代码, …
我正在尝试使用 CefSharp 动态更改用户代理。我查看了 IRequestHandler 类,但不再看到名为 OnBeforeResourceLoad 的方法。
但是,我确实找到了一个名为 OnBeforeBrowse 的方法。但是,所有请求标头都是空的,当我尝试添加一个时,它根本没有添加。我试图参考,更改值并重新分配,但没有骰子。
我在 IRequestHandler 中找到了一个叫做 OnBeforeBrowse 的方法。但是,所有请求标头都是空的,当我尝试通过 IRequest 参数添加一个时,它根本没有添加。我试图参考,更改值并重新分配,但没有骰子。总是空着没有钥匙回来。
protected override bool OnBeforeBrowse(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, bool userGesture, bool isRedirect)
{
var headers = request.Headers;
headers["User-Agent"] = "New user agent";
request.Headers = headers;
return false;
}
Run Code Online (Sandbox Code Playgroud)
我希望用户代理更改为我给它的值。
如何在带有 CefSharp 浏览器控制器的 WinForms 下运行的 Html 文档中的按钮上拦截 js onClick,以便 C# 代码可以拦截此事件并在 .NET 环境中执行一些操作?
所以我的最终目标是检测用户何时在网页上按下鼠标左键(任何元素,如按钮、图像等)。有了这个,我将运行一些 javascript 来根据用户点击的位置获取我需要的正确的 html 数据。
不用再进一步,我已经陷入了第一部分,我的浏览器控件似乎没有触发任何与鼠标相关的事件。然而,它似乎确实提供了像 MouseDown、MouseEnter、MouseClick 等处理程序,但似乎没有触发它们中的任何一个。
我尝试使用文本框控件和按钮设置一个简单的 WinForms 测试项目。浏览器是手动添加的,如下所示:
using CefSharp;
using CefSharp.WinForms;
using System;
using System.Drawing;
using System.Windows.Forms;
namespace myProject
{
public partial class Form1 : Form
{
public ChromiumWebBrowser browser;
private string myUrl = "https://www.google.com/";
public Form1()
{
InitializeComponent();
InitializeChromium();
browser.MouseDown += ChromeBrowser_MouseDown;
}
public void InitializeChromium()
{
browser = new ChromiumWebBrowser(myUrl);
browser.Location = new Point(26, 59);
browser.Size = new Size(988,566);
browser.Dock = DockStyle.None;
this.Controls.Add(browser);
}
private void ChromeBrowser_MouseDown(object sender, MouseEventArgs e)
{
//This handler never …Run Code Online (Sandbox Code Playgroud) 它似乎是包中的错误(v49.0.1).要重现 - 创建新的WPF项目,将其体系结构设置为x86或x64,添加CefSharp.Wpf NuGet包.重启VS,编译.将ChromiumBrowser添加到MainWinoow.xaml,并将Address属性设置为任何URL,例如" http://stackoverflow.com ".运行应用程序
我看到的是浏览器每秒重绘一次,完全无法使用.WinForms版本工作正常.由于我的整个大项目取决于CEF - 任何线索该做什么?什么可以导致控制像疯了一样重绘?
更新:
我找到了触发它的东西:任何DOM变化.静态页面正确显示.我还发现v47.0.4适用于WPF和动态内容.我宁愿避免使用它,因为版本49.0.0中引入了API的重大变化.
它似乎是一个bug,实际上它知道GitHub上发布的问题是#1666:https: //github.com/cefsharp/CefSharp/issues/1666
它也出现在v49.0.0的发行说明中 https://github.com/cefsharp/CefSharp/releases/tag/v49.0.0
看到我找到的workaroud的答案.
我正在使用优秀的CefSharp项目(版本 67)在我们的 WPF 应用程序中托管浏览器。
使用 CefSharp 会导致CefSharp.BrowserSubprocess启动子进程,这是设计使然。
如果我干净地退出我的应用程序并Cef.Shutdown()按照文档中的建议调用,这些进程将停止:
// Hook up handler earlier in application
Application.Current.Exit += OnApplicationExit;
...
private void OnApplicationExit(object sender, ExitEventArgs e)
{
if (Dispatcher.CheckAccess() == false)
{
Dispatcher.Invoke(() => OnApplicationExit(sender, e));
return;
}
// Stops CefSharp.BrowserSubprocess processes
Cef.Shutdown();
}
Run Code Online (Sandbox Code Playgroud)
我注意到,如果应用程序被终止,CefSharp.BrowserSubprocess负责渲染的将继续运行并开始使用大量CPU,并且会无限期地这样做。
我可以添加一些代码来处理这个问题,检查任何孤立的CefSharp.BrowserSubprocess进程,然后杀死它们。我想知道是否有更好的选择?
如果进程本身可以执行周期检查并自行终止,这可能是一种设置,那就太好了。
我想做的是以下几点:
我有一个CefSharp ChromiumWebBrowser(WPF控件),我想在该浏览器中截取网页的屏幕截图。屏幕ChromiumWebBrowser上没有获取屏幕截图的方法。但是我可以通过将事件处理程序附加到OnPaint浏览器的事件来获取渲染。这样,我得到的位图就是屏幕截图。该过程基于以下答案:https : //stackoverflow.com/a/54236602/2190492
现在,我正在创建一个类CefSharpScreenshotRecorder,该类负责拍摄屏幕截图。它应该接受浏览器实例,将事件处理程序附加到OnPaint事件,并获取位图。该过程的所有状态都应封装在CefSharpScreenshotRecorder该类中。我希望能够异步使用我的课程。因为我们必须等到OnPaint事件被触发。触发该事件(并调用事件处理程序)后,该事件处理程序中将提供一个位图。然后,该位图应该是最初调用的异步方法的结果(如CefSharpScreenshotRecorder.TakeScreenshot(...cefBrowserInstance...)。当然,所有事情都必须在不阻塞/滞后UI的情况下发生。
我对C#中的异步编程不是很熟悉。我遇到的问题是,我找不到找到一种可以等待的方法的方法,该方法仅在被调用时代表OnPaint事件处理程序返回。我什至不知道是否存在任何代码功能来创建此逻辑。
Visual Studio 2017、Windows 10、.NET Framework 4.8、CefSharp WinForms 83.4.20、平台目标 x64
创建了新的非常简单的 CefSharp Windows 窗体应用程序。我无法获取网页的 html 源代码。我想我已经查看了 StackOverflow 上的每个 CefSharp 和异步同步问题 - 尝试了很多解决方案 - 我的头已经变得糊涂了。这是我看到的第一个问题 - 我也有同样的问题。
'浏览器.ViewSource();' 确实会弹出一个记事本,其中包含网页的源代码。但是当我尝试使用源代码获取字符串时 - 任务似乎永远不会运行。运行以获取网页源的任务显示 ---> Status = WaitingForActivation ---> 并且永远不会返回源。
我尝试过异步到同步的转换 - 可能有十种不同的方式。没有工作。一个 StackOverflow 解决方案建议使用 Application.DoEvents() - 所以我什至尝试过。
希望有人有一些想法。这个浏览器似乎有很大的潜力 - 但我需要获取网页源 html。
using System;
using System.Threading.Tasks;
using System.Windows.Forms;
using CefSharp;
using CefSharp.WinForms;
using System.Diagnostics;
namespace Test1
{
public partial class Form1 : Form
{
public ChromiumWebBrowser browser;
public Form1() …Run Code Online (Sandbox Code Playgroud) 我有一个方法可以进行 Chromium 浏览器初始化。运行两个异步方法后,程序自动关闭。难道是我用Task.WhenAll错了?
这是程序的入口点:
开始.cs
static class Start
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Initializer.Start();
}
}
Run Code Online (Sandbox Code Playgroud)
初始化程序.cs
public static class Initializer
{
public static async void Start()
{
// The task that automatically close the program.
Task<bool> chromiumInitTask = ChromiumInfo.InitializeAsync();
await chromiumInitTask;
Task webviewInitTask = WebViewInfo.InitializeAsync();
Task guiInitTask = GUIInfo.InitializeAsync();
HardwareManager.Initialize();
await webviewInitTask;
await guiInitTask;
GUIInfo.Layout.ChangeMainDisplay(ChromiumInfo.Browser);
Application.Run(GUIInfo.Layout.GetLayoutForm());
}
}
Run Code Online (Sandbox Code Playgroud)
ChromiumInfo.cs
public static class …Run Code Online (Sandbox Code Playgroud) cefsharp ×11
c# ×10
async-await ×3
winforms ×3
javascript ×2
wpf ×2
asynchronous ×1
events ×1
handler ×1
mousedown ×1
screenshot ×1
vb.net ×1
web ×1