@@ -12,16 +12,29 @@ document we describe the new API. We'd appreciate your feedback.
1212# Description
1313The ` BrowserProcessExited ` event allows developers to subscribe event handlers
1414to be run when the ` WebView2 Runtime ` 's browser process associated to a
15- ` CoreWebView2Environment ` terminates. A key scenario is cleanup of the use data
15+ ` CoreWebView2Environment ` terminates. Key scenarios are cleanup of the use data
1616folder used by the ` WebView2 Runtime ` , which is locked while the runtime's
17- browser process is active.
17+ browser process is active, and moving to a new ` WebView2 Runtime ` version after
18+ a ` NewBrowserVersionAvailable ` event.
1819
1920This event is raised for both expected and unexpected browser process
20- termination. The ` ICoreWebView2BrowserProcessExitedEventArgs ` interfaces lets
21- app developers get the ` BrowserProcessExitKind ` so they can decide how to handle
22- different exit kinds or bypass handling if an event handler for the
23- ` CoreWebView2 ` s ` ProcessFailed ` event (for
24- ` CoreWebView2ProcessFailedKind.BrowserProcessFailed ` ) is already registered.
21+ termination, after all resources, including the user data folder, used by the
22+ browser process (and related processes) have been released. The
23+ ` ICoreWebView2BrowserProcessExitedEventArgs ` interface lets app developers get
24+ the ` BrowserProcessExitKind ` so they can decide how to handle different exit
25+ kinds or bypass handling if an event handler for the ` CoreWebView2 ` s
26+ ` ProcessFailed ` event (for ` CoreWebView2ProcessFailedKind.BrowserProcessFailed ` )
27+ is already registered. In case of a browser process crash, both
28+ ` BrowserProcessExited ` and ` ProcessFailed ` events are raised, but the order is
29+ not guaranteed.
30+
31+ All ` CoreWebView2Environment ` objects across different app processes that use
32+ the same browser process receive this event when the browser process exits.
33+ If the browser process (and therefore the user data folder) in use by the app
34+ process (through the ` CoreWebView2Environment ` options used) is shared with
35+ other processes, these processes need to coordinate to handle the potential race
36+ condition on the use of the resources. E.g., if one app process tries to clear
37+ the user data folder, while other tries to recreate its WebViews on crash.
2538
2639
2740# Examples
@@ -62,14 +75,68 @@ CHECK_FAILURE(m_webViewEnvironment->add_BrowserProcessExited(
6275
6376## .NET C#
6477```c#
65- // Get the environment from the CoreWebView2 and add a handler.
66- webView.CoreWebView2.Environment.BrowserProcessExited += Environment_BrowserProcessExited;
78+ // URI or other state to save/restore when the WebView is recreated.
79+ private Uri _uriToRestore;
80+
81+ async void RegisterForNewVersion()
82+ {
83+ // We need to make sure the CoreWebView2 property is not null, so we can get
84+ // the environment from it. Alternatively, if the WebView was created from
85+ // an environment provided to the control, we can use that environment
86+ // object directly.
87+ await webView.EnsureCoreWebView2Async();
88+ _coreWebView2Environment = webView.CoreWebView2.Environment;
89+ _coreWebView2Environment.NewBrowserVersionAvailable += Environment_NewBrowserVersionAvailable;
90+ }
91+
92+ // A new version of the WebView2 Runtime is available, our handler gets called.
93+ // We close our WebView and set a handler to reinitialize it once the browser
94+ // process is gone, so we get the new version of the WebView2 Runtime.
95+ void Environment_NewBrowserVersionAvailable(object sender, object e)
96+ {
97+ StringBuilder messageBuilder = new StringBuilder(256);
98+ messageBuilder.Append("We detected there is a new version of the WebView2 Runtime installed. ");
99+ messageBuilder.Append("Do you want to switch to it now? This will re-create the WebView.");
100+ var selection = MessageBox.Show(this, messageBuilder.ToString(), "New WebView2 Runtime detected", MessageBoxButton.YesNo);
101+ if (selection == MessageBoxResult.Yes)
102+ {
103+ // Save URI or other state you want to restore when the WebView is recreated.
104+ _uriToRestore = webView.Source;
105+ _coreWebView2Environment.BrowserProcessExited += Environment_BrowserProcessExited;
106+ // We dispose of the control so the internal WebView objects are released
107+ // and the associated browser process exits. If there are any other WebViews
108+ // from the same environment configuration, they need to be closed too.
109+ webView.Dispose();
110+ webView = null;
111+ }
112+ }
67113
68- // Check and report browser process exit kind.
69114void Environment_BrowserProcessExited(object sender, CoreWebView2BrowserProcessExitedEventArgs e)
70115{
71- var exitKind = (e.BrowserProcessExitKind == CoreWebView2BrowserProcessExitKind.NormalExit) ? "normally" : "unexpectedly";
72- MessageBox.Show(this, $"The browser process has exited {exitKind}.", "Browser Process Exited");
116+ ((CoreWebView2Environment)sender).BrowserProcessExited -= Environment_BrowserProcessExited;
117+ ReinitializeWebView();
118+ }
119+
120+ void ReinitializeWebView()
121+ {
122+ webView = new WebView2();
123+
124+ // Restore URI and other WebView state/setup.
125+ webView.CreationProperties = (CoreWebView2CreationProperties)this.FindResource("EvergreenWebView2CreationProperties");
126+ webView.NavigationStarting += WebView_NavigationStarting;
127+ webView.NavigationCompleted += WebView_NavigationCompleted;
128+
129+ Binding urlBinding = new Binding()
130+ {
131+ Source = webView,
132+ Path = new PropertyPath("Source"),
133+ Mode = BindingMode.OneWay
134+ };
135+ url.SetBinding(TextBox.TextProperty, urlBinding);
136+
137+ MyWindow.MyDockPanel.Children.Add(webView);
138+ webView.Source = (_uriToRestore != null) ? _uriToRestore : new Uri("https://www.bing.com");
139+ RegisterForNewVersion();
73140}
74141```
75142
@@ -83,6 +150,9 @@ raised for any (expected and unexpected) **browser process** exits, while
83150** render process** exits/unresponsiveness. To learn more about the WebView2
84151Process Model, go to [ Process model] ( https://docs.microsoft.com/en-us/microsoft-edge/webview2/concepts/process-model ) .
85152
153+ In the case the browser process crashes, both ` BrowserProcessExited ` and
154+ ` ProcessFailed ` events are raised, but the order is not guaranteed.
155+
86156
87157# API Notes
88158See [ API Details] ( #api-details ) section below for API reference.
@@ -115,19 +185,32 @@ interface ICoreWebView2Environment3 : ICoreWebView2Environment2
115185 /// Add an event handler for the ` BrowserProcessExited ` event.
116186 /// The ` BrowserProcessExited ` event is raised when the browser process of the
117187 /// WebView2 Runtime associated to this environment terminates due to an error
118- /// or normal shutdown (e.g., when all its WebViews are closed).
188+ /// or normal shutdown (e.g., when all its WebViews are closed), after all
189+ /// resources (including the user data folder) used by the browser process
190+ /// (and related processes) have been released.
119191 ///
120192 /// A handler added with this method is called until removed with
121193 /// ` remove_BrowserProcessExited ` , even if a new browser process is bound to
122194 /// this environment after earlier ` BrowserProcessExited ` events are raised.
123195 ///
196+ /// All ` CoreWebView2Environment ` objects across different app processes that use
197+ /// the same browser process receive this event when the browser process exits.
198+ /// If the browser process (and therefore the user data folder) in use by the app
199+ /// process (through the ` CoreWebView2Environment ` options used) is shared with
200+ /// other processes, these processes need to coordinate to handle the potential race
201+ /// condition on the use of the resources. E.g., if one app process tries to clear
202+ /// the user data folder, while other tries to recreate its WebViews on crash.
203+ ///
124204 /// Note this is an event from the ` ICoreWebView2Environment3 ` interface, not the
125205 /// ` ICoreWebView2 ` . The difference between this ` BrowserProcessExited ` event and
126206 /// the ` CoreWebView2 ` 's ` ProcessFailed ` event is that ` BrowserProcessExited ` is
127207 /// raised for any (expected and unexpected) ** browser process** exits, while
128208 /// ` ProcessFailed ` is raised only for ** unexpected** browser process exits, or for
129209 /// ** render process** exits/unresponsiveness. To learn more about the WebView2
130210 /// Process Model, go to [ Process model] ( https://docs.microsoft.com/en-us/microsoft-edge/webview2/concepts/process-model ) .
211+ ///
212+ /// In the case the browser process crashes, both ` BrowserProcessExited ` and
213+ /// ` ProcessFailed ` events are raised, but the order is not guaranteed.
131214 HRESULT add_BrowserProcessExited(
132215 [ in] ICoreWebView2BrowserProcessExitedEventHandler* eventHandler,
133216 [ out] EventRegistrationToken* token);
@@ -180,7 +263,17 @@ namespace Microsoft.Web.WebView2.Core
180263 /// `BrowserProcessExited` is raised when the browser process of the
181264 /// `WebView2 Runtime` associated to this `CoreWebView2Environment`
182265 /// terminates due to an error or normal shutdown (e.g., when all its
183- /// WebViews are closed).
266+ /// WebViews are closed), after all resources (including the user data
267+ /// folder) used by the browser process (and related processes) have
268+ /// been released.
269+ ///
270+ /// All `CoreWebView2Environment` objects across different app processes that use
271+ /// the same browser process receive this event when the browser process exits.
272+ /// If the browser process (and therefore the user data folder) in use by the app
273+ /// process (through the `CoreWebView2Environment` options used) is shared with
274+ /// other processes, these processes need to coordinate to handle the potential race
275+ /// condition on the use of the resources. E.g., if one app process tries to clear
276+ /// the user data folder, while other tries to recreate its WebViews on crash.
184277 ///
185278 /// Note this is an event from `CoreWebView2Environment`, not the
186279 /// `CoreWebView2`. The difference between this `BrowserProcessExited` event and
@@ -189,6 +282,9 @@ namespace Microsoft.Web.WebView2.Core
189282 /// `ProcessFailed` is raised only for **unexpected** browser process exits, or for
190283 /// **render process** exits/unresponsiveness. To learn more about the WebView2
191284 /// Process Model, go to [Process model](https://docs.microsoft.com/en-us/microsoft-edge/webview2/concepts/process-model).
285+ ///
286+ /// In the case the browser process crashes, both `BrowserProcessExited` and
287+ /// `ProcessFailed` events are raised, but the order is not guaranteed.
192288 event Windows.Foundation.TypedEventHandler<CoreWebView2Environment, CoreWebView2BrowserProcessExitedEventArgs> BrowserProcessExited;
193289 }
194290
0 commit comments