You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WebView2初始化浏览器触发路径非法格式ArgumentException异常排查

问题背景

WinForms应用集成Microsoft.Web.WebView2控件,预期实现以下功能:

  • 浏览器控件初始化
  • 自动导航至穆迪官网
  • 检测用户登录状态
  • 自动触发指定文件下载、等待下载流程完成
    程序执行初始化代码时抛出路径格式非法异常。
异常信息
System.ArgumentException: The path is not of a legal form.

完整调用堆栈:

at System.IO.Path.LegacyNormalizePath(String path, Boolean fullCheck, Int32 maxPathLength, Boolean expandShortPaths)
at System.IO.Path.InternalGetDirectoryName(String path)
at Microsoft.Web.WebView2.Core.CoreWebView2Environment.LoadWebView2LoaderDll()
at Microsoft.Web.WebView2.Core.CoreWebView2Environment.d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Web.WebView2.WinForms.WebView2.d__23.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at ECLautomation.Form1.d__150.MoveNext() in xxx\Form1.cs:line xxx
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at ECLautomation.Form1.<Form1_Load>d__149.MoveNext() in xxx\Form1.cs:line xxx
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

触发异常的代码

异常在执行以下初始化逻辑时抛出:

CoreWebView2Environment webView2Environment = null;
await webView21.EnsureCoreWebView2Async(webView2Environment);

完整业务实现代码:

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 WinFormsApp2
{
    public partial class Form1 : Form
    {
        private static readonly string indexUrl = "http://www.moodys.com";

        public Form1()
        {
            InitializeComponent();
        }

        private async void Form1_Load(object sender, EventArgs e)
        {
            await InitializeAsync(webView21);
        }

        public async Task InitializeAsync(WebView2 webView21)
        {
            CoreWebView2Environment webView2Environment = null;
            await webView21.EnsureCoreWebView2Async(webView2Environment);
        }

        private void webView21_CoreWebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e)
        {
            webView21.CoreWebView2.Navigate(indexUrl);
        }

        private void webView21_NavigationCompleted(object sender, CoreWebView2NavigationCompletedEventArgs e)
        {
            string url = webView21.CoreWebView2.Source.ToString();
            Console.WriteLine(url);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            bool res = IsLogin();

            if (res == true)
            {
                MessageBox.Show("Please login Moody's");
            }
            else
            {
                MessageBox.Show("Successful");
                webView21.CoreWebView2.Navigate("https://www.moodys.com/search?keyword=annual%20default%20study%20excel&searchfrom=GS");
                WaitForSeconds(10);
                SendKeys.SendWait("{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}");
                SendKeys.SendWait("{ENTER}");

                MessageBox.Show("Annual Default Study file downloaded, please close the popup edge browser.");

                WaitForSeconds(10);
                webView21.CoreWebView2.Navigate("https://www.moodys.com/search?keyword=Sovereign%20Default%20And%20Recovery%20Rates%20excel%20data&searchfrom=GS");
                WaitForSeconds(10);
                SendKeys.SendWait("{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}");
                SendKeys.SendWait("{ENTER}");

                MessageBox.Show("Sovereign file downloaded, please close the popup edge browser.");
            }
        }

        public static void WaitForSeconds(int seconds)
        {
            DateTime startTime;
            DateTime endTime;
            startTime = DateTime.Now;
            for (int i = 0; ; i++)
            {
                endTime = DateTime.Now;
                TimeSpan difference = endTime - startTime;
                if (difference.TotalSeconds < seconds)
                {
                    Application.DoEvents();
                }
                else
                {
                    break;
                }
            }
        }

        private bool IsLogin()
        {
            var js = @"document.documentElement.innerText.indexOf('Sign In or Register');";
            int res = Convert.ToInt32(ExecuteScript(js));
            return res >= 1;
        }

        private string ExecuteScript(string javaScript)
        {
            var taskAwaiter = webView21.CoreWebView2.ExecuteScriptAsync(javaScript).GetAwaiter();
            WaitAsyncTask(5, taskAwaiter);
            return taskAwaiter.GetResult();
        }

        public void WaitAsyncTask(int waitSecond, System.Runtime.CompilerServices.TaskAwaiter<string> activeTask)
        {
            DateTime WaitStartTime = DateTime.Now;
            double secondDiffer = (DateTime.Now - WaitStartTime).TotalSeconds;
            while (secondDiffer < waitSecond)
            {
                secondDiffer = (DateTime.Now - WaitStartTime).TotalSeconds;
                Application.DoEvents();
                if (activeTask.IsCompleted)
                {
                    break;
                }
            }
        }
    }
}
根因定位

初始化代码存在明确错误,直接触发异常的原因如下:

  1. 向EnsureCoreWebView2Async传入null作为环境参数时,WebView2 SDK会自动尝试推导运行时路径、用户数据目录,旧版本SDK存在路径解析bug:当程序从含特殊字符的路径、网络共享路径启动时,内部调用Path.InternalGetDirectoryName处理空值或非法格式路径,直接抛出路径格式非法异常。
  2. 代码存在其他稳定性隐患:
    • 未显式指定用户数据目录,不同运行环境下自动生成的路径可能出现权限不足、格式非法问题
    • 用固定延时+SendKeys模拟页面操作,完全依赖页面加载耗时,极易失效
    • 异步任务用阻塞循环+Application.DoEvents()等待,存在UI死锁风险
    • 登录状态判断逻辑颠倒:检测到"Sign In or Register"文本说明用户未登录,现有判断分支的提示逻辑完全相反
    • 下载流程依赖人工关闭弹窗,没有对接WebView2原生下载事件,无法准确判断下载完成状态。
修复方案
  1. 修正初始化逻辑,显式创建WebView2环境,指定合法的用户数据目录,禁止传入null:
using System.IO;

public async Task InitializeAsync(WebView2 webView21)
{
    // 显式指定用户数据存储目录,使用程序启动路径下的独立文件夹,避免路径解析问题
    string userDataPath = Path.Combine(Application.StartupPath, "WebView2_UserData");
    // 创建WebView2运行环境,第一个参数为null时自动查找系统已安装的WebView2 Runtime
    CoreWebView2Environment env = await CoreWebView2Environment.CreateAsync(null, userDataPath);
    await webView21.EnsureCoreWebView2Async(env);
}
  1. 提前确认运行环境:目标机器安装与项目NuGet包版本匹配的WebView2 Runtime,或把固定版本运行时嵌入程序输出目录。
  2. 重构交互逻辑:移除所有SendKeys、阻塞等待写法,页面操作全部通过ExecuteScriptAsync直接操作DOM元素触发,异步方法统一用await等待结果。
  3. 对接WebView2原生下载事件:订阅CoreWebView2.DownloadStarting事件,监听每个下载任务的StateChanged事件,在下载完成/失败后再执行后续流程,无需人工介入。
  4. 修正登录状态判断逻辑,调整提示分支的对应关系。

内容的提问来源于stack exchange,提问作者Jason Wong

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 00:48:24