繁体   English   中英

如何删除 C# WPF 应用程序中的 WebView2 UserDataFolder,BrowserProcessExited 事件不会触发

[英]How to delete the WebView2 UserDataFolder in C# WPF Application, BrowserProcessExited event does not fire

我的 C# 应用程序使用 WebView2。

要求同时打开多个不共享会话的实例。 根据对 WebView2 进程 model 的解释,这是通过使用不同的UserDataFolder来实现的,在创建 CoreWebView2Environment 时传递。

该应用程序当前是从只读网络共享加载的,因此在 exe 旁边创建用户数据文件夹的默认设置不符合条件,因此我的实现在用户临时目录中创建了不同的 UserDataFolders。

为了清理,我想在应用程序关闭时删除创建的目录。 文档建议在释放 WebView2 占用的所有资源时调用BrowserProcessExited事件。

但是BrowserProcessExited 事件永远不会被调用

在使用 WebView2 的页面中,我这样做:

public void MyApp_Closing(object sender, CancelEventArgs e)
{
    glucoTabWebcontrol2.CoreWebView2.Environment.BrowserProcessExited += Environment_BrowserProcessExited;
}

// This is never called
private void Environment_BrowserProcessExited(object sender, CoreWebView2BrowserProcessExitedEventArgs e)
{
    try
    {
        System.IO.Directory.Delete(((CoreWebView2Environment)sender).UserDataFolder);
    } catch (Exception ex)
    {
        ... handle exception
    }
}

我的猜测是应用程序在事件被触发之前关闭。 要实现接收到BrowserProcessExited事件需要什么?

MyApp_Closing方法中,检索 WebView2 浏览器的 pid,然后释放控件。

一旦处理,等待进程退出(2秒超时)

当进程有效停止时,删除文件夹:

try
{
    uint wvProcessId = glucoTabWebcontrol2.CoreWebView2.BrowserProcessId;
    string userDataFolder = glucoTabWebcontrol2.CoreWebView2.Environment.UserDataFolder;
    int timeout = 10;

    glucoTabWebcontrol2.Dispose();
    try
    {
        while (System.Diagnostics.Process.GetProcessById(Convert.ToInt32(wvProcessId)) != null && timeout < 2000)
        {
            System.Threading.Thread.Sleep(10);
            timeout += 10;
        }
    }
    catch { }
    Directory.Delete(userDataFolder, true)
}
catch
{
    // Eventually show error deletion here
}

在关闭应用程序之前,您必须等待进程退出。 文档

要删除用户数据文件夹 (UDF),您必须首先结束 WebView2 session。 如果 WebView2 session 当前处于活动状态,则无法删除 UDF。

如果 WebView2 主机应用程序关闭后文件仍在使用中,请等待浏览器进程退出,然后再删除用户数据文件夹 (UDF)。

在 WebView2 应用程序关闭后,UDF 中的文件可能仍在使用中。 在这种情况下,请等待浏览器进程和所有子进程退出,然后再删除 UDF。 要监视进程以等待它们退出,请使用 WebView2 应用实例的 BrowserProcessId 属性检索浏览器进程的进程 ID。

我是这样做的,类似于 CFou 的回答:

Application.Current.Exit += OnAppExit;
private void OnAppExit(object sender, ExitEventArgs e)
{
    try
    {
        // Delete WebView2 user data before application exits
        string? webViewCacheDir = Browser.CoreWebView2.Environment.UserDataFolder;
        var webViewProcessId = Convert.ToInt32(Browser.CoreWebView2.BrowserProcessId);
        var webViewProcess = Process.GetProcessById(webViewProcessId);

        // Shutdown browser with Dispose, and wait for process to exit
        Browser.Dispose();
        webViewProcess.WaitForExit(3000);

        Directory.Delete(webViewCacheDir, true);
    }
    catch (Exception ex)
    {
        // log warning
    }
}

我将超时设置为 3 秒,这应该足够了。 注意不要使用 WaitForExit 的异步版本,因为无法等待异步 void 方法,因此 WPF 将愉快地继续关闭应用程序。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM