diff --git a/specs/MultiProfile.md b/specs/MultiProfile.md index 14ae95c32..8b2fcde58 100644 --- a/specs/MultiProfile.md +++ b/specs/MultiProfile.md @@ -169,20 +169,29 @@ void ScenarioCookieManagement::DeleteAllCookies() ### Delete profile ```cpp -HRESULT AppWindow::DeleteProfile(ICoreWebView2Controller* controller) +HRESULT AppWindow::DeleteProfile(ICoreWebView2* webView2) { - wil::com_ptr coreWebView2; - CHECK_FAILURE(controller->get_CoreWebView2(&coreWebView2)); - auto webview7 = coreWebView2.try_query(); - if (webview7) + wil::com_ptr profile; + CHECK_FAILURE(webView2->get_Profile(&profile)); + CHECK_FAILURE(profile2->Delete()); +} + +void AppWindow::RegisterEventHandlers() +{ + wil::com_ptr webView2Profile; + webView2_13->get_Profile(&webView2Profile); + if (webView2Profile) { - wil::com_ptr profile; - CHECK_FAILURE(webview7->get_Profile(&profile)); - auto profile2 = profile.try_query(); - if (profile2) - { - CHECK_FAILURE(profile2->Delete()); - } + webView2Profile->add_ProfileDeletionStarted( + Microsoft::WRL::Callback( + [this](ICoreWebView2Profile7* sender, IUnknown* args) + { + RunAsync( [this]() + { + CloseAppWindow(); + } + return S_OK; + }).Get(),nullptr); } } ``` @@ -253,10 +262,23 @@ public DeleteProfile(CoreWebView2Controller controller) { // Get the profile object. CoreWebView2Profile profile = controller.CoreWebView2.Profile; - + // Delete current profile. profile.Delete(); } + +void WebView_CoreWebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e) +{ + WebViewProfile.ProfileDeletionStarted += CoreWebView2_ProfileDeletionStarted; +} + +private void CoreWebView2_ProfileDeletionStarted(object sender, object e) +{ + this.Dispatcher.InvokeAsync(() => + { + Close(); + }); +} ``` # API Details @@ -270,6 +292,8 @@ interface ICoreWebView2_7; interface ICoreWebView2Profile; interface ICoreWebView2Profile2; interface ICoreWebView2Profile3; +interface ICoreWebView2Profile4; +interface ICoreWebView2ProfileDeletionStartedEventHandler; /// This interface is used to manage profile options that created by 'CreateCoreWebView2ControllerOptions'. [uuid(C2669A3A-03A9-45E9-97EA-03CD55E5DC03), object, pointer_default(unique)] @@ -363,16 +387,43 @@ interface ICoreWebView2Profile2 : ICoreWebView2Profile { [propget] HRESULT CookieManager([out, retval] ICoreWebView2CookieManager** cookieManager); } -[uuid(1c1ae2cc-d5c2-ffe3-d3e7-7857035d23b7), object, pointer_default(unique)] -interface ICoreWebView2Profile3 : ICoreWebView2Profile2 { - /// All webviews on this profile will be closed, and the profile will be marked for deletion. - /// After the Delete() call completes, The render process of webviews on this profile will - /// asynchronously exit with the reason:`COREWEBVIEW2_PROCESS_FAILED_REASON_PROFILE_DELETED`. - /// See 'COREWEBVIEW2_PROCESS_FAILED_REASON::COREWEBVIEW2_PROCESS_FAILED_REASON_PROFILE_DELETED' - /// for more details. The profile directory on disk will be actually deleted when the browser - /// process exits. Webview2 creation will fail with the HRESULT is ERROR_INVALID_STATE(0x8007139FL) - /// if you create it with the same name as a profile that is being deleted. - HRESULT Delete(); +/// Interfaces in profile for Delete. +[uuid(7CB8811D-A9B6-425E-9C57-0B0E599BAC5D), object, pointer_default(unique)] +interface ICoreWebView2Profile7 : IUnknown { + /// After the API is called, the profile will be marked for deletion. If the + /// profile has been marked for deletion, this API will return S_OK directly. + /// The local profile's directory will be tried to delete at browser + /// process exit, if fail to delete, it will recursively try to delete at + /// next browser process start until successful. + /// When the profile is marked for deletion, the corresponding + /// `ProfileDeletionStarted` event handle of each profile with the same name + /// in current or different process will be all triggered. See + /// `add_ProfileDeletionStarted` for more information. + /// If create a new profile with the same name as the profile that has been + /// marked as deleted will be failure with the HRESULT:ERROR_INVALID_STATE + /// (0x8007139FL). + HRESULT Delete(); + + /// The `ProfileDeletionStarted` event will be raised when profile has been + /// marked as deleted. When this event has been raised, it is recommended to + /// do some clean works and then close the webview2. + HRESULT add_ProfileDeletionStarted ( + [in] ICoreWebView2ProfileDeletionStartedEventHandler* eventHandler, + [out] EventRegistrationToken* token); + + /// Remove an event handler previously added with `add_ProfileDeletionStarted`. + HRESULT remove_ProfileDeletionStarted ( + [in] EventRegistrationToken token); +} + +/// Receives the profile `ProfileDeletionStarted` event. +[uuid(970BB7E0-A257-4A76-BE15-5BDEB00B5673), object, pointer_default(unique)] +interface ICoreWebView2ProfileDeletionStartedEventHandler : IUnknown { + /// Called to provide the implementer for the ProfileDeletionStarted event. + /// No event args exist and the `args` parameter is set to `null`. + HRESULT Invoke( + [in] ICoreWebView2Profile7* sender, + [in] IUnknown* args); } ``` @@ -409,13 +460,6 @@ namespace Microsoft.Web.WebView2.Core CoreWebView2ControllerWindowReference ParentWindow, CoreWebView2ControllerOptions options); } - - runtimeclass CoreWebView2 - { - // ... - CoreWebView2Profile Profile { get; }; - } - runtimeclass CoreWebView2Profile { String ProfileName { get; }; @@ -426,10 +470,10 @@ namespace Microsoft.Web.WebView2.Core CoreWebView2CookieManager CookieManager { get; }; - [interface_name("Microsoft.Web.WebView2.Core.ICoreWebView2Profile3")] + [interface_name("Microsoft.Web.WebView2.Core.ICoreWebView2Profile7")] { - // ICoreWebView2Profile3 members void Delete(); + event Windows.Foundation.TypedEventHandler ProfileDeletionStarted; } } }