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

WPF中使用WebView加载本地视频导致文件被锁定的问题

解决WPF WebView加载本地视频后文件锁定的问题

这个问题我之前也踩过坑,核心原因是WebView(不管是旧的WebBrowser还是新的WebView2)在直接加载本地视频文件时,底层浏览器引擎会一直占用文件句柄——就算你关闭了包含WebView的窗口,只要控件没被彻底清理,句柄就不会释放,自然没法修改或删除原文件。下面是几个实测有效的解决办法:

1. 改用自定义协议/流加载视频(推荐)

直接让VIDEO标签指向本地文件路径是句柄锁定的根源,换成通过自定义协议或内存流传递视频内容,就能从根本上避免原文件被占用。

以WebView2为例,你可以注册一个自定义URI协议(比如myapp://videos/),拦截WebView的资源请求,读取本地视频文件的流并返回给浏览器:

private void SetupWebView2Protocol()
{
    webView2.CoreWebView2InitializationCompleted += (s, e) =>
    {
        // 拦截自定义协议的请求
        webView2.CoreWebView2.AddWebResourceRequestedFilter("myapp://*", Microsoft.Web.WebView2.Core.CoreWebView2WebResourceContext.All);
        webView2.CoreWebView2.WebResourceRequested += OnWebResourceRequested;
    };
}

private void OnWebResourceRequested(object sender, Microsoft.Web.WebView2.Core.CoreWebView2WebResourceRequestedEventArgs e)
{
    var requestUri = new Uri(e.Request.Uri);
    if (requestUri.Scheme == "myapp" && requestUri.Host == "videos")
    {
        // 解析出本地视频路径
        var videoFileName = requestUri.AbsolutePath.TrimStart('/');
        var localVideoPath = Path.Combine("你的本地视频目录", videoFileName);
        
        if (File.Exists(localVideoPath))
        {
            // 读取文件流并返回给WebView
            var fileStream = File.OpenRead(localVideoPath);
            var response = webView2.CoreWebView2.Environment.CreateWebResourceResponse(
                fileStream,
                200,
                "OK",
                $"Content-Type: video/{Path.GetExtension(localVideoPath).TrimStart('.')}"
            );
            e.Response = response;
        }
    }
}

之后在网页的VIDEO标签里写src="myapp://videos/你的视频文件名.mp4",WebView就会通过自定义协议读取文件,不会锁定原文件。

2. 关闭窗口前强制清理WebView

如果必须直接加载本地文件路径,一定要在窗口关闭前让WebView彻底释放资源:

  • 先导航到空白页,让浏览器停止加载并释放文件句柄
  • 等待导航完成后,手动销毁WebView控件

在WPF窗口的Closing事件里添加如下逻辑:

private async void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
    // 先阻止窗口直接关闭,先做清理
    e.Cancel = true;

    // 导航到空白页,释放文件句柄
    if (webView is WebBrowser oldBrowser)
    {
        oldBrowser.Navigate("about:blank");
    }
    else if (webView is WebView2 webView2)
    {
        webView2.CoreWebView2.Navigate("about:blank");
    }

    // 给浏览器一点时间完成资源释放
    await Task.Delay(200);

    // 手动销毁WebView控件
    webView.Dispose();

    // 现在关闭窗口
    (sender as Window).Close();
}

这个方法的关键是不能让窗口直接关闭,必须先让WebView导航离开视频页面,确保文件句柄被释放。

3. 临时文件中转(应急方案)

如果上面的方法暂时没法落地,可以把要播放的视频复制到系统临时目录,让WebView加载临时文件。这样原文件不会被锁定,播放完成后还能删除临时文件:

private string CopyVideoToTemp(string originalPath)
{
    var tempFileName = Guid.NewGuid() + Path.GetExtension(originalPath);
    var tempPath = Path.Combine(Path.GetTempPath(), tempFileName);
    File.Copy(originalPath, tempPath);
    return tempPath;
}

// 加载视频时使用临时路径
var tempVideoPath = CopyVideoToTemp("你的原视频路径.mp4");
// 将tempVideoPath传入网页的VIDEO标签

不过这个方法会占用额外磁盘空间,适合临时应急场景。


内容的提问来源于stack exchange,提问作者Panzer Ihnen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 11:33:03