我有如下代码,
public partial class LawView : UserControl
{
public LawView()
{
InitializeComponent();
InitializeAsync();
}
async void InitializeAsync()
{
await webView.EnsureCoreWebView2Async(null);
webView.Source = new System.Uri("https://klimedsoft.pl/strefa-klienta/");
webView.Focus();
await webView.CoreWebView2.ExecuteScriptAsync("(function() { document.getElementById('user').value = 'blahblahusername'; document.getElementById('password').value = 'blahpassword'; })()");
await webView.CoreWebView2.ExecuteScriptAsync("(function() { document.getElementsByName('wp-submit')[0].click(); })()");
}
}
在控制台中,脚本运行时没有任何问题,但是当我在应用程序中运行它们时,打开页面中的字段不会填充我。我做错了什么?有什么东西不见了吗?
我已经搜索过堆栈溢出和其他网站了。我什么也没找到解决办法。我将非常感谢您的帮助。
发布于 2022-06-20 02:40:23
设置Source
属性后,需要等待页面实际加载。为此,您可以使用NavigationCompleted事件或DOMContentLoaded。注意,NavigationCompleted
是为成功和不成功的导航而调用的。
extension
方法包装NavigationCompleted
事件。该方法使用Navigate
方法,而不是设置Source
属性。// Create a static class and add the following extension method
// Add using System.Threading.Tasks;
public static Task NavigateToAsync(this CoreWebView2 coreWebView2, string url)
{
var tcs = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
EventHandler<CoreWebView2NavigationCompletedEventArgs> evt = null;
evt = async (s, args) =>
{
coreWebView2.NavigationCompleted -= evt;
if (args.IsSuccess)
{
tcs.TrySetResult(true);
}
else
{
tcs.TrySetException(new Exception("Nav Failed With Error:" + args.WebErrorStatus.ToString()));
}
};
coreWebView2.NavigationCompleted += evt;
coreWebView2.Navigate(url);
return tcs.Task;
}
// Use extension method in your code.
async void InitializeAsync()
{
await webView.EnsureCoreWebView2Async(null);
try
{
await webView.CoreWebView2.NavigateToAsync("https://klimedsoft.pl/strefa-klienta/");
webView.Focus();
// now execute your javascript
await webView.CoreWebView2.ExecuteScriptAsync("(function() { document.getElementById('user').value = 'blahblahusername'; document.getElementById('password').value = 'blahpassword'; })()");
await webView.CoreWebView2.ExecuteScriptAsync("(function() { document.getElementsByName('wp-submit')[0].click(); })()");
}
catch (Exception ex)
{
//TODO: Handle error
}
}
async void InitializeAsync()
{
await webView.EnsureCoreWebView2Async(null);
webView.CoreWebView2.DOMContentLoaded += OnWebViewDOMContentLoaded;
webView.Source = new System.Uri("https://klimedsoft.pl/strefa-klienta/");
}
private async void OnWebViewDOMContentLoaded(object sender, CoreWebView2DOMContentLoadedEventArgs arg)
{
webView.CoreWebView2.DOMContentLoaded -= OnWebViewDOMContentLoaded;
webView.Focus();
// now execute your javascript
await webView.CoreWebView2.ExecuteScriptAsync("(function() { document.getElementById('user').value = 'blahblahusername'; document.getElementById('password').value = 'blahpassword'; })()");
await webView.CoreWebView2.ExecuteScriptAsync("(function() { document.getElementsByName('wp-submit')[0].click(); })()");
}
发布于 2022-06-19 15:10:36
您没有指示web视图是否导航到该页。
尝试在核心查看器上使用Navigate(string url)
。主要问题通常是,我们需要等待页面加载完成,然后它才能准备好执行脚本。当您在web控制台中运行此操作时,只有在页面加载之后才会这样做。
这是来自@amaitland的回复通常是将基于事件的API (EAP)转换为基于任务的API (TAP)的公认解决方案。这种模式通常被称为TAP包装器或TAP扩展。在这里可以找到更多有关这方面的信息:
我前面的解决方案(我将在下面留下)是一个快速而肮脏的等待循环,但是我们应该使用SemiphoreSlim
而不是线程阻塞逻辑来实现相同的目标。您可以在这里找到更多信息:
这是一个使用SemaphoreSlim
的解决方案
private SemaphoreSlim _waitForWebViewToLoad;
async void InitializeAsync()
{
await webView.EnsureCoreWebView2Async(null);
_waitForWebViewToLoad = new SemaphoreSlim(0,1);
webView.CoreWebView2.NavigationCompleted += CoreWebView2_NavigationCompleted;
webView.CoreWebView2.Navigate("https://klimedsoft.pl/strefa-klienta/");
webView.Focus();
await _waitForWebViewToLoad.WaitAsync();
// now execute your javascripts
await webView.CoreWebView2.ExecuteScriptAsync("(function() { document.getElementById('user').value = 'blahblahusername'; document.getElementById('password').value = 'blahpassword'; })()");
await webView.CoreWebView2.ExecuteScriptAsync("(function() { document.getElementsByName('wp-submit')[0].click(); })()");
}
private void CoreWebView2_NavigationCompleted(object sender, Microsoft.Web.WebView2.Core.CoreWebView2NavigationCompletedEventArgs e)
{
webView.CoreWebView2.NavigationCompleted -= CoreWebView2_NavigationCompleted;
_waitForWebViewToLoad.Release();
}
下面是一种类似的方法,它使用一个简单的布尔标志来指示事件何时触发,这里的不同之处在于它使用了一个无限循环,该循环阻塞并等待100毫秒。如果您发现自己使用了这种类型的代码,那么SemaphoreSlim
是专门为解决这个问题而设计的,而不阻塞当前线程:
async void InitializeAsync()
{
await webView.EnsureCoreWebView2Async(null);
webView.CoreWebView2.NavigationCompleted += CoreWebView2_NavigationCompleted;
navComplete = false;
webView.CoreWebView2.Navigate("https://klimedsoft.pl/strefa-klienta/");
webView.Focus();
while(!navComplete)
{
await Task.Delay(100);
}
// now execute your javascripts
await webView.CoreWebView2.ExecuteScriptAsync("(function() { document.getElementById('user').value = 'blahblahusername'; document.getElementById('password').value = 'blahpassword'; })()");
await webView.CoreWebView2.ExecuteScriptAsync("(function() { document.getElementsByName('wp-submit')[0].click(); })()");
}
bool navComplete = false;
private void CoreWebView2_NavigationCompleted(object sender, Microsoft.Web.WebView2.Core.CoreWebView2NavigationCompletedEventArgs e)
{
webView.CoreWebView2.NavigationCompleted -= CoreWebView2_NavigationCompleted;
navComplete = true;
}
https://stackoverflow.com/questions/72677869
复制相似问题