My C# application uses WebView2.
It is required that multiple instances are open at the same time which do not share sessions. According to this explanation of the WebView2 process model, this is achieved by using different UserDataFolders, passed at creation of the CoreWebView2Environment.
The app is currently loaded from a read-only network share, so the default setting to create the user data folders alongside the exe is not eligible, so my implementation creates different UserDataFolders in the user temp directory.
To clean up, I would like to delete the created directories when the application is closed. The documentation suggests the BrowserProcessExited Event which should be called when all resources taken by the WebView2 are released.
But the BrowserProcessExited event never gets called.
In the Page where the WebView2 is used, I do:
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
}
}
My guess is that the application is closed before the event gets fired.
What is necessary to achieve that the BrowserProcessExited
event is received?
You must wait for the process to exit before shutting down the application. From the docs:
To delete a user data folder (UDF), you must first end the WebView2 session. You cannot delete a UDF if the WebView2 session is currently active.
If files are still in use after your WebView2 host app closes, wait for browser processes to exit before deleting the user data folder (UDF).
Files in UDFs might still be in use after the WebView2 app is closed. In this situation, wait for the browser process and all child processes to exit before deleting the UDF. To monitor processes to wait for them to exit, retrieve the process ID of the browser process by using the BrowserProcessId property of the WebView2 app instance.
I did it this way, which is similar to CFou's answer:
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
}
}
I set the timeout to 3 seconds, which should be plenty. Beware not to use the async version of WaitForExit because async void methods cannot be awaited, so WPF will happily continue shutting down the application.