PowerShell结合WebView2执行脚本及获取页面源码问题求助
PowerShell WebView2:获取页面源码与执行脚本的正确方案
核心问题分析
直接调用ExecuteScriptAsync导致UI锁定崩溃,本质是PowerShell中未正确处理异步操作的UI线程上下文,异步任务阻塞了WinForms的主消息循环;你用VB类的方式属于临时 workaround,并非规范实现。
1. 如何获取页面源码?
通过WebView2的CoreWebView2.ExecuteScriptAsync执行获取页面源码的JavaScript(document.documentElement.outerHTML),并通过异步任务的回调在UI线程安全的环境中处理结果,避免阻塞主窗体。
2. 不依赖VB方案执行脚本的方法
利用.NET Task的ContinueWith方法,指定在UI同步上下文执行回调逻辑,确保异步操作不会阻塞WinForms主线程,同时避免跨线程访问UI控件的问题。
修正后的完整代码
$teamsdllpath="C:\Users\Administrateur\AppData\Local\Microsoft\TeamsMeetingAddin\1.0.23061.1" # 加载32位WebView2 DLL(必须以32位PowerShell运行) $WinForms = "$teamsdllpath\x86\Microsoft.Web.WebView2.WinForms.dll" $Core = "$teamsdllpath\x86\Microsoft.Web.WebView2.Core.dll" Add-Type -Path $WinForms Add-Type -Path $Core # 创建WinForms窗体与WebView2控件 $Form = New-Object -TypeName System.Windows.Forms.Form -Property @{Width=900;Height=800} $WebView2 = New-Object -TypeName Microsoft.Web.WebView2.WinForms.WebView2 $WebView2.CreationProperties = New-Object -TypeName 'Microsoft.Web.WebView2.WinForms.CoreWebView2CreationProperties' $WebView2.CreationProperties.UserDataFolder = "c:\temp\webviewuserdata" $WebView2.Source = "https://www.example.com" $WebView2.Size = New-Object System.Drawing.Size(884, 760) # 导航完成事件处理:异步执行脚本并安全获取结果 $WebView2_NavigationCompleted = { # 要执行的JavaScript:获取页面完整源码 $script = "document.documentElement.outerHTML" # 异步执行脚本,指定回调在UI线程执行 $WebView2.CoreWebView2.ExecuteScriptAsync($script).ContinueWith({ param($task) # 获取脚本执行结果 $htmlResult = $task.Result # 通过Form.Invoke回到UI线程处理结果(避免跨线程异常) $form.Invoke([Action]{ $global:html = $htmlResult Write-Host $htmlResult $form.Close() }) }, [System.Threading.Tasks.TaskScheduler]::FromCurrentSynchronizationContext()) } $WebView2.add_NavigationCompleted($WebView2_NavigationCompleted) # 显示窗体 $form.Controls.Add($WebView2) $form.Add_Shown({$form.Activate()}) $form.ShowDialog()
关键注意事项
- 32位环境要求:必须启动32位PowerShell(ISE或控制台),否则无法加载x86版本的WebView2 DLL,会抛出加载异常。
- UI线程安全:所有涉及UI控件的操作(如关闭窗体、输出结果)必须通过
Control.Invoke回到UI线程执行,避免跨线程访问异常。 - 异步任务处理:使用
ContinueWith并指定TaskScheduler.FromCurrentSynchronizationContext()确保回调在WinForms主线程执行,彻底解决UI锁定崩溃问题。
内容的提问来源于stack exchange,提问作者Christopher
相关产品推荐
相关产品推荐

