From 3b46d95e1a8853a4d798a2a2deda1822cbdfcbdb Mon Sep 17 00:00:00 2001
From: Denghui Yu <denghuiyu@microsoft.com>
Date: Thu, 15 Dec 2022 16:13:02 +0800
Subject: [PATCH 1/8]  Multiprofile's Delete API modify

---
 specs/MultiProfile.md | 42 +++++++++++++++++++-----------------------
 1 file changed, 19 insertions(+), 23 deletions(-)

diff --git a/specs/MultiProfile.md b/specs/MultiProfile.md
index 14ae95c32..ad0e76ce3 100644
--- a/specs/MultiProfile.md
+++ b/specs/MultiProfile.md
@@ -169,21 +169,11 @@ void ScenarioCookieManagement::DeleteAllCookies()
 ### Delete profile
 
 ```cpp
-HRESULT AppWindow::DeleteProfile(ICoreWebView2Controller* controller)
+HRESULT AppWindow::DeleteProfile(ICoreWebView2* webView2)
 {
-    wil::com_ptr<ICoreWebView2> coreWebView2;
-    CHECK_FAILURE(controller->get_CoreWebView2(&coreWebView2));
-    auto webview7 = coreWebView2.try_query<ICoreWebView2_7>();
-    if (webview7)
-    {
-        wil::com_ptr<ICoreWebView2Profile> profile;
-        CHECK_FAILURE(webview7->get_Profile(&profile));
-        auto profile2 = profile.try_query<ICoreWebView2StagingProfile4>();
-        if (profile2)
-        {
-            CHECK_FAILURE(profile2->Delete());
-        }
-    }
+    wil::com_ptr<ICoreWebView2Profile> profile;
+    CHECK_FAILURE(webView2->get_Profile(&profile));
+    CHECK_FAILURE(profile2->Delete());
 }
 ```
 
@@ -253,7 +243,7 @@ public DeleteProfile(CoreWebView2Controller controller)
 {
     // Get the profile object.
     CoreWebView2Profile profile = controller.CoreWebView2.Profile;
-    
+
     // Delete current profile.
     profile.Delete();
 }
@@ -365,14 +355,20 @@ interface ICoreWebView2Profile2 : ICoreWebView2Profile {
 
 [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(); 
+  /// After the API is called, the profile will be marked for deletion. 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.
+  /// The corresponding user's `ProfileDeleted` event handle function will
+  /// be triggered. After the function is triggered, continuing to use the
+  /// profile or its corresponding webviews is an undefined behavior.
+  /// For each WebView of the same profile, the WebView will be auto closed.
+  /// If the user has registered an event handler for ProfileDeleted event,
+  /// the event handle will be invoked before WebView is closed.
+  /// 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();
 }
 ```
 

From 710afd2faced2d637576710d9d8d14d274fcc4a5 Mon Sep 17 00:00:00 2001
From: Denghui Yu <denghuiyu@microsoft.com>
Date: Mon, 19 Dec 2022 16:50:38 +0800
Subject: [PATCH 2/8] add add_ProfileDeleted/remove_ProfileDeleted SPEC

---
 specs/MultiProfile.md | 58 ++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 54 insertions(+), 4 deletions(-)

diff --git a/specs/MultiProfile.md b/specs/MultiProfile.md
index ad0e76ce3..64f119d97 100644
--- a/specs/MultiProfile.md
+++ b/specs/MultiProfile.md
@@ -175,6 +175,22 @@ HRESULT AppWindow::DeleteProfile(ICoreWebView2* webView2)
     CHECK_FAILURE(webView2->get_Profile(&profile));
     CHECK_FAILURE(profile2->Delete());
 }
+
+EventRegistrationToken m_profileDeletedEventToken = {};
+void AppWindow::AddProfileDeleted(ICoreWebView2* webView2)
+{
+    CHECK_FAILURE(webView2->add_ProfileDeleted(
+        Microsoft::WRL::Callback<ICoreWebView2StagingProfileDeletedEventHandler>(
+            [this](ICoreWebView2Staging9* sender, IUnknown* args)  {
+                CloseAppWindow();
+                return S_OK;
+            }).Get(), &m_profileDeletedEventToken));
+}
+
+void AppWindow::RemoveProfileDeleted(ICoreWebView2* webView2)
+{
+    CHECK_FAILURE(webView2->remove_ProfileDeleted(m_profileDeletedEventToken));
+}
 ```
 
 ## .NET and WinRT
@@ -247,6 +263,21 @@ public DeleteProfile(CoreWebView2Controller controller)
     // Delete current profile.
     profile.Delete();
 }
+
+private void AddProfileDeleted(object sender, object e)
+{
+    webView.CoreWebView2.ProfileDeleted += CoreWebView2_ProfileDeleted;
+}
+
+private void RemoveProfileDeleted(object sender, object e)
+{
+    webView.CoreWebView2.ProfileDeleted -= CoreWebView2_ProfileDeleted;
+}
+
+private void CoreWebView2_ProfileDeleted(object sender, object e)
+{
+    Close();
+}
 ```
 
 # API Details
@@ -353,8 +384,8 @@ interface ICoreWebView2Profile2 : ICoreWebView2Profile {
   [propget] HRESULT CookieManager([out, retval] ICoreWebView2CookieManager** cookieManager);
 }
 
-[uuid(1c1ae2cc-d5c2-ffe3-d3e7-7857035d23b7), object, pointer_default(unique)]
-interface ICoreWebView2Profile3 : ICoreWebView2Profile2 {
+[uuid(2765B8BD-7C57-4B76-B8AA-1EC940FE92CC), object, pointer_default(unique)]
+interface ICoreWebView2StagingProfile4 : IUnknown {
   /// After the API is called, the profile will be marked for deletion. 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
@@ -370,6 +401,20 @@ interface ICoreWebView2Profile3 : ICoreWebView2Profile2 {
   /// (0x8007139FL).
   HRESULT Delete();
 }
+
+[uuid(cc39bea3-f6f8-471b-919f-fa253e2fff03), object, pointer_default(unique)]
+interface ICoreWebView2Staging9 : IUnknown {
+  /// The `ProfileDeleted` event is raised when its corresponding Profile's
+  /// Delete API is called. When this event has been raised, continue to use
+  /// the profile or its corresponding webviews is an undefined behavior.
+  HRESULT add_ProfileDeleted(
+      [in] ICoreWebView2StagingProfileDeletedEventHandler* eventHandler,
+      [out] EventRegistrationToken* token);
+
+  /// Remove an event handler previously added with `add_ProfileDeleted`.
+  HRESULT remove_ProfileDeleted(
+      [in] EventRegistrationToken token);
+}
 ```
 
 ## .NET and WinRT
@@ -410,6 +455,11 @@ namespace Microsoft.Web.WebView2.Core
     {
         // ...
         CoreWebView2Profile Profile { get; };
+
+        [interface_name("Microsoft.Web.WebView2.Core.ICoreWebView2Staging9")]
+        {
+            event Windows.Foundation.TypedEventHandler<CoreWebView2, Object> ProfileDeleted;
+        }
     }
     
     runtimeclass CoreWebView2Profile
@@ -422,9 +472,9 @@ namespace Microsoft.Web.WebView2.Core
 
         CoreWebView2CookieManager CookieManager { get; };
         
-        [interface_name("Microsoft.Web.WebView2.Core.ICoreWebView2Profile3")]
+        [interface_name("Microsoft.Web.WebView2.Core.ICoreWebView2StagingProfile4")]
         {
-            // ICoreWebView2Profile3 members
+            // ICoreWebView2StagingProfile4 members
             void Delete();
         }
     }

From 3a0c4aa9f83b36a4cdf2156674f7c5b4be5dd1f4 Mon Sep 17 00:00:00 2001
From: Denghui Yu <denghuiyu@microsoft.com>
Date: Wed, 4 Jan 2023 14:02:08 +0800
Subject: [PATCH 3/8] comments fix

---
 specs/MultiProfile.md | 19 ++++---------------
 1 file changed, 4 insertions(+), 15 deletions(-)

diff --git a/specs/MultiProfile.md b/specs/MultiProfile.md
index 64f119d97..86a519d26 100644
--- a/specs/MultiProfile.md
+++ b/specs/MultiProfile.md
@@ -176,20 +176,14 @@ HRESULT AppWindow::DeleteProfile(ICoreWebView2* webView2)
     CHECK_FAILURE(profile2->Delete());
 }
 
-EventRegistrationToken m_profileDeletedEventToken = {};
-void AppWindow::AddProfileDeleted(ICoreWebView2* webView2)
+void AppWindow::RegisterEventHandlers()
 {
-    CHECK_FAILURE(webView2->add_ProfileDeleted(
+    CHECK_FAILURE(m_webView->add_ProfileDeleted(
         Microsoft::WRL::Callback<ICoreWebView2StagingProfileDeletedEventHandler>(
             [this](ICoreWebView2Staging9* sender, IUnknown* args)  {
                 CloseAppWindow();
                 return S_OK;
-            }).Get(), &m_profileDeletedEventToken));
-}
-
-void AppWindow::RemoveProfileDeleted(ICoreWebView2* webView2)
-{
-    CHECK_FAILURE(webView2->remove_ProfileDeleted(m_profileDeletedEventToken));
+            }).Get(), nullptr));
 }
 ```
 
@@ -264,16 +258,11 @@ public DeleteProfile(CoreWebView2Controller controller)
     profile.Delete();
 }
 
-private void AddProfileDeleted(object sender, object e)
+void WebView_CoreWebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e)
 {
     webView.CoreWebView2.ProfileDeleted += CoreWebView2_ProfileDeleted;
 }
 
-private void RemoveProfileDeleted(object sender, object e)
-{
-    webView.CoreWebView2.ProfileDeleted -= CoreWebView2_ProfileDeleted;
-}
-
 private void CoreWebView2_ProfileDeleted(object sender, object e)
 {
     Close();

From e834d1e6741745500117993763956719592e5859 Mon Sep 17 00:00:00 2001
From: Denghui Yu <denghuiyu@microsoft.com>
Date: Thu, 5 Jan 2023 10:26:11 +0800
Subject: [PATCH 4/8] remove staging and use the expected public name

---
 specs/MultiProfile.md | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/specs/MultiProfile.md b/specs/MultiProfile.md
index 86a519d26..313712ad8 100644
--- a/specs/MultiProfile.md
+++ b/specs/MultiProfile.md
@@ -179,8 +179,8 @@ HRESULT AppWindow::DeleteProfile(ICoreWebView2* webView2)
 void AppWindow::RegisterEventHandlers()
 {
     CHECK_FAILURE(m_webView->add_ProfileDeleted(
-        Microsoft::WRL::Callback<ICoreWebView2StagingProfileDeletedEventHandler>(
-            [this](ICoreWebView2Staging9* sender, IUnknown* args)  {
+        Microsoft::WRL::Callback<ICoreWebView2ProfileDeletedEventHandler>(
+            [this](ICoreWebView2_9* sender, IUnknown* args)  {
                 CloseAppWindow();
                 return S_OK;
             }).Get(), nullptr));
@@ -374,7 +374,7 @@ interface ICoreWebView2Profile2 : ICoreWebView2Profile {
 }
 
 [uuid(2765B8BD-7C57-4B76-B8AA-1EC940FE92CC), object, pointer_default(unique)]
-interface ICoreWebView2StagingProfile4 : IUnknown {
+interface ICoreWebView2Profile4 : IUnknown {
   /// After the API is called, the profile will be marked for deletion. 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
@@ -392,12 +392,12 @@ interface ICoreWebView2StagingProfile4 : IUnknown {
 }
 
 [uuid(cc39bea3-f6f8-471b-919f-fa253e2fff03), object, pointer_default(unique)]
-interface ICoreWebView2Staging9 : IUnknown {
+interface ICoreWebView2_9 : IUnknown {
   /// The `ProfileDeleted` event is raised when its corresponding Profile's
   /// Delete API is called. When this event has been raised, continue to use
   /// the profile or its corresponding webviews is an undefined behavior.
   HRESULT add_ProfileDeleted(
-      [in] ICoreWebView2StagingProfileDeletedEventHandler* eventHandler,
+      [in] ICoreWebView2ProfileDeletedEventHandler* eventHandler,
       [out] EventRegistrationToken* token);
 
   /// Remove an event handler previously added with `add_ProfileDeleted`.
@@ -445,7 +445,7 @@ namespace Microsoft.Web.WebView2.Core
         // ...
         CoreWebView2Profile Profile { get; };
 
-        [interface_name("Microsoft.Web.WebView2.Core.ICoreWebView2Staging9")]
+        [interface_name("Microsoft.Web.WebView2.Core.ICoreWebView2_9")]
         {
             event Windows.Foundation.TypedEventHandler<CoreWebView2, Object> ProfileDeleted;
         }
@@ -461,9 +461,9 @@ namespace Microsoft.Web.WebView2.Core
 
         CoreWebView2CookieManager CookieManager { get; };
         
-        [interface_name("Microsoft.Web.WebView2.Core.ICoreWebView2StagingProfile4")]
+        [interface_name("Microsoft.Web.WebView2.Core.ICoreWebView2Profile4")]
         {
-            // ICoreWebView2StagingProfile4 members
+            // ICoreWebView2Profile4 members
             void Delete();
         }
     }

From 70e7a7ffb308f67ee419060128a4e2c668981fe2 Mon Sep 17 00:00:00 2001
From: Denghui Yu <denghuiyu@microsoft.com>
Date: Thu, 5 Jan 2023 18:58:55 +0800
Subject: [PATCH 5/8] fix comments

---
 specs/MultiProfile.md | 103 +++++++++++++++++++++++++++++++++---------
 1 file changed, 81 insertions(+), 22 deletions(-)

diff --git a/specs/MultiProfile.md b/specs/MultiProfile.md
index 313712ad8..6f8e00a5c 100644
--- a/specs/MultiProfile.md
+++ b/specs/MultiProfile.md
@@ -178,10 +178,24 @@ HRESULT AppWindow::DeleteProfile(ICoreWebView2* webView2)
 
 void AppWindow::RegisterEventHandlers()
 {
-    CHECK_FAILURE(m_webView->add_ProfileDeleted(
-        Microsoft::WRL::Callback<ICoreWebView2ProfileDeletedEventHandler>(
-            [this](ICoreWebView2_9* sender, IUnknown* args)  {
-                CloseAppWindow();
+    CHECK_FAILURE(m_webView->add_Closed(
+        Microsoft::WRL::Callback<ICoreWebView2ClosedEventHandler>(
+            [this](ICoreWebView2_20* sender, ICoreWebView2EventArgs* args)
+            {
+                COREWEBVIEW2_CLOSED_REASON reason;
+                CHECK_FAILURE(args->get_Reason(&reason));
+                if (reason == COREWEBVIEW2_CLOSED_REASON::COREWEBVIEW2_CLOSED_REASON_PROFILE_DELETED)
+                {
+                    RunAsync( [this]()
+                    {
+                        std::wstring message =
+                            L"The webview2 has been closed and the reason is profile "
+                            L"has been marked as deleted.";
+                        MessageBox(
+                            m_mainWindow, message.c_str(), L"webview2 closed", MB_OK);
+                        CloseAppWindow();
+                    });
+                }
                 return S_OK;
             }).Get(), nullptr));
 }
@@ -260,12 +274,20 @@ public DeleteProfile(CoreWebView2Controller controller)
 
 void WebView_CoreWebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e)
 {
-    webView.CoreWebView2.ProfileDeleted += CoreWebView2_ProfileDeleted;
+    webView.CoreWebView2.Closed += CoreWebView2_Closed;
 }
 
-private void CoreWebView2_ProfileDeleted(object sender, object e)
+private void CoreWebView2_Closed(object sender, CoreWebView2ClosedEventArgs e)
 {
-    Close();
+    if (e.Reason == CoreWebView2ClosedReason.ProfileDeleted)
+    {
+        this.Dispatcher.InvokeAsync(() =>
+        {
+            String message = "The webview2 has been closed and the reason is profile has been marked as deleted";
+            MessageBox.Show(message);
+            Close();
+        });
+    }
 }
 ```
 
@@ -277,9 +299,13 @@ private void CoreWebView2_ProfileDeleted(object sender, object e)
 interface ICoreWebView2ControllerOptions;
 interface ICoreWebView2Environment5;
 interface ICoreWebView2_7;
+interface ICoreWebView2_9;
 interface ICoreWebView2Profile;
 interface ICoreWebView2Profile2;
 interface ICoreWebView2Profile3;
+interface ICoreWebView2Profile4;
+interface ICoreWebView2ClosedEventHandler;
+interface ICoreWebView2ClosedEventArgs;
 
 /// This interface is used to manage profile options that created by 'CreateCoreWebView2ControllerOptions'.
 [uuid(C2669A3A-03A9-45E9-97EA-03CD55E5DC03), object, pointer_default(unique)]
@@ -376,15 +402,12 @@ interface ICoreWebView2Profile2 : ICoreWebView2Profile {
 [uuid(2765B8BD-7C57-4B76-B8AA-1EC940FE92CC), object, pointer_default(unique)]
 interface ICoreWebView2Profile4 : IUnknown {
   /// After the API is called, the profile will be marked for deletion. The
-  /// local profile’s directory will be tried to delete at browser process
+  /// 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.
-  /// The corresponding user's `ProfileDeleted` event handle function will
-  /// be triggered. After the function is triggered, continuing to use the
-  /// profile or its corresponding webviews is an undefined behavior.
-  /// For each WebView of the same profile, the WebView will be auto closed.
-  /// If the user has registered an event handler for ProfileDeleted event,
-  /// the event handle will be invoked before WebView is closed.
+  /// The corresponding webview2s will be auto closed and its Closed event
+  /// handle function will be triggered with the reason is 
+  /// COREWEBVIEW2_CLOSED_REASON.COREWEBVIEW2_CLOSED_REASON_PROFILE_DELETED.
   /// 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).
@@ -393,17 +416,43 @@ interface ICoreWebView2Profile4 : IUnknown {
 
 [uuid(cc39bea3-f6f8-471b-919f-fa253e2fff03), object, pointer_default(unique)]
 interface ICoreWebView2_9 : IUnknown {
-  /// The `ProfileDeleted` event is raised when its corresponding Profile's
-  /// Delete API is called. When this event has been raised, continue to use
-  /// the profile or its corresponding webviews is an undefined behavior.
-  HRESULT add_ProfileDeleted(
-      [in] ICoreWebView2ProfileDeletedEventHandler* eventHandler,
+  /// Add an event handler for the `Closed` event. `Closed` enent handle runs
+  /// when the webview2 is closed passivly. When this event is raised, the 
+  /// webview2 cannot be used anymore.
+  HRESULT add_Closed(
+      [in] ICoreWebView2ClosedEventHandler* eventHandler,
       [out] EventRegistrationToken* token);
 
-  /// Remove an event handler previously added with `add_ProfileDeleted`.
-  HRESULT remove_ProfileDeleted(
+  /// Remove an event handler previously added with `add_Closed`.
+  HRESULT remove_Closed(
       [in] EventRegistrationToken token);
 }
+
+/// The reason of webview2 closed.
+[v1_enum]
+typedef enum COREWEBVIEW2_CLOSED_REASON {
+  /// Indicates that the reason of webview2 closed is its corresponding 
+  /// Profile has been or marked as deleted.
+  COREWEBVIEW2_CLOSED_REASON_PROFILE_DELETED,
+} COREWEBVIEW2_CLOSED_REASON;
+
+/// Receives the webview2 `Closed` event.
+[uuid(970BB7E0-A257-4A76-BE15-5BDEB00B5673), object, pointer_default(unique)]
+interface ICoreWebView2ClosedEventHandler : IUnknown {
+  /// Called to provide the implementer with the event args for the
+  /// corresponding event.
+  HRESULT Invoke([in] ICoreWebView2_20* sender,
+      [in] ICoreWebView2ClosedEventArgs* args);
+}
+
+/// This is the event args interface for webview2 `Closed` event handle.
+[uuid(0e1730c1-03df-4ad2-b847-be4d63adf777), object, pointer_default(unique)]
+interface ICoreWebView2ClosedEventArgs : IUnknown {
+  /// webview2 closed reason.
+  [propget] HRESULT Reason([out, retval]
+      COREWEBVIEW2_CLOSED_REASON* value);
+}
+
 ```
 
 ## .NET and WinRT
@@ -447,9 +496,19 @@ namespace Microsoft.Web.WebView2.Core
 
         [interface_name("Microsoft.Web.WebView2.Core.ICoreWebView2_9")]
         {
-            event Windows.Foundation.TypedEventHandler<CoreWebView2, Object> ProfileDeleted;
+            event Windows.Foundation.TypedEventHandler<CoreWebView2, CoreWebView2ClosedEventArgs> Closed;
         }
     }
+
+    enum CoreWebView2ClosedReason
+    {
+        ProfileDeleted = 0,
+    };
+
+    runtimeclass CoreWebView2ClosedEventArgs
+    {
+        CoreWebView2ClosedReason Reason { get; };
+    }
     
     runtimeclass CoreWebView2Profile
     {

From 4e428e225ef0db1cdf07ed5bb622a26acda131c6 Mon Sep 17 00:00:00 2001
From: Denghui Yu <denghuiyu@microsoft.com>
Date: Mon, 16 Jan 2023 18:04:43 +0800
Subject: [PATCH 6/8] comments fix

---
 specs/MultiProfile.md | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/specs/MultiProfile.md b/specs/MultiProfile.md
index 6f8e00a5c..b99a4804e 100644
--- a/specs/MultiProfile.md
+++ b/specs/MultiProfile.md
@@ -417,8 +417,9 @@ interface ICoreWebView2Profile4 : IUnknown {
 [uuid(cc39bea3-f6f8-471b-919f-fa253e2fff03), object, pointer_default(unique)]
 interface ICoreWebView2_9 : IUnknown {
   /// Add an event handler for the `Closed` event. `Closed` enent handle runs
-  /// when the webview2 is closed passivly. When this event is raised, the 
-  /// webview2 cannot be used anymore.
+  /// when the webview2 is closed due to the reason that described in the
+  /// COREWEBVIEW2_CLOSED_REASON enumeration. When this event is raised, the
+  /// webview2 moves to the Closed state, and cannot be used anymore.
   HRESULT add_Closed(
       [in] ICoreWebView2ClosedEventHandler* eventHandler,
       [out] EventRegistrationToken* token);

From 33cda74a7a054b5dd1f56a8e139fb7ca5a0cbe20 Mon Sep 17 00:00:00 2001
From: Denghui Yu <denghuiyu@microsoft.com>
Date: Fri, 3 Feb 2023 12:27:38 +0800
Subject: [PATCH 7/8] add spec of 'IsClosed' and Enum value of 'Closed' event

---
 specs/MultiProfile.md | 137 +++++++++++++++++++++++++++++++++++-------
 1 file changed, 115 insertions(+), 22 deletions(-)

diff --git a/specs/MultiProfile.md b/specs/MultiProfile.md
index b99a4804e..802a58226 100644
--- a/specs/MultiProfile.md
+++ b/specs/MultiProfile.md
@@ -178,26 +178,63 @@ HRESULT AppWindow::DeleteProfile(ICoreWebView2* webView2)
 
 void AppWindow::RegisterEventHandlers()
 {
-    CHECK_FAILURE(m_webView->add_Closed(
+    BOOL isWebview2Closed = FALSE;
+    CHECK_FAILURE(webView2->get_IsClosed(&isWebview2Closed));
+    if (!isWebview2Closed) {
+        CHECK_FAILURE(m_webView->add_Closed(
         Microsoft::WRL::Callback<ICoreWebView2ClosedEventHandler>(
             [this](ICoreWebView2_20* sender, ICoreWebView2EventArgs* args)
             {
                 COREWEBVIEW2_CLOSED_REASON reason;
                 CHECK_FAILURE(args->get_Reason(&reason));
-                if (reason == COREWEBVIEW2_CLOSED_REASON::COREWEBVIEW2_CLOSED_REASON_PROFILE_DELETED)
+                std::wstring message;
+                switch (reason)
                 {
-                    RunAsync( [this]()
+                    case COREWEBVIEW2_CLOSED_REASON::COREWEBVIEW2_CLOSED_REASON_SHUTDOWN:
                     {
-                        std::wstring message =
-                            L"The webview2 has been closed and the reason is profile "
-                            L"has been marked as deleted.";
-                        MessageBox(
-                            m_mainWindow, message.c_str(), L"webview2 closed", MB_OK);
-                        CloseAppWindow();
-                    });
+                        message = L"The CoreWebView2 has closed because the corresponding "
+                                  L"CoreWebView2Controller had its Close method called either "
+                                  L"explicitly or implicitly.";
+                        break;
+                    }
+                    case COREWEBVIEW2_CLOSED_REASON::
+                        COREWEBVIEW2_CLOSED_REASON_BROWSER_PROCESS_FAILURE:
+                    {
+                        message = L"The CoreWebView2 has closed because its browser process "
+                                  L"crashed. The Closed event will be raised after the "
+                                  L"ProcessFailed event is raised.";
+                        break;
+                    }
+                    case COREWEBVIEW2_CLOSED_REASON::
+                        COREWEBVIEW2_CLOSED_REASON_BROWSER_PROCESS_EXITED:
+                    {
+                        message = L"The CoreWebView2 has closed because its browser process has "
+                                  L"exited.";
+                        break;
+                    }
+                    case COREWEBVIEW2_CLOSED_REASON::
+                        COREWEBVIEW2_CLOSED_REASON_PARENT_WINDOW_CLOSED:
+                    {
+                        message = L"The CoreWebView2 has closed because its parent window was "
+                                  L"closed.";
+                        break;
+                    }
+                    case COREWEBVIEW2_CLOSED_REASON::COREWEBVIEW2_CLOSED_REASON_PROFILE_DELETED:
+                    {
+                        message = L"The CoreWebView2 has closed because its corresponding "
+                                  L"Profile has been or marked as deleted.";
+                        break;
+                    }
                 }
+                RunAsync([this, message]()
+                {
+                    MessageBox(
+                        m_mainWindow, message.c_str(), L"webview2 closed", MB_OK);
+                    CloseAppWindow();
+                });
                 return S_OK;
             }).Get(), nullptr));
+    }
 }
 ```
 
@@ -274,20 +311,48 @@ public DeleteProfile(CoreWebView2Controller controller)
 
 void WebView_CoreWebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e)
 {
-    webView.CoreWebView2.Closed += CoreWebView2_Closed;
+    if (!webView.IsClosed) {
+        webView.CoreWebView2.Closed += CoreWebView2_Closed;
+    }
 }
 
 private void CoreWebView2_Closed(object sender, CoreWebView2ClosedEventArgs e)
 {
-    if (e.Reason == CoreWebView2ClosedReason.ProfileDeleted)
+    String message;
+    switch (e.Reason)
     {
-        this.Dispatcher.InvokeAsync(() =>
+        case CoreWebView2ClosedReason.ShutDown:
+        {
+            message = "The CoreWebView2 has closed because the corresponding CoreWebView2Controller had its Close method called either explicitly or implicitly."
+            break;
+        }
+        case CoreWebView2ClosedReason.BrowserProcessFailure:
+        {
+            message = "The CoreWebView2 has closed because its browser process crashed. The Closed event will be raised after the ProcessFailed event is raised."
+            break;
+        }
+        case CoreWebView2ClosedReason.BrowserProcessExited:
+        {
+            message = "The CoreWebView2 has closed because its browser process has exited."
+            break;
+        }
+        case CoreWebView2ClosedReason.ParentWindowClosed:
+        {
+            message = "The CoreWebView2 has closed because its parent window was closed."
+            break;
+        }
+        case CoreWebView2ClosedReason.ProfileDeleted:
         {
-            String message = "The webview2 has been closed and the reason is profile has been marked as deleted";
-            MessageBox.Show(message);
-            Close();
-        });
+            message = "The CoreWebView2 has closed because its corresponding Profile has been or marked as deleted."
+            break;
+        }
     }
+
+    this.Dispatcher.InvokeAsync(() =>
+    {
+        MessageBox.Show(message);
+        Close();
+    });
 }
 ```
 
@@ -427,14 +492,33 @@ interface ICoreWebView2_9 : IUnknown {
   /// Remove an event handler previously added with `add_Closed`.
   HRESULT remove_Closed(
       [in] EventRegistrationToken token);
+
+  /// `TRUE` if WebView2 has moved to the Closed state. Use `add_Closed` API
+  /// to get the specific closed reason. For more information see `add_Closed`.
+  [propget] HRESULT IsClosed([out, retval] BOOL* value);
 }
 
 /// The reason of webview2 closed.
 [v1_enum]
 typedef enum COREWEBVIEW2_CLOSED_REASON {
-  /// Indicates that the reason of webview2 closed is its corresponding 
-  /// Profile has been or marked as deleted.
-  COREWEBVIEW2_CLOSED_REASON_PROFILE_DELETED,
+  /// The CoreWebView2 has closed because the corresponding
+  /// CoreWebView2Controller had its Close method called either explicitly or
+  /// implicitly.
+  COREWEBVIEW2_CLOSED_REASON_SHUTDOWN,
+  
+  /// The CoreWebView2 has closed because its browser process crashed.
+  /// The Closed event will be raised after the ProcessFailed event is raised.
+  COREWEBVIEW2_CLOSED_REASON_BROWSER_PROCESS_FAILURE,
+
+  /// The CoreWebView2 has closed because its browser process has exited.
+  COREWEBVIEW2_CLOSED_REASON_BROWSER_PROCESS_EXITED,
+  
+  /// The CoreWebView2 has closed because its parent window was closed.
+  COREWEBVIEW2_CLOSED_REASON_PARENT_WINDOW_CLOSED,
+
+  /// The CoreWebView2 has closed because its corresponding Profile has been or
+  /// marked as deleted.
+  COREWEBVIEW2_CLOSED_REASON_PROFILE_DELETED
 } COREWEBVIEW2_CLOSED_REASON;
 
 /// Receives the webview2 `Closed` event.
@@ -489,7 +573,12 @@ namespace Microsoft.Web.WebView2.Core
             CoreWebView2ControllerWindowReference ParentWindow,
             CoreWebView2ControllerOptions options);
     }
-    
+
+    runtimeclass WebView2
+    {
+        bool IsClosed { get; };
+    }
+
     runtimeclass CoreWebView2
     {
         // ...
@@ -503,7 +592,11 @@ namespace Microsoft.Web.WebView2.Core
 
     enum CoreWebView2ClosedReason
     {
-        ProfileDeleted = 0,
+        ShutDown,
+        BrowserProcessFailure,
+        BrowserProcessExited,
+        ParentWindowClosed,
+        ProfileDeleted,
     };
 
     runtimeclass CoreWebView2ClosedEventArgs

From 767d420d19c32ec9f7544861bb543ad716242fe0 Mon Sep 17 00:00:00 2001
From: Denghui Yu <denghuiyu@microsoft.com>
Date: Tue, 7 Feb 2023 17:17:30 +0800
Subject: [PATCH 8/8] remove other enum value and add them in latter PR

---
 specs/MultiProfile.md | 68 -------------------------------------------
 1 file changed, 68 deletions(-)

diff --git a/specs/MultiProfile.md b/specs/MultiProfile.md
index 802a58226..7c79f61b4 100644
--- a/specs/MultiProfile.md
+++ b/specs/MultiProfile.md
@@ -190,35 +190,6 @@ void AppWindow::RegisterEventHandlers()
                 std::wstring message;
                 switch (reason)
                 {
-                    case COREWEBVIEW2_CLOSED_REASON::COREWEBVIEW2_CLOSED_REASON_SHUTDOWN:
-                    {
-                        message = L"The CoreWebView2 has closed because the corresponding "
-                                  L"CoreWebView2Controller had its Close method called either "
-                                  L"explicitly or implicitly.";
-                        break;
-                    }
-                    case COREWEBVIEW2_CLOSED_REASON::
-                        COREWEBVIEW2_CLOSED_REASON_BROWSER_PROCESS_FAILURE:
-                    {
-                        message = L"The CoreWebView2 has closed because its browser process "
-                                  L"crashed. The Closed event will be raised after the "
-                                  L"ProcessFailed event is raised.";
-                        break;
-                    }
-                    case COREWEBVIEW2_CLOSED_REASON::
-                        COREWEBVIEW2_CLOSED_REASON_BROWSER_PROCESS_EXITED:
-                    {
-                        message = L"The CoreWebView2 has closed because its browser process has "
-                                  L"exited.";
-                        break;
-                    }
-                    case COREWEBVIEW2_CLOSED_REASON::
-                        COREWEBVIEW2_CLOSED_REASON_PARENT_WINDOW_CLOSED:
-                    {
-                        message = L"The CoreWebView2 has closed because its parent window was "
-                                  L"closed.";
-                        break;
-                    }
                     case COREWEBVIEW2_CLOSED_REASON::COREWEBVIEW2_CLOSED_REASON_PROFILE_DELETED:
                     {
                         message = L"The CoreWebView2 has closed because its corresponding "
@@ -321,26 +292,6 @@ private void CoreWebView2_Closed(object sender, CoreWebView2ClosedEventArgs e)
     String message;
     switch (e.Reason)
     {
-        case CoreWebView2ClosedReason.ShutDown:
-        {
-            message = "The CoreWebView2 has closed because the corresponding CoreWebView2Controller had its Close method called either explicitly or implicitly."
-            break;
-        }
-        case CoreWebView2ClosedReason.BrowserProcessFailure:
-        {
-            message = "The CoreWebView2 has closed because its browser process crashed. The Closed event will be raised after the ProcessFailed event is raised."
-            break;
-        }
-        case CoreWebView2ClosedReason.BrowserProcessExited:
-        {
-            message = "The CoreWebView2 has closed because its browser process has exited."
-            break;
-        }
-        case CoreWebView2ClosedReason.ParentWindowClosed:
-        {
-            message = "The CoreWebView2 has closed because its parent window was closed."
-            break;
-        }
         case CoreWebView2ClosedReason.ProfileDeleted:
         {
             message = "The CoreWebView2 has closed because its corresponding Profile has been or marked as deleted."
@@ -501,21 +452,6 @@ interface ICoreWebView2_9 : IUnknown {
 /// The reason of webview2 closed.
 [v1_enum]
 typedef enum COREWEBVIEW2_CLOSED_REASON {
-  /// The CoreWebView2 has closed because the corresponding
-  /// CoreWebView2Controller had its Close method called either explicitly or
-  /// implicitly.
-  COREWEBVIEW2_CLOSED_REASON_SHUTDOWN,
-  
-  /// The CoreWebView2 has closed because its browser process crashed.
-  /// The Closed event will be raised after the ProcessFailed event is raised.
-  COREWEBVIEW2_CLOSED_REASON_BROWSER_PROCESS_FAILURE,
-
-  /// The CoreWebView2 has closed because its browser process has exited.
-  COREWEBVIEW2_CLOSED_REASON_BROWSER_PROCESS_EXITED,
-  
-  /// The CoreWebView2 has closed because its parent window was closed.
-  COREWEBVIEW2_CLOSED_REASON_PARENT_WINDOW_CLOSED,
-
   /// The CoreWebView2 has closed because its corresponding Profile has been or
   /// marked as deleted.
   COREWEBVIEW2_CLOSED_REASON_PROFILE_DELETED
@@ -592,10 +528,6 @@ namespace Microsoft.Web.WebView2.Core
 
     enum CoreWebView2ClosedReason
     {
-        ShutDown,
-        BrowserProcessFailure,
-        BrowserProcessExited,
-        ParentWindowClosed,
         ProfileDeleted,
     };