profile
viewpoint
If you are wondering where the data of this site comes from, please visit https://api.github.com/users/david-risney/events. GitMemory does not store any data, but only uses NGINX to cache data for a period of time. The idea behind GitMemory is simply to give users a better reading experience.
David Risney david-risney @Microsoft Redmond, WA http://deletethis.net/dave/ Professionally I work on Microsoft Edge WebView2. Personally I work on my random projects here on GitHub.

david-risney/CSP-Fiddler-Extension 87

Content Security Policy rule collector extension for Fiddler

david-risney/AppxUtilities 22

Fill in functionality gaps for Windows Store packages and processes utlities

david-risney/browser-strace 4

Logging DOM calls in and DOM callbacks out in the browser - like strace but for the browser.

david-risney/CodeGraph 2

Auto-generate code samples for connecting arbitrary DOM APIs.

david-risney/InteropWebViewBrowser 2

Windows.Web.UI.Interop.WebViewControl based simple browser

david-risney/appImageSizer 1

Given your app's logo, produces the myriad of images at various resolutions required by your app platform.

david-risney/EncodeOMatic 1

Web app for encoding and decoding

david-risney/MinecraftBedrockEditionBehaviorPacksEnvironment 1

Scripts to help build Minecraft Bedrock Edition behavior packs

david-risney/ObjectToHtml 1

Programmatically create HTML in browser environments with a simple, object based, and concise notation that makes it easy to avoid injection security bugs.

Pull request review commentMicrosoftEdge/WebView2Feedback

API Review: multiple profile support

+API spec for multiple profile support+===++# Background++Previously, all WebView2s can only use one fixed Edge profile in the browser process, which is+normally the **Default** profile or the profile specified by the **--profile-directory** command+line switch. It means different WebView2s share a single profile directory on disk for data storage,+which might bring security concerns over cookies, autofill data, and password management etc.. Also,+they might also interfere with each other in terms of user preference settings.++Although you can make your WebView2s use different user data directories to achieve data separation,+in such way you'll have to be running multiple browser instances (each including a browser process+and a bunch of child processes), which means much more consumption for system resources including+memory, CPU footprint, disk space etc. so it is not desirable.++With all above, we're adding these new APIs to support multiple profiles, so that you can have+multiple WebView2s running with separate profiles under a single user data directory (i.e. a single+browser instance at runtime), which means separate cookies, user preference settings, and various+data storage etc., to help you build a more wonderful experience for your application.++# Examples++## Win32 C++++### Provide options to create WebView2 with a specific profile++```cpp+HRESULT AppWindow::CreateControllerWithOptions()+{+    auto webViewEnvironment4 =+        m_webViewEnvironment.try_query<ICoreWebView2Environment4>();+    if (!webViewEnvironment4)+    {+        FeatureNotAvailable();+        return S_OK;+    }++    Microsoft::WRL::ComPtr<ICoreWebView2ControllerOptions> options;+    HRESULT hr = webViewEnvironment4->CreateCoreWebView2ControllerOptions(+        m_webviewOption.profile.c_str(), m_webviewOption.isInPrivate, options.GetAddressOf());+    if (hr == E_INVALIDARG)+    {+        ShowFailure(hr, L"Unable to create WebView2 due to an invalid profile name.");+        CloseAppWindow();+        return S_OK;+    }+    CHECK_FAILURE(hr);++#ifdef USE_WEBVIEW2_WIN10+    if (m_dcompDevice || m_wincompCompositor)+#else+    if (m_dcompDevice)+#endif+    {+        CHECK_FAILURE(webViewEnvironment4->CreateCoreWebView2CompositionControllerWithOptions(+            m_mainWindow, options.Get(),+            Callback<ICoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler>(+                [this](+                    HRESULT result,+                    ICoreWebView2CompositionController* compositionController) -> HRESULT {+                    auto controller =+                        wil::com_ptr<ICoreWebView2CompositionController>(compositionController)+                            .query<ICoreWebView2Controller>();+                    return OnCreateCoreWebView2ControllerCompleted(result, controller.get());+                })+                .Get()));+    }+    else+    {+        CHECK_FAILURE(webViewEnvironment4->CreateCoreWebView2ControllerWithOptions(+            m_mainWindow, options.Get(),+            Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(+                this, &AppWindow::OnCreateCoreWebView2ControllerCompleted)+                .Get()));+    }++    return S_OK;+}+```++### Access the profile property of WebView2++```cpp+HRESULT AppWindow::OnCreateCoreWebView2ControllerCompleted(HRESULT result, ICoreWebView2Controller* controller)+{+    // ...++    m_controller = controller;+    +    // Gets the webview object from controller.+    wil::com_ptr<ICoreWebView2> coreWebView2;+    CHECK_FAILURE(m_controller->get_CoreWebView2(&coreWebView2));++    auto webview7 = coreWebView2.try_query<ICoreWebView2_7>();+    if (webview7)+    {+        // Gets the profile property of webview.+        wil::com_ptr<ICoreWebView2Profile> profile;+        CHECK_FAILURE(webview7->get_Profile(&profile));++        // Accesses the profile object.+        BOOL inPrivateModeEnabled = FALSE;+        CHECK_FAILURE(profile->get_IsInPrivateModeEnabled(&inPrivateModeEnabled));+        wil::unique_cotaskmem_string profile_path;+        CHECK_FAILURE(profile->get_ProfilePath(&profile_path));+        std::wstring str(profile_path.get());+        m_profileDirName = str.substr(str.find_last_of(L'\\') + 1);+        +        // update window title with m_profileDirName+        UpdateAppTitle();++        // update window icon+        SetAppIcon(inPrivate);        +    }+  +    // ...+}+```+## .NET and WinRT++### Create WebView2 with a specific profile, then access the profile property of WebView2++```csharp+CoreWebView2Environment _webViewEnvironment;+public CreateWebView2ControllerWithOptions(IntPtr parentHWND, string profileName, bool isInPrivate)+{+    CoreWebView2ControllerOptions options = _webViewEnvironment.CreateCoreWebView2ControllerOptions(profileName, isInPrivate);+    CoreWebView2Controller webView2Controller = await _webViewEnvironment.CreateCoreWebView2ControllerWithOptionsAsync(parentHWND, options);+    string profilePath = webView2Controller.CoreWebView2.Profile.ProfilePath;+    string profileDirName = profilePath.Substring(profilePath.LastIndexOf('\\') + 1);+    bool inPrivate = webView2Controller.CoreWebView2.Profile.IsInPrivateModeEnabled;++    // update window title with profileDirName+    UpdateAppTitle();++    // update window icon+    SetAppIcon(inPrivate);+}+```++# API Details++## Win32 C++++```IDL+interface ICoreWebView2ControllerOptions;+interface ICoreWebView2Environment5;+interface ICoreWebView2_7;+interface ICoreWebView2Profile;++[uuid(C2669A3A-03A9-45E9-97EA-03CD55E5DC03), object, pointer_default(unique)]+interface ICoreWebView2ControllerOptions : IUnknown {

TLDR: In the long term yes I'd like to make our IDL3 the source of truth and from it generate our .NET & COM APIs or replace those with just WinRT

This is our COM IDL(1) style IDL file to define our COM APIs usable down to Win7. Because it goes to Win7 where we don't have various aspects of WinRT available the conventions of the COM API are similar to but are not the same as the WinRT ABI. We later added WinRT support in part by generating a MIDL3 from our COM IDL in a tool that understands how to translate between our conventions and WinRT. In the future I'd like to make MIDL3 the source of truth from which we generate our COM IDL and then after that if usage drops far enough deprecating in favor of COM ABI WinRT.

leonhsl

comment created time in 2 days

Pull request review commentMicrosoftEdge/WebView2Feedback

API Review: multiple profile support

+API spec for multiple profile support+===++# Background++Previously, all WebView2s can only use one fixed Edge profile in the browser process, which is+normally the **Default** profile or the profile specified by the **--profile-directory** command
normally the **Default** profile by not specifying a profile path, or the profile specified by the **--profile-directory** command
leonhsl

comment created time in 2 days

Pull request review commentMicrosoftEdge/WebView2Feedback

API Review: multiple profile support

+API spec for multiple profile support+===++# Background++Previously, all WebView2s can only use one fixed Edge profile in the browser process, which is+normally the **Default** profile or the profile specified by the **--profile-directory** command+line switch. It means different WebView2s share a single profile directory on disk for data storage,+which might bring security concerns over cookies, autofill data, and password management etc.. Also,+they might also interfere with each other in terms of user preference settings.++Although you can make your WebView2s use different user data directories to achieve data separation,+in such way you'll have to be running multiple browser instances (each including a browser process+and a bunch of child processes), which means much more consumption for system resources including+memory, CPU footprint, disk space etc. so it is not desirable.++With all above, we're adding these new APIs to support multiple profiles, so that you can have+multiple WebView2s running with separate profiles under a single user data directory (i.e. a single+browser instance at runtime), which means separate cookies, user preference settings, and various+data storage etc., to help you build a more wonderful experience for your application.++# Examples++## Win32 C++++### Provide options to create WebView2 with a specific profile++```cpp+HRESULT AppWindow::CreateControllerWithOptions()+{+    auto webViewEnvironment4 =+        m_webViewEnvironment.try_query<ICoreWebView2Environment4>();+    if (!webViewEnvironment4)+    {+        FeatureNotAvailable();+        return S_OK;+    }++    Microsoft::WRL::ComPtr<ICoreWebView2ControllerOptions> options;+    HRESULT hr = webViewEnvironment4->CreateCoreWebView2ControllerOptions(+        m_webviewOption.profile.c_str(), m_webviewOption.isInPrivate, options.GetAddressOf());

Great question: yes indirectly. Profiles are sub folders under the CoreWebView2's user data folder. The host app optionally provides the path for the user data folder when creating the CoreWebView2 environment. WinUI doesn't provide a way for the end dev to set the user data folder right now but there's a scenario for it on them.

leonhsl

comment created time in 2 days

PullRequestReviewEvent
PullRequestReviewEvent

Pull request review commentMicrosoftEdge/WebView2Feedback

API Review: multiple profile support

+API spec for multiple profile support+===++# Background++Previously, all WebView2s can only use one fixed Edge profile in the browser process, which is+normally the **Default** profile or the profile specified by the **--profile-directory** command+line switch. It means different WebView2s share a single profile directory on disk for data storage,+which might bring security concerns over cookies, autofill data, and password management etc.. Also,+they might also interfere with each other in terms of user preference settings.++Although you can make your WebView2s use different user data directories to achieve data separation,+in such way you'll have to be running multiple browser instances (each including a browser process+and a bunch of child processes), which means much more consumption for system resources including+memory, CPU footprint, disk space etc. so it is not desirable.++With all above, we're adding these new APIs to support multiple profiles, so that you can have+multiple WebView2s running with separate profiles under a single user data directory (i.e. a single+browser instance at runtime), which means separate cookies, user preference settings, and various+data storage etc., to help you build a more wonderful experience for your application.++# Examples++## Win32 C++++### Provide options to create WebView2 with a specific profile++```cpp+HRESULT AppWindow::CreateControllerWithOptions()+{+    auto webViewEnvironment4 =+        m_webViewEnvironment.try_query<ICoreWebView2Environment4>();+    if (!webViewEnvironment4)+    {+        FeatureNotAvailable();+        return S_OK;+    }++    Microsoft::WRL::ComPtr<ICoreWebView2ControllerOptions> options;+    HRESULT hr = webViewEnvironment4->CreateCoreWebView2ControllerOptions(+        m_webviewOption.profile.c_str(), m_webviewOption.isInPrivate, options.GetAddressOf());+    if (hr == E_INVALIDARG)+    {+        ShowFailure(hr, L"Unable to create WebView2 due to an invalid profile name.");+        CloseAppWindow();+        return S_OK;+    }+    CHECK_FAILURE(hr);+

Must document. Its in CreateCoreWebView2ControllerWithOptions creates/opens the profile.

leonhsl

comment created time in 2 days

Pull request review commentMicrosoftEdge/WebView2Feedback

API Review: multiple profile support

+API spec for multiple profile support+===++# Background++Previously, all WebView2s can only use one fixed Edge profile in the browser process, which is+normally the **Default** profile or the profile specified by the **--profile-directory** command+line switch. It means different WebView2s share a single profile directory on disk for data storage,+which might bring security concerns over cookies, autofill data, and password management etc.. Also,+they might also interfere with each other in terms of user preference settings.++Although you can make your WebView2s use different user data directories to achieve data separation,+in such way you'll have to be running multiple browser instances (each including a browser process+and a bunch of child processes), which means much more consumption for system resources including+memory, CPU footprint, disk space etc. so it is not desirable.++With all above, we're adding these new APIs to support multiple profiles, so that you can have+multiple WebView2s running with separate profiles under a single user data directory (i.e. a single+browser instance at runtime), which means separate cookies, user preference settings, and various+data storage etc., to help you build a more wonderful experience for your application.++# Examples++## Win32 C++++### Provide options to create WebView2 with a specific profile++```cpp+HRESULT AppWindow::CreateControllerWithOptions()+{+    auto webViewEnvironment4 =+        m_webViewEnvironment.try_query<ICoreWebView2Environment4>();+    if (!webViewEnvironment4)+    {+        FeatureNotAvailable();+        return S_OK;+    }++    Microsoft::WRL::ComPtr<ICoreWebView2ControllerOptions> options;+    HRESULT hr = webViewEnvironment4->CreateCoreWebView2ControllerOptions(+        m_webviewOption.profile.c_str(), m_webviewOption.isInPrivate, options.GetAddressOf());

Must investigate and document this.

Two controllers at the same time with same profile but one is InPrivate and one is not expect this works since it works in browser. In second case I'm guessing that there's an initialized but otherwise empty profile after the controller closes.

leonhsl

comment created time in 2 days

Pull request review commentMicrosoftEdge/WebView2Feedback

API Review: multiple profile support

+API spec for multiple profile support+===++# Background++Previously, all WebView2s can only use one fixed Edge profile in the browser process, which is+normally the **Default** profile or the profile specified by the **--profile-directory** command+line switch. It means different WebView2s share a single profile directory on disk for data storage,+which might bring security concerns over cookies, autofill data, and password management etc.. Also,+they might also interfere with each other in terms of user preference settings.++Although you can make your WebView2s use different user data directories to achieve data separation,+in such way you'll have to be running multiple browser instances (each including a browser process+and a bunch of child processes), which means much more consumption for system resources including+memory, CPU footprint, disk space etc. so it is not desirable.++With all above, we're adding these new APIs to support multiple profiles, so that you can have+multiple WebView2s running with separate profiles under a single user data directory (i.e. a single+browser instance at runtime), which means separate cookies, user preference settings, and various+data storage etc., to help you build a more wonderful experience for your application.++# Examples++## Win32 C++++### Provide options to create WebView2 with a specific profile++```cpp+HRESULT AppWindow::CreateControllerWithOptions()+{+    auto webViewEnvironment4 =+        m_webViewEnvironment.try_query<ICoreWebView2Environment4>();+    if (!webViewEnvironment4)+    {+        FeatureNotAvailable();+        return S_OK;+    }++    Microsoft::WRL::ComPtr<ICoreWebView2ControllerOptions> options;+    HRESULT hr = webViewEnvironment4->CreateCoreWebView2ControllerOptions(+        m_webviewOption.profile.c_str(), m_webviewOption.isInPrivate, options.GetAddressOf());+    if (hr == E_INVALIDARG)+    {+        ShowFailure(hr, L"Unable to create WebView2 due to an invalid profile name.");+        CloseAppWindow();+        return S_OK;+    }+    CHECK_FAILURE(hr);++#ifdef USE_WEBVIEW2_WIN10+    if (m_dcompDevice || m_wincompCompositor)+#else+    if (m_dcompDevice)+#endif+    {+        CHECK_FAILURE(webViewEnvironment4->CreateCoreWebView2CompositionControllerWithOptions(+            m_mainWindow, options.Get(),+            Callback<ICoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler>(+                [this](+                    HRESULT result,+                    ICoreWebView2CompositionController* compositionController) -> HRESULT {+                    auto controller =+                        wil::com_ptr<ICoreWebView2CompositionController>(compositionController)+                            .query<ICoreWebView2Controller>();+                    return OnCreateCoreWebView2ControllerCompleted(result, controller.get());+                })+                .Get()));+    }+    else+    {+        CHECK_FAILURE(webViewEnvironment4->CreateCoreWebView2ControllerWithOptions(+            m_mainWindow, options.Get(),+            Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(+                this, &AppWindow::OnCreateCoreWebView2ControllerCompleted)+                .Get()));+    }++    return S_OK;+}+```++### Access the profile property of WebView2++```cpp+HRESULT AppWindow::OnCreateCoreWebView2ControllerCompleted(HRESULT result, ICoreWebView2Controller* controller)+{+    // ...++    m_controller = controller;+    +    // Gets the webview object from controller.+    wil::com_ptr<ICoreWebView2> coreWebView2;+    CHECK_FAILURE(m_controller->get_CoreWebView2(&coreWebView2));++    auto webview7 = coreWebView2.try_query<ICoreWebView2_7>();+    if (webview7)+    {+        // Gets the profile property of webview.+        wil::com_ptr<ICoreWebView2Profile> profile;+        CHECK_FAILURE(webview7->get_Profile(&profile));++        // Accesses the profile object.+        BOOL inPrivateModeEnabled = FALSE;+        CHECK_FAILURE(profile->get_IsInPrivateModeEnabled(&inPrivateModeEnabled));+        wil::unique_cotaskmem_string profile_path;+        CHECK_FAILURE(profile->get_ProfilePath(&profile_path));+        std::wstring str(profile_path.get());+        m_profileDirName = str.substr(str.find_last_of(L'\\') + 1);

Not strictly necessary but for education or completeness let's use this to normalize the path for us.

leonhsl

comment created time in 2 days

Pull request review commentMicrosoftEdge/WebView2Feedback

API Review: multiple profile support

+API spec for multiple profile support+===++# Background++Previously, all WebView2s can only use one fixed Edge profile in the browser process, which is+normally the **Default** profile or the profile specified by the **--profile-directory** command+line switch. It means different WebView2s share a single profile directory on disk for data storage,+which might bring security concerns over cookies, autofill data, and password management etc.. Also,+they might also interfere with each other in terms of user preference settings.++Although you can make your WebView2s use different user data directories to achieve data separation,+in such way you'll have to be running multiple browser instances (each including a browser process+and a bunch of child processes), which means much more consumption for system resources including+memory, CPU footprint, disk space etc. so it is not desirable.++With all above, we're adding these new APIs to support multiple profiles, so that you can have+multiple WebView2s running with separate profiles under a single user data directory (i.e. a single+browser instance at runtime), which means separate cookies, user preference settings, and various+data storage etc., to help you build a more wonderful experience for your application.++# Examples++## Win32 C++++### Provide options to create WebView2 with a specific profile++```cpp+HRESULT AppWindow::CreateControllerWithOptions()+{+    auto webViewEnvironment4 =+        m_webViewEnvironment.try_query<ICoreWebView2Environment4>();+    if (!webViewEnvironment4)+    {+        FeatureNotAvailable();+        return S_OK;+    }++    Microsoft::WRL::ComPtr<ICoreWebView2ControllerOptions> options;+    HRESULT hr = webViewEnvironment4->CreateCoreWebView2ControllerOptions(+        m_webviewOption.profile.c_str(), m_webviewOption.isInPrivate, options.GetAddressOf());

Correct. Document better how inPrivate interacts with profiles.

leonhsl

comment created time in 2 days

Pull request review commentMicrosoftEdge/WebView2Feedback

API Review: multiple profile support

+API spec for multiple profile support+===++# Background++Previously, all WebView2s can only use one fixed Edge profile in the browser process, which is+normally the **Default** profile or the profile specified by the **--profile-directory** command+line switch. It means different WebView2s share a single profile directory on disk for data storage,+which might bring security concerns over cookies, autofill data, and password management etc.. Also,+they might also interfere with each other in terms of user preference settings.++Although you can make your WebView2s use different user data directories to achieve data separation,+in such way you'll have to be running multiple browser instances (each including a browser process+and a bunch of child processes), which means much more consumption for system resources including+memory, CPU footprint, disk space etc. so it is not desirable.++With all above, we're adding these new APIs to support multiple profiles, so that you can have+multiple WebView2s running with separate profiles under a single user data directory (i.e. a single+browser instance at runtime), which means separate cookies, user preference settings, and various+data storage etc., to help you build a more wonderful experience for your application.++# Examples++## Win32 C++++### Provide options to create WebView2 with a specific profile++```cpp+HRESULT AppWindow::CreateControllerWithOptions()+{+    auto webViewEnvironment4 =+        m_webViewEnvironment.try_query<ICoreWebView2Environment4>();+    if (!webViewEnvironment4)+    {+        FeatureNotAvailable();+        return S_OK;+    }++    Microsoft::WRL::ComPtr<ICoreWebView2ControllerOptions> options;+    HRESULT hr = webViewEnvironment4->CreateCoreWebView2ControllerOptions(+        m_webviewOption.profile.c_str(), m_webviewOption.isInPrivate, options.GetAddressOf());+    if (hr == E_INVALIDARG)+    {+        ShowFailure(hr, L"Unable to create WebView2 due to an invalid profile name.");+        CloseAppWindow();+        return S_OK;+    }+    CHECK_FAILURE(hr);++#ifdef USE_WEBVIEW2_WIN10+    if (m_dcompDevice || m_wincompCompositor)+#else+    if (m_dcompDevice)+#endif+    {+        CHECK_FAILURE(webViewEnvironment4->CreateCoreWebView2CompositionControllerWithOptions(+            m_mainWindow, options.Get(),+            Callback<ICoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler>(+                [this](+                    HRESULT result,+                    ICoreWebView2CompositionController* compositionController) -> HRESULT {+                    auto controller =+                        wil::com_ptr<ICoreWebView2CompositionController>(compositionController)+                            .query<ICoreWebView2Controller>();+                    return OnCreateCoreWebView2ControllerCompleted(result, controller.get());+                })+                .Get()));+    }+    else+    {+        CHECK_FAILURE(webViewEnvironment4->CreateCoreWebView2ControllerWithOptions(+            m_mainWindow, options.Get(),+            Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(+                this, &AppWindow::OnCreateCoreWebView2ControllerCompleted)+                .Get()));+    }++    return S_OK;+}+```++### Access the profile property of WebView2++```cpp+HRESULT AppWindow::OnCreateCoreWebView2ControllerCompleted(HRESULT result, ICoreWebView2Controller* controller)+{+    // ...++    m_controller = controller;+    +    // Gets the webview object from controller.+    wil::com_ptr<ICoreWebView2> coreWebView2;+    CHECK_FAILURE(m_controller->get_CoreWebView2(&coreWebView2));++    auto webview7 = coreWebView2.try_query<ICoreWebView2_7>();+    if (webview7)+    {+        // Gets the profile property of webview.+        wil::com_ptr<ICoreWebView2Profile> profile;+        CHECK_FAILURE(webview7->get_Profile(&profile));++        // Accesses the profile object.+        BOOL inPrivateModeEnabled = FALSE;+        CHECK_FAILURE(profile->get_IsInPrivateModeEnabled(&inPrivateModeEnabled));+        wil::unique_cotaskmem_string profile_path;+        CHECK_FAILURE(profile->get_ProfilePath(&profile_path));+        std::wstring str(profile_path.get());+        m_profileDirName = str.substr(str.find_last_of(L'\\') + 1);+        +        // update window title with m_profileDirName+        UpdateAppTitle();++        // update window icon+        SetAppIcon(inPrivate);        +    }+  +    // ...+}+```+## .NET and WinRT++### Create WebView2 with a specific profile, then access the profile property of WebView2++```csharp+CoreWebView2Environment _webViewEnvironment;+public CreateWebView2ControllerWithOptions(IntPtr parentHWND, string profileName, bool isInPrivate)+{+    CoreWebView2ControllerOptions options = _webViewEnvironment.CreateCoreWebView2ControllerOptions(profileName, isInPrivate);+    CoreWebView2Controller webView2Controller = await _webViewEnvironment.CreateCoreWebView2ControllerWithOptionsAsync(parentHWND, options);+    string profilePath = webView2Controller.CoreWebView2.Profile.ProfilePath;+    string profileDirName = profilePath.Substring(profilePath.LastIndexOf('\\') + 1);+    bool inPrivate = webView2Controller.CoreWebView2.Profile.IsInPrivateModeEnabled;++    // update window title with profileDirName+    UpdateAppTitle();+

Yes, please fix.

leonhsl

comment created time in 2 days

Pull request review commentMicrosoftEdge/WebView2Feedback

API Review: multiple profile support

+API spec for multiple profile support+===++# Background++Previously, all WebView2s can only use one fixed Edge profile in the browser process, which is+normally the **Default** profile or the profile specified by the **--profile-directory** command+line switch. It means different WebView2s share a single profile directory on disk for data storage,+which might bring security concerns over cookies, autofill data, and password management etc.. Also,+they might also interfere with each other in terms of user preference settings.++Although you can make your WebView2s use different user data directories to achieve data separation,+in such way you'll have to be running multiple browser instances (each including a browser process+and a bunch of child processes), which means much more consumption for system resources including+memory, CPU footprint, disk space etc. so it is not desirable.++With all above, we're adding these new APIs to support multiple profiles, so that you can have+multiple WebView2s running with separate profiles under a single user data directory (i.e. a single+browser instance at runtime), which means separate cookies, user preference settings, and various+data storage etc., to help you build a more wonderful experience for your application.++# Examples++## Win32 C++++### Provide options to create WebView2 with a specific profile++```cpp+HRESULT AppWindow::CreateControllerWithOptions()+{+    auto webViewEnvironment4 =+        m_webViewEnvironment.try_query<ICoreWebView2Environment4>();+    if (!webViewEnvironment4)+    {+        FeatureNotAvailable();+        return S_OK;+    }++    Microsoft::WRL::ComPtr<ICoreWebView2ControllerOptions> options;+    HRESULT hr = webViewEnvironment4->CreateCoreWebView2ControllerOptions(+        m_webviewOption.profile.c_str(), m_webviewOption.isInPrivate, options.GetAddressOf());+    if (hr == E_INVALIDARG)+    {+        ShowFailure(hr, L"Unable to create WebView2 due to an invalid profile name.");+        CloseAppWindow();+        return S_OK;+    }+    CHECK_FAILURE(hr);++#ifdef USE_WEBVIEW2_WIN10+    if (m_dcompDevice || m_wincompCompositor)+#else+    if (m_dcompDevice)+#endif+    {+        CHECK_FAILURE(webViewEnvironment4->CreateCoreWebView2CompositionControllerWithOptions(+            m_mainWindow, options.Get(),+            Callback<ICoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler>(+                [this](+                    HRESULT result,+                    ICoreWebView2CompositionController* compositionController) -> HRESULT {+                    auto controller =+                        wil::com_ptr<ICoreWebView2CompositionController>(compositionController)+                            .query<ICoreWebView2Controller>();+                    return OnCreateCoreWebView2ControllerCompleted(result, controller.get());+                })+                .Get()));+    }+    else+    {+        CHECK_FAILURE(webViewEnvironment4->CreateCoreWebView2ControllerWithOptions(+            m_mainWindow, options.Get(),+            Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(+                this, &AppWindow::OnCreateCoreWebView2ControllerCompleted)+                .Get()));+    }++    return S_OK;+}+```++### Access the profile property of WebView2++```cpp+HRESULT AppWindow::OnCreateCoreWebView2ControllerCompleted(HRESULT result, ICoreWebView2Controller* controller)+{+    // ...++    m_controller = controller;+    +    // Gets the webview object from controller.+    wil::com_ptr<ICoreWebView2> coreWebView2;+    CHECK_FAILURE(m_controller->get_CoreWebView2(&coreWebView2));++    auto webview7 = coreWebView2.try_query<ICoreWebView2_7>();+    if (webview7)+    {+        // Gets the profile property of webview.+        wil::com_ptr<ICoreWebView2Profile> profile;+        CHECK_FAILURE(webview7->get_Profile(&profile));++        // Accesses the profile object.+        BOOL inPrivateModeEnabled = FALSE;+        CHECK_FAILURE(profile->get_IsInPrivateModeEnabled(&inPrivateModeEnabled));+        wil::unique_cotaskmem_string profile_path;+        CHECK_FAILURE(profile->get_ProfilePath(&profile_path));+        std::wstring str(profile_path.get());+        m_profileDirName = str.substr(str.find_last_of(L'\\') + 1);+        +        // update window title with m_profileDirName+        UpdateAppTitle();++        // update window icon+        SetAppIcon(inPrivate);        +    }+  +    // ...+}+```+## .NET and WinRT++### Create WebView2 with a specific profile, then access the profile property of WebView2++```csharp+CoreWebView2Environment _webViewEnvironment;+public CreateWebView2ControllerWithOptions(IntPtr parentHWND, string profileName, bool isInPrivate)+{+    CoreWebView2ControllerOptions options = _webViewEnvironment.CreateCoreWebView2ControllerOptions(profileName, isInPrivate);+    CoreWebView2Controller webView2Controller = await _webViewEnvironment.CreateCoreWebView2ControllerWithOptionsAsync(parentHWND, options);

Its not but it should be. Add overloads for WinRT and .NET

leonhsl

comment created time in 2 days

Pull request review commentMicrosoftEdge/WebView2Feedback

API Review: multiple profile support

+API spec for multiple profile support+===++# Background++Previously, all WebView2s can only use one fixed Edge profile in the browser process, which is+normally the **Default** profile or the profile specified by the **--profile-directory** command+line switch. It means different WebView2s share a single profile directory on disk for data storage,+which might bring security concerns over cookies, autofill data, and password management etc.. Also,+they might also interfere with each other in terms of user preference settings.++Although you can make your WebView2s use different user data directories to achieve data separation,+in such way you'll have to be running multiple browser instances (each including a browser process+and a bunch of child processes), which means much more consumption for system resources including+memory, CPU footprint, disk space etc. so it is not desirable.++With all above, we're adding these new APIs to support multiple profiles, so that you can have+multiple WebView2s running with separate profiles under a single user data directory (i.e. a single+browser instance at runtime), which means separate cookies, user preference settings, and various+data storage etc., to help you build a more wonderful experience for your application.++# Examples++## Win32 C++++### Provide options to create WebView2 with a specific profile++```cpp+HRESULT AppWindow::CreateControllerWithOptions()+{+    auto webViewEnvironment4 =+        m_webViewEnvironment.try_query<ICoreWebView2Environment4>();+    if (!webViewEnvironment4)+    {+        FeatureNotAvailable();+        return S_OK;+    }++    Microsoft::WRL::ComPtr<ICoreWebView2ControllerOptions> options;+    HRESULT hr = webViewEnvironment4->CreateCoreWebView2ControllerOptions(+        m_webviewOption.profile.c_str(), m_webviewOption.isInPrivate, options.GetAddressOf());+    if (hr == E_INVALIDARG)+    {+        ShowFailure(hr, L"Unable to create WebView2 due to an invalid profile name.");+        CloseAppWindow();+        return S_OK;+    }+    CHECK_FAILURE(hr);++#ifdef USE_WEBVIEW2_WIN10+    if (m_dcompDevice || m_wincompCompositor)+#else+    if (m_dcompDevice)+#endif+    {+        CHECK_FAILURE(webViewEnvironment4->CreateCoreWebView2CompositionControllerWithOptions(+            m_mainWindow, options.Get(),+            Callback<ICoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler>(+                [this](+                    HRESULT result,+                    ICoreWebView2CompositionController* compositionController) -> HRESULT {+                    auto controller =+                        wil::com_ptr<ICoreWebView2CompositionController>(compositionController)+                            .query<ICoreWebView2Controller>();+                    return OnCreateCoreWebView2ControllerCompleted(result, controller.get());+                })+                .Get()));+    }+    else+    {+        CHECK_FAILURE(webViewEnvironment4->CreateCoreWebView2ControllerWithOptions(+            m_mainWindow, options.Get(),+            Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(+                this, &AppWindow::OnCreateCoreWebView2ControllerCompleted)+                .Get()));+    }++    return S_OK;+}+```++### Access the profile property of WebView2++```cpp+HRESULT AppWindow::OnCreateCoreWebView2ControllerCompleted(HRESULT result, ICoreWebView2Controller* controller)+{+    // ...++    m_controller = controller;+    +    // Gets the webview object from controller.+    wil::com_ptr<ICoreWebView2> coreWebView2;+    CHECK_FAILURE(m_controller->get_CoreWebView2(&coreWebView2));++    auto webview7 = coreWebView2.try_query<ICoreWebView2_7>();+    if (webview7)+    {+        // Gets the profile property of webview.+        wil::com_ptr<ICoreWebView2Profile> profile;+        CHECK_FAILURE(webview7->get_Profile(&profile));++        // Accesses the profile object.+        BOOL inPrivateModeEnabled = FALSE;+        CHECK_FAILURE(profile->get_IsInPrivateModeEnabled(&inPrivateModeEnabled));+        wil::unique_cotaskmem_string profile_path;+        CHECK_FAILURE(profile->get_ProfilePath(&profile_path));+        std::wstring str(profile_path.get());+        m_profileDirName = str.substr(str.find_last_of(L'\\') + 1);+        +        // update window title with m_profileDirName+        UpdateAppTitle();++        // update window icon+        SetAppIcon(inPrivate);        +    }+  +    // ...+}+```+## .NET and WinRT++### Create WebView2 with a specific profile, then access the profile property of WebView2++```csharp+CoreWebView2Environment _webViewEnvironment;+public CreateWebView2ControllerWithOptions(IntPtr parentHWND, string profileName, bool isInPrivate)+{+    CoreWebView2ControllerOptions options = _webViewEnvironment.CreateCoreWebView2ControllerOptions(profileName, isInPrivate);+    CoreWebView2Controller webView2Controller = await _webViewEnvironment.CreateCoreWebView2ControllerWithOptionsAsync(parentHWND, options);+    string profilePath = webView2Controller.CoreWebView2.Profile.ProfilePath;+    string profileDirName = profilePath.Substring(profilePath.LastIndexOf('\\') + 1);+    bool inPrivate = webView2Controller.CoreWebView2.Profile.IsInPrivateModeEnabled;++    // update window title with profileDirName+    UpdateAppTitle();++    // update window icon+    SetAppIcon(inPrivate);+}+```++# API Details++## Win32 C++++```IDL+interface ICoreWebView2ControllerOptions;+interface ICoreWebView2Environment5;+interface ICoreWebView2_7;+interface ICoreWebView2Profile;++[uuid(C2669A3A-03A9-45E9-97EA-03CD55E5DC03), object, pointer_default(unique)]+interface ICoreWebView2ControllerOptions : IUnknown {+  /// `ProfileName` property is to specify a profile name, which is only allowed to contain+  /// the following ASCII characters. It has a maximum length of 64 characters excluding the null terminator. It is+  /// ASCII case insensitive.+  ///    alphabet characters: a-z and A-Z+  ///    digit characters: 0-9+  ///    and '#', '@', '$', '(', ')', '+', '-', '_', '~', '.', ' ' (space).+  /// Note: the text must not end with a period '.' or ' ' (space). And, although upper case letters are+  /// allowed, they're treated just as lower case couterparts because the profile name will be mapped to+  /// the real profile directory path on disk and Windows file system handles path names in a case-insensitive way.

Document the additional restriction that they must be valid filenames (which also means no leading spaces, and nul and com* are disallowed) and then have 'For example: ' and link to what is valid file name document.

leonhsl

comment created time in 2 days

Pull request review commentMicrosoftEdge/WebView2Feedback

API Review: multiple profile support

+API spec for multiple profile support+===++# Background++Previously, all WebView2s can only use one fixed Edge profile in the browser process, which is+normally the **Default** profile or the profile specified by the **--profile-directory** command+line switch. It means different WebView2s share a single profile directory on disk for data storage,+which might bring security concerns over cookies, autofill data, and password management etc.. Also,+they might also interfere with each other in terms of user preference settings.++Although you can make your WebView2s use different user data directories to achieve data separation,+in such way you'll have to be running multiple browser instances (each including a browser process+and a bunch of child processes), which means much more consumption for system resources including+memory, CPU footprint, disk space etc. so it is not desirable.++With all above, we're adding these new APIs to support multiple profiles, so that you can have+multiple WebView2s running with separate profiles under a single user data directory (i.e. a single+browser instance at runtime), which means separate cookies, user preference settings, and various+data storage etc., to help you build a more wonderful experience for your application.++# Examples++## Win32 C++++### Provide options to create WebView2 with a specific profile++```cpp+HRESULT AppWindow::CreateControllerWithOptions()+{+    auto webViewEnvironment4 =+        m_webViewEnvironment.try_query<ICoreWebView2Environment4>();+    if (!webViewEnvironment4)+    {+        FeatureNotAvailable();+        return S_OK;+    }++    Microsoft::WRL::ComPtr<ICoreWebView2ControllerOptions> options;

Please use wil::com_ptr

leonhsl

comment created time in 2 days

Pull request review commentMicrosoftEdge/WebView2Feedback

API Review: multiple profile support

+API spec for multiple profile support+===++# Background++Previously, all WebView2s can only use one fixed Edge profile in the browser process, which is+normally the **Default** profile or the profile specified by the **--profile-directory** command+line switch. It means different WebView2s share a single profile directory on disk for data storage,+which might bring security concerns over cookies, autofill data, and password management etc.. Also,+they might also interfere with each other in terms of user preference settings.++Although you can make your WebView2s use different user data directories to achieve data separation,+in such way you'll have to be running multiple browser instances (each including a browser process+and a bunch of child processes), which means much more consumption for system resources including+memory, CPU footprint, disk space etc. so it is not desirable.++With all above, we're adding these new APIs to support multiple profiles, so that you can have+multiple WebView2s running with separate profiles under a single user data directory (i.e. a single+browser instance at runtime), which means separate cookies, user preference settings, and various+data storage etc., to help you build a more wonderful experience for your application.++# Examples++## Win32 C++++### Provide options to create WebView2 with a specific profile++```cpp+HRESULT AppWindow::CreateControllerWithOptions()+{+    auto webViewEnvironment4 =+        m_webViewEnvironment.try_query<ICoreWebView2Environment4>();+    if (!webViewEnvironment4)+    {+        FeatureNotAvailable();+        return S_OK;+    }++    Microsoft::WRL::ComPtr<ICoreWebView2ControllerOptions> options;+    HRESULT hr = webViewEnvironment4->CreateCoreWebView2ControllerOptions(+        m_webviewOption.profile.c_str(), m_webviewOption.isInPrivate, options.GetAddressOf());+    if (hr == E_INVALIDARG)+    {+        ShowFailure(hr, L"Unable to create WebView2 due to an invalid profile name.");+        CloseAppWindow();+        return S_OK;+    }+    CHECK_FAILURE(hr);++#ifdef USE_WEBVIEW2_WIN10+    if (m_dcompDevice || m_wincompCompositor)+#else+    if (m_dcompDevice)+#endif+    {+        CHECK_FAILURE(webViewEnvironment4->CreateCoreWebView2CompositionControllerWithOptions(+            m_mainWindow, options.Get(),+            Callback<ICoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler>(+                [this](+                    HRESULT result,+                    ICoreWebView2CompositionController* compositionController) -> HRESULT {+                    auto controller =+                        wil::com_ptr<ICoreWebView2CompositionController>(compositionController)+                            .query<ICoreWebView2Controller>();+                    return OnCreateCoreWebView2ControllerCompleted(result, controller.get());+                })+                .Get()));+    }+    else+    {+        CHECK_FAILURE(webViewEnvironment4->CreateCoreWebView2ControllerWithOptions(+            m_mainWindow, options.Get(),+            Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(+                this, &AppWindow::OnCreateCoreWebView2ControllerCompleted)+                .Get()));+    }++    return S_OK;+}+```++### Access the profile property of WebView2++```cpp+HRESULT AppWindow::OnCreateCoreWebView2ControllerCompleted(HRESULT result, ICoreWebView2Controller* controller)+{+    // ...++    m_controller = controller;+    +    // Gets the webview object from controller.+    wil::com_ptr<ICoreWebView2> coreWebView2;+    CHECK_FAILURE(m_controller->get_CoreWebView2(&coreWebView2));++    auto webview7 = coreWebView2.try_query<ICoreWebView2_7>();+    if (webview7)+    {+        // Gets the profile property of webview.+        wil::com_ptr<ICoreWebView2Profile> profile;+        CHECK_FAILURE(webview7->get_Profile(&profile));++        // Accesses the profile object.+        BOOL inPrivateModeEnabled = FALSE;+        CHECK_FAILURE(profile->get_IsInPrivateModeEnabled(&inPrivateModeEnabled));+        wil::unique_cotaskmem_string profile_path;+        CHECK_FAILURE(profile->get_ProfilePath(&profile_path));+        std::wstring str(profile_path.get());+        m_profileDirName = str.substr(str.find_last_of(L'\\') + 1);+        +        // update window title with m_profileDirName+        UpdateAppTitle();

Do we need the path property? What are its uses? Can we put a more realistic use in the sample or can we remove the property? It seems reasonable to include the Name in the title but not the entire path.

leonhsl

comment created time in 2 days

Pull request review commentMicrosoftEdge/WebView2Feedback

API Review: multiple profile support

+API spec for multiple profile support+===++# Background++Previously, all WebView2s can only use one fixed Edge profile in the browser process, which is+normally the **Default** profile or the profile specified by the **--profile-directory** command+line switch. It means different WebView2s share a single profile directory on disk for data storage,+which might bring security concerns over cookies, autofill data, and password management etc.. Also,+they might also interfere with each other in terms of user preference settings.++Although you can make your WebView2s use different user data directories to achieve data separation,+in such way you'll have to be running multiple browser instances (each including a browser process+and a bunch of child processes), which means much more consumption for system resources including+memory, CPU footprint, disk space etc. so it is not desirable.++With all above, we're adding these new APIs to support multiple profiles, so that you can have+multiple WebView2s running with separate profiles under a single user data directory (i.e. a single+browser instance at runtime), which means separate cookies, user preference settings, and various+data storage etc., to help you build a more wonderful experience for your application.++# Examples++## Win32 C++++### Provide options to create WebView2 with a specific profile++```cpp+HRESULT AppWindow::CreateControllerWithOptions()+{+    auto webViewEnvironment4 =+        m_webViewEnvironment.try_query<ICoreWebView2Environment4>();+    if (!webViewEnvironment4)+    {+        FeatureNotAvailable();+        return S_OK;+    }++    Microsoft::WRL::ComPtr<ICoreWebView2ControllerOptions> options;+    HRESULT hr = webViewEnvironment4->CreateCoreWebView2ControllerOptions(+        m_webviewOption.profile.c_str(), m_webviewOption.isInPrivate, options.GetAddressOf());+    if (hr == E_INVALIDARG)+    {+        ShowFailure(hr, L"Unable to create WebView2 due to an invalid profile name.");+        CloseAppWindow();+        return S_OK;+    }+    CHECK_FAILURE(hr);++#ifdef USE_WEBVIEW2_WIN10+    if (m_dcompDevice || m_wincompCompositor)+#else+    if (m_dcompDevice)+#endif+    {+        CHECK_FAILURE(webViewEnvironment4->CreateCoreWebView2CompositionControllerWithOptions(+            m_mainWindow, options.Get(),+            Callback<ICoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler>(+                [this](+                    HRESULT result,+                    ICoreWebView2CompositionController* compositionController) -> HRESULT {+                    auto controller =+                        wil::com_ptr<ICoreWebView2CompositionController>(compositionController)+                            .query<ICoreWebView2Controller>();+                    return OnCreateCoreWebView2ControllerCompleted(result, controller.get());+                })+                .Get()));+    }+    else+    {+        CHECK_FAILURE(webViewEnvironment4->CreateCoreWebView2ControllerWithOptions(+            m_mainWindow, options.Get(),+            Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(+                this, &AppWindow::OnCreateCoreWebView2ControllerCompleted)+                .Get()));+    }++    return S_OK;+}+```++### Access the profile property of WebView2++```cpp+HRESULT AppWindow::OnCreateCoreWebView2ControllerCompleted(HRESULT result, ICoreWebView2Controller* controller)+{+    // ...++    m_controller = controller;+    +    // Gets the webview object from controller.+    wil::com_ptr<ICoreWebView2> coreWebView2;+    CHECK_FAILURE(m_controller->get_CoreWebView2(&coreWebView2));++    auto webview7 = coreWebView2.try_query<ICoreWebView2_7>();+    if (webview7)+    {+        // Gets the profile property of webview.+        wil::com_ptr<ICoreWebView2Profile> profile;+        CHECK_FAILURE(webview7->get_Profile(&profile));++        // Accesses the profile object.+        BOOL inPrivateModeEnabled = FALSE;+        CHECK_FAILURE(profile->get_IsInPrivateModeEnabled(&inPrivateModeEnabled));+        wil::unique_cotaskmem_string profile_path;+        CHECK_FAILURE(profile->get_ProfilePath(&profile_path));+        std::wstring str(profile_path.get());+        m_profileDirName = str.substr(str.find_last_of(L'\\') + 1);+        +        // update window title with m_profileDirName+        UpdateAppTitle();++        // update window icon+        SetAppIcon(inPrivate);        +    }+  +    // ...+}+```+## .NET and WinRT++### Create WebView2 with a specific profile, then access the profile property of WebView2++```csharp+CoreWebView2Environment _webViewEnvironment;+public CreateWebView2ControllerWithOptions(IntPtr parentHWND, string profileName, bool isInPrivate)+{+    CoreWebView2ControllerOptions options = _webViewEnvironment.CreateCoreWebView2ControllerOptions(profileName, isInPrivate);+    CoreWebView2Controller webView2Controller = await _webViewEnvironment.CreateCoreWebView2ControllerWithOptionsAsync(parentHWND, options);+    string profilePath = webView2Controller.CoreWebView2.Profile.ProfilePath;+    string profileDirName = profilePath.Substring(profilePath.LastIndexOf('\\') + 1);+    bool inPrivate = webView2Controller.CoreWebView2.Profile.IsInPrivateModeEnabled;++    // update window title with profileDirName+    UpdateAppTitle();++    // update window icon+    SetAppIcon(inPrivate);+}+```++# API Details++## Win32 C++++```IDL+interface ICoreWebView2ControllerOptions;+interface ICoreWebView2Environment5;+interface ICoreWebView2_7;+interface ICoreWebView2Profile;++[uuid(C2669A3A-03A9-45E9-97EA-03CD55E5DC03), object, pointer_default(unique)]+interface ICoreWebView2ControllerOptions : IUnknown {+  /// `ProfileName` property is to specify a profile name, which is only allowed to contain+  /// the following ASCII characters. It has a maximum length of 64 characters excluding the null terminator. It is+  /// ASCII case insensitive.+  ///    alphabet characters: a-z and A-Z+  ///    digit characters: 0-9+  ///    and '#', '@', '$', '(', ')', '+', '-', '_', '~', '.', ' ' (space).+  /// Note: the text must not end with a period '.' or ' ' (space). And, although upper case letters are+  /// allowed, they're treated just as lower case couterparts because the profile name will be mapped to+  /// the real profile directory path on disk and Windows file system handles path names in a case-insensitive way.+  [propget] HRESULT ProfileName([out, retval] LPWSTR* value);+  /// Sets the `ProfileName` property.+  [propput] HRESULT ProfileName([in] LPCWSTR value);++  /// `IsInPrivateModeEnabled` property is to enable/disable InPrivate mode.+  [propget] HRESULT IsInPrivateModeEnabled([out, retval] BOOL* value);+  /// Sets the `IsInPrivateModeEnabled` property.+  [propput] HRESULT IsInPrivateModeEnabled([in] BOOL value);+}++[uuid(57FD205C-39D5-4BA1-8E7B-3E53C323EA87), object, pointer_default(unique)]+interface ICoreWebView2Environment5 : IUnknown+{+  /// Create a new ICoreWebView2ControllerOptions to be passed as a parameter of+  /// CreateCoreWebView2ControllerWithOptions and CreateCoreWebView2CompositionControllerWithOptions.+  /// Returns E_INVALIDARG only in case of invalid profile name.+  HRESULT CreateCoreWebView2ControllerOptions(+      [in] LPCWSTR profileName,+      [in] BOOL isInPrivateModeEnabled,+      [out, retval] ICoreWebView2ControllerOptions** options);++  /// Create a new WebView with options.+  HRESULT CreateCoreWebView2ControllerWithOptions(+      [in] HWND parentWindow,+      [in] ICoreWebView2ControllerOptions* options,+      [in] ICoreWebView2CreateCoreWebView2ControllerCompletedHandler* handler);++  /// Create a new WebView in visual hosting mode with options.+  HRESULT CreateCoreWebView2CompositionControllerWithOptions(+      [in] HWND parentWindow,+      [in] ICoreWebView2ControllerOptions* options,+      [in] ICoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler* handler);+}++[uuid(6E5CE5F0-16E6-4A05-97D8-4E256B3EB609), object, pointer_default(unique)]+interface ICoreWebView2_7 : IUnknown {+  /// The associated `ICoreWebView2Profile` object.+  [propget] HRESULT Profile([out, retval] ICoreWebView2Profile** value);+}++[uuid(3B9A2AF2-E703-4C81-9D25-FCE44312E960), object, pointer_default(unique)]+interface ICoreWebView2Profile : IUnknown {+  /// Name of the profile.+  [propget] HRESULT ProfileName([out, retval] LPWSTR* value);++  /// InPrivate mode is enabled or not.+  [propget] HRESULT IsInPrivateModeEnabled([out, retval] BOOL* value);++  /// Full path of the profile directory.+  [propget] HRESULT ProfilePath([out, retval] LPWSTR* value);++  // TODO: All profile-wide operations/settings will be put below in the future.+}+```++## .NET and WinRT++```c#+namespace Microsoft.Web.WebView2.Core+{+    runtimeclass CoreWebView2ControllerOptions;+    runtimeclass CoreWebView2Environment;+    runtimeclass CoreWebView2;+    runtimeclass CoreWebView2Profile;++    runtimeclass CoreWebView2ControllerOptions+    {        +        String ProfileName { get; set; };++        Boolean IsInPrivateModeEnabled { get; set; };+    }+    +    runtimeclass CoreWebView2Environment+    {+        // ...+    +        CoreWebView2ControllerOptions CreateCoreWebView2ControllerOptions(+            String ProfileName, Boolean InPrivateModeEnabled);+        +        Windows.Foundation.IAsyncOperation<CoreWebView2Controller>+        CreateCoreWebView2ControllerWithOptionsAsync(+            CoreWebView2ControllerWindowReference ParentWindow,+            CoreWebView2ControllerOptions options);+        +        Windows.Foundation.IAsyncOperation<CoreWebView2CompositionController>+        CreateCoreWebView2CompositionControllerWithOptionsAsync(+            CoreWebView2ControllerWindowReference ParentWindow,+            CoreWebView2ControllerOptions options);+    }+    +    runtimeclass CoreWebView2+    {+        // ...+        CoreWebView2Profile Profile { get; };+    }+    +    runtimeclass CoreWebView2Profile+    {+        String ProfileName { get; };++        Boolean IsInPrivateModeEnabled { get; };++        String ProfilePath { get; };+    }+}+```

Consider adding based on customer feedback.

leonhsl

comment created time in 2 days

Pull request review commentMicrosoftEdge/WebView2Feedback

API Review: multiple profile support

+API spec for multiple profile support+===++# Background++Previously, all WebView2s can only use one fixed Edge profile in the browser process, which is+normally the **Default** profile or the profile specified by the **--profile-directory** command+line switch. It means different WebView2s share a single profile directory on disk for data storage,+which might bring security concerns over cookies, autofill data, and password management etc.. Also,+they might also interfere with each other in terms of user preference settings.++Although you can make your WebView2s use different user data directories to achieve data separation,+in such way you'll have to be running multiple browser instances (each including a browser process+and a bunch of child processes), which means much more consumption for system resources including+memory, CPU footprint, disk space etc. so it is not desirable.++With all above, we're adding these new APIs to support multiple profiles, so that you can have+multiple WebView2s running with separate profiles under a single user data directory (i.e. a single+browser instance at runtime), which means separate cookies, user preference settings, and various+data storage etc., to help you build a more wonderful experience for your application.++# Examples++## Win32 C++++### Provide options to create WebView2 with a specific profile++```cpp+HRESULT AppWindow::CreateControllerWithOptions()+{+    auto webViewEnvironment4 =+        m_webViewEnvironment.try_query<ICoreWebView2Environment4>();+    if (!webViewEnvironment4)+    {+        FeatureNotAvailable();+        return S_OK;+    }++    Microsoft::WRL::ComPtr<ICoreWebView2ControllerOptions> options;+    HRESULT hr = webViewEnvironment4->CreateCoreWebView2ControllerOptions(+        m_webviewOption.profile.c_str(), m_webviewOption.isInPrivate, options.GetAddressOf());+    if (hr == E_INVALIDARG)+    {+        ShowFailure(hr, L"Unable to create WebView2 due to an invalid profile name.");+        CloseAppWindow();+        return S_OK;+    }+    CHECK_FAILURE(hr);++#ifdef USE_WEBVIEW2_WIN10+    if (m_dcompDevice || m_wincompCompositor)+#else+    if (m_dcompDevice)+#endif+    {+        CHECK_FAILURE(webViewEnvironment4->CreateCoreWebView2CompositionControllerWithOptions(+            m_mainWindow, options.Get(),+            Callback<ICoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler>(+                [this](+                    HRESULT result,+                    ICoreWebView2CompositionController* compositionController) -> HRESULT {+                    auto controller =+                        wil::com_ptr<ICoreWebView2CompositionController>(compositionController)+                            .query<ICoreWebView2Controller>();+                    return OnCreateCoreWebView2ControllerCompleted(result, controller.get());+                })+                .Get()));+    }+    else+    {+        CHECK_FAILURE(webViewEnvironment4->CreateCoreWebView2ControllerWithOptions(+            m_mainWindow, options.Get(),+            Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(+                this, &AppWindow::OnCreateCoreWebView2ControllerCompleted)+                .Get()));+    }++    return S_OK;+}+```++### Access the profile property of WebView2++```cpp+HRESULT AppWindow::OnCreateCoreWebView2ControllerCompleted(HRESULT result, ICoreWebView2Controller* controller)+{+    // ...++    m_controller = controller;+    +    // Gets the webview object from controller.+    wil::com_ptr<ICoreWebView2> coreWebView2;+    CHECK_FAILURE(m_controller->get_CoreWebView2(&coreWebView2));++    auto webview7 = coreWebView2.try_query<ICoreWebView2_7>();+    if (webview7)+    {+        // Gets the profile property of webview.+        wil::com_ptr<ICoreWebView2Profile> profile;+        CHECK_FAILURE(webview7->get_Profile(&profile));++        // Accesses the profile object.+        BOOL inPrivateModeEnabled = FALSE;+        CHECK_FAILURE(profile->get_IsInPrivateModeEnabled(&inPrivateModeEnabled));+        wil::unique_cotaskmem_string profile_path;+        CHECK_FAILURE(profile->get_ProfilePath(&profile_path));+        std::wstring str(profile_path.get());+        m_profileDirName = str.substr(str.find_last_of(L'\\') + 1);+        +        // update window title with m_profileDirName+        UpdateAppTitle();++        // update window icon+        SetAppIcon(inPrivate);        +    }+  +    // ...+}+```+## .NET and WinRT++### Create WebView2 with a specific profile, then access the profile property of WebView2++```csharp+CoreWebView2Environment _webViewEnvironment;+public CreateWebView2ControllerWithOptions(IntPtr parentHWND, string profileName, bool isInPrivate)+{+    CoreWebView2ControllerOptions options = _webViewEnvironment.CreateCoreWebView2ControllerOptions(profileName, isInPrivate);+    CoreWebView2Controller webView2Controller = await _webViewEnvironment.CreateCoreWebView2ControllerWithOptionsAsync(parentHWND, options);+    string profilePath = webView2Controller.CoreWebView2.Profile.ProfilePath;+    string profileDirName = profilePath.Substring(profilePath.LastIndexOf('\\') + 1);+    bool inPrivate = webView2Controller.CoreWebView2.Profile.IsInPrivateModeEnabled;++    // update window title with profileDirName+    UpdateAppTitle();++    // update window icon+    SetAppIcon(inPrivate);+}+```++# API Details++## Win32 C++++```IDL+interface ICoreWebView2ControllerOptions;+interface ICoreWebView2Environment5;+interface ICoreWebView2_7;+interface ICoreWebView2Profile;++[uuid(C2669A3A-03A9-45E9-97EA-03CD55E5DC03), object, pointer_default(unique)]+interface ICoreWebView2ControllerOptions : IUnknown {+  /// `ProfileName` property is to specify a profile name, which is only allowed to contain+  /// the following ASCII characters. It has a maximum length of 64 characters excluding the null terminator. It is+  /// ASCII case insensitive.+  ///    alphabet characters: a-z and A-Z+  ///    digit characters: 0-9+  ///    and '#', '@', '$', '(', ')', '+', '-', '_', '~', '.', ' ' (space).+  /// Note: the text must not end with a period '.' or ' ' (space). And, although upper case letters are+  /// allowed, they're treated just as lower case couterparts because the profile name will be mapped to+  /// the real profile directory path on disk and Windows file system handles path names in a case-insensitive way.+  [propget] HRESULT ProfileName([out, retval] LPWSTR* value);+  /// Sets the `ProfileName` property.+  [propput] HRESULT ProfileName([in] LPCWSTR value);++  /// `IsInPrivateModeEnabled` property is to enable/disable InPrivate mode.+  [propget] HRESULT IsInPrivateModeEnabled([out, retval] BOOL* value);+  /// Sets the `IsInPrivateModeEnabled` property.+  [propput] HRESULT IsInPrivateModeEnabled([in] BOOL value);+}++[uuid(57FD205C-39D5-4BA1-8E7B-3E53C323EA87), object, pointer_default(unique)]+interface ICoreWebView2Environment5 : IUnknown+{+  /// Create a new ICoreWebView2ControllerOptions to be passed as a parameter of+  /// CreateCoreWebView2ControllerWithOptions and CreateCoreWebView2CompositionControllerWithOptions.+  /// Returns E_INVALIDARG only in case of invalid profile name.+  HRESULT CreateCoreWebView2ControllerOptions(+      [in] LPCWSTR profileName,+      [in] BOOL isInPrivateModeEnabled,+      [out, retval] ICoreWebView2ControllerOptions** options);++  /// Create a new WebView with options.+  HRESULT CreateCoreWebView2ControllerWithOptions(+      [in] HWND parentWindow,+      [in] ICoreWebView2ControllerOptions* options,+      [in] ICoreWebView2CreateCoreWebView2ControllerCompletedHandler* handler);++  /// Create a new WebView in visual hosting mode with options.+  HRESULT CreateCoreWebView2CompositionControllerWithOptions(+      [in] HWND parentWindow,+      [in] ICoreWebView2ControllerOptions* options,+      [in] ICoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler* handler);+}++[uuid(6E5CE5F0-16E6-4A05-97D8-4E256B3EB609), object, pointer_default(unique)]+interface ICoreWebView2_7 : IUnknown {+  /// The associated `ICoreWebView2Profile` object.+  [propget] HRESULT Profile([out, retval] ICoreWebView2Profile** value);

Default profile! Must document this.

leonhsl

comment created time in 2 days

Pull request review commentMicrosoftEdge/WebView2Feedback

API Review: multiple profile support

+API spec for multiple profile support+===++# Background++Previously, all WebView2s can only use one fixed Edge profile in the browser process, which is+normally the **Default** profile or the profile specified by the **--profile-directory** command+line switch. It means different WebView2s share a single profile directory on disk for data storage,+which might bring security concerns over cookies, autofill data, and password management etc.. Also,+they might also interfere with each other in terms of user preference settings.++Although you can make your WebView2s use different user data directories to achieve data separation,+in such way you'll have to be running multiple browser instances (each including a browser process+and a bunch of child processes), which means much more consumption for system resources including+memory, CPU footprint, disk space etc. so it is not desirable.++With all above, we're adding these new APIs to support multiple profiles, so that you can have+multiple WebView2s running with separate profiles under a single user data directory (i.e. a single+browser instance at runtime), which means separate cookies, user preference settings, and various+data storage etc., to help you build a more wonderful experience for your application.++# Examples++## Win32 C++++### Provide options to create WebView2 with a specific profile++```cpp+HRESULT AppWindow::CreateControllerWithOptions()+{+    auto webViewEnvironment4 =+        m_webViewEnvironment.try_query<ICoreWebView2Environment4>();+    if (!webViewEnvironment4)+    {+        FeatureNotAvailable();+        return S_OK;+    }++    Microsoft::WRL::ComPtr<ICoreWebView2ControllerOptions> options;+    HRESULT hr = webViewEnvironment4->CreateCoreWebView2ControllerOptions(+        m_webviewOption.profile.c_str(), m_webviewOption.isInPrivate, options.GetAddressOf());+    if (hr == E_INVALIDARG)+    {+        ShowFailure(hr, L"Unable to create WebView2 due to an invalid profile name.");+        CloseAppWindow();+        return S_OK;+    }+    CHECK_FAILURE(hr);++#ifdef USE_WEBVIEW2_WIN10+    if (m_dcompDevice || m_wincompCompositor)+#else+    if (m_dcompDevice)+#endif+    {+        CHECK_FAILURE(webViewEnvironment4->CreateCoreWebView2CompositionControllerWithOptions(+            m_mainWindow, options.Get(),+            Callback<ICoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler>(+                [this](+                    HRESULT result,+                    ICoreWebView2CompositionController* compositionController) -> HRESULT {+                    auto controller =+                        wil::com_ptr<ICoreWebView2CompositionController>(compositionController)+                            .query<ICoreWebView2Controller>();+                    return OnCreateCoreWebView2ControllerCompleted(result, controller.get());+                })+                .Get()));+    }+    else+    {+        CHECK_FAILURE(webViewEnvironment4->CreateCoreWebView2ControllerWithOptions(+            m_mainWindow, options.Get(),+            Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(+                this, &AppWindow::OnCreateCoreWebView2ControllerCompleted)+                .Get()));+    }++    return S_OK;+}+```++### Access the profile property of WebView2++```cpp+HRESULT AppWindow::OnCreateCoreWebView2ControllerCompleted(HRESULT result, ICoreWebView2Controller* controller)+{+    // ...++    m_controller = controller;+    +    // Gets the webview object from controller.+    wil::com_ptr<ICoreWebView2> coreWebView2;+    CHECK_FAILURE(m_controller->get_CoreWebView2(&coreWebView2));++    auto webview7 = coreWebView2.try_query<ICoreWebView2_7>();+    if (webview7)+    {+        // Gets the profile property of webview.+        wil::com_ptr<ICoreWebView2Profile> profile;+        CHECK_FAILURE(webview7->get_Profile(&profile));++        // Accesses the profile object.+        BOOL inPrivateModeEnabled = FALSE;+        CHECK_FAILURE(profile->get_IsInPrivateModeEnabled(&inPrivateModeEnabled));+        wil::unique_cotaskmem_string profile_path;+        CHECK_FAILURE(profile->get_ProfilePath(&profile_path));+        std::wstring str(profile_path.get());+        m_profileDirName = str.substr(str.find_last_of(L'\\') + 1);+        +        // update window title with m_profileDirName+        UpdateAppTitle();++        // update window icon+        SetAppIcon(inPrivate);        +    }+  +    // ...+}+```+## .NET and WinRT++### Create WebView2 with a specific profile, then access the profile property of WebView2++```csharp+CoreWebView2Environment _webViewEnvironment;+public CreateWebView2ControllerWithOptions(IntPtr parentHWND, string profileName, bool isInPrivate)+{+    CoreWebView2ControllerOptions options = _webViewEnvironment.CreateCoreWebView2ControllerOptions(profileName, isInPrivate);+    CoreWebView2Controller webView2Controller = await _webViewEnvironment.CreateCoreWebView2ControllerWithOptionsAsync(parentHWND, options);+    string profilePath = webView2Controller.CoreWebView2.Profile.ProfilePath;+    string profileDirName = profilePath.Substring(profilePath.LastIndexOf('\\') + 1);

Please use this.

leonhsl

comment created time in 2 days

Pull request review commentMicrosoftEdge/WebView2Feedback

API Review: multiple profile support

+API spec for multiple profile support+===++# Background++Previously, all WebView2s can only use one fixed Edge profile in the browser process, which is+normally the **Default** profile or the profile specified by the **--profile-directory** command+line switch. It means different WebView2s share a single profile directory on disk for data storage,+which might bring security concerns over cookies, autofill data, and password management etc.. Also,+they might also interfere with each other in terms of user preference settings.++Although you can make your WebView2s use different user data directories to achieve data separation,+in such way you'll have to be running multiple browser instances (each including a browser process+and a bunch of child processes), which means much more consumption for system resources including+memory, CPU footprint, disk space etc. so it is not desirable.++With all above, we're adding these new APIs to support multiple profiles, so that you can have+multiple WebView2s running with separate profiles under a single user data directory (i.e. a single+browser instance at runtime), which means separate cookies, user preference settings, and various+data storage etc., to help you build a more wonderful experience for your application.++# Examples++## Win32 C++++### Provide options to create WebView2 with a specific profile++```cpp+HRESULT AppWindow::CreateControllerWithOptions()+{+    auto webViewEnvironment4 =+        m_webViewEnvironment.try_query<ICoreWebView2Environment4>();+    if (!webViewEnvironment4)+    {+        FeatureNotAvailable();+        return S_OK;+    }++    Microsoft::WRL::ComPtr<ICoreWebView2ControllerOptions> options;+    HRESULT hr = webViewEnvironment4->CreateCoreWebView2ControllerOptions(+        m_webviewOption.profile.c_str(), m_webviewOption.isInPrivate, options.GetAddressOf());+    if (hr == E_INVALIDARG)+    {+        ShowFailure(hr, L"Unable to create WebView2 due to an invalid profile name.");+        CloseAppWindow();+        return S_OK;+    }+    CHECK_FAILURE(hr);

Document where the validation of the name occurs - in the property setter or in the create.

leonhsl

comment created time in 2 days

Pull request review commentMicrosoftEdge/WebView2Feedback

API Review: multiple profile support

+API spec for multiple profile support+===++# Background++Previously, all WebView2s can only use one fixed Edge profile in the browser process, which is+normally the **Default** profile or the profile specified by the **--profile-directory** command+line switch. It means different WebView2s share a single profile directory on disk for data storage,+which might bring security concerns over cookies, autofill data, and password management etc.. Also,+they might also interfere with each other in terms of user preference settings.++Although you can make your WebView2s use different user data directories to achieve data separation,+in such way you'll have to be running multiple browser instances (each including a browser process+and a bunch of child processes), which means much more consumption for system resources including+memory, CPU footprint, disk space etc. so it is not desirable.++With all above, we're adding these new APIs to support multiple profiles, so that you can have+multiple WebView2s running with separate profiles under a single user data directory (i.e. a single+browser instance at runtime), which means separate cookies, user preference settings, and various+data storage etc., to help you build a more wonderful experience for your application.++# Examples++## Win32 C++++### Provide options to create WebView2 with a specific profile++```cpp+HRESULT AppWindow::CreateControllerWithOptions()+{+    auto webViewEnvironment4 =+        m_webViewEnvironment.try_query<ICoreWebView2Environment4>();+    if (!webViewEnvironment4)+    {+        FeatureNotAvailable();+        return S_OK;+    }++    Microsoft::WRL::ComPtr<ICoreWebView2ControllerOptions> options;+    HRESULT hr = webViewEnvironment4->CreateCoreWebView2ControllerOptions(+        m_webviewOption.profile.c_str(), m_webviewOption.isInPrivate, options.GetAddressOf());+    if (hr == E_INVALIDARG)+    {+        ShowFailure(hr, L"Unable to create WebView2 due to an invalid profile name.");+        CloseAppWindow();+        return S_OK;+    }+    CHECK_FAILURE(hr);++#ifdef USE_WEBVIEW2_WIN10+    if (m_dcompDevice || m_wincompCompositor)+#else+    if (m_dcompDevice)+#endif+    {+        CHECK_FAILURE(webViewEnvironment4->CreateCoreWebView2CompositionControllerWithOptions(+            m_mainWindow, options.Get(),+            Callback<ICoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler>(+                [this](+                    HRESULT result,+                    ICoreWebView2CompositionController* compositionController) -> HRESULT {+                    auto controller =+                        wil::com_ptr<ICoreWebView2CompositionController>(compositionController)+                            .query<ICoreWebView2Controller>();+                    return OnCreateCoreWebView2ControllerCompleted(result, controller.get());+                })+                .Get()));+    }+    else+    {+        CHECK_FAILURE(webViewEnvironment4->CreateCoreWebView2ControllerWithOptions(+            m_mainWindow, options.Get(),+            Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(+                this, &AppWindow::OnCreateCoreWebView2ControllerCompleted)+                .Get()));+    }++    return S_OK;+}+```++### Access the profile property of WebView2++```cpp+HRESULT AppWindow::OnCreateCoreWebView2ControllerCompleted(HRESULT result, ICoreWebView2Controller* controller)+{+    // ...++    m_controller = controller;+    +    // Gets the webview object from controller.+    wil::com_ptr<ICoreWebView2> coreWebView2;+    CHECK_FAILURE(m_controller->get_CoreWebView2(&coreWebView2));++    auto webview7 = coreWebView2.try_query<ICoreWebView2_7>();+    if (webview7)+    {+        // Gets the profile property of webview.+        wil::com_ptr<ICoreWebView2Profile> profile;+        CHECK_FAILURE(webview7->get_Profile(&profile));++        // Accesses the profile object.+        BOOL inPrivateModeEnabled = FALSE;+        CHECK_FAILURE(profile->get_IsInPrivateModeEnabled(&inPrivateModeEnabled));+        wil::unique_cotaskmem_string profile_path;+        CHECK_FAILURE(profile->get_ProfilePath(&profile_path));+        std::wstring str(profile_path.get());+        m_profileDirName = str.substr(str.find_last_of(L'\\') + 1);+        +        // update window title with m_profileDirName+        UpdateAppTitle();++        // update window icon+        SetAppIcon(inPrivate);        +    }+  +    // ...+}+```+## .NET and WinRT++### Create WebView2 with a specific profile, then access the profile property of WebView2++```csharp+CoreWebView2Environment _webViewEnvironment;+public CreateWebView2ControllerWithOptions(IntPtr parentHWND, string profileName, bool isInPrivate)

Yes please

leonhsl

comment created time in 2 days

Pull request review commentMicrosoftEdge/WebView2Feedback

API Review: multiple profile support

+API spec for multiple profile support+===++# Background++Previously, all WebView2s can only use one fixed Edge profile in the browser process, which is+normally the **Default** profile or the profile specified by the **--profile-directory** command+line switch. It means different WebView2s share a single profile directory on disk for data storage,+which might bring security concerns over cookies, autofill data, and password management etc.. Also,+they might also interfere with each other in terms of user preference settings.++Although you can make your WebView2s use different user data directories to achieve data separation,+in such way you'll have to be running multiple browser instances (each including a browser process+and a bunch of child processes), which means much more consumption for system resources including+memory, CPU footprint, disk space etc. so it is not desirable.++With all above, we're adding these new APIs to support multiple profiles, so that you can have+multiple WebView2s running with separate profiles under a single user data directory (i.e. a single+browser instance at runtime), which means separate cookies, user preference settings, and various+data storage etc., to help you build a more wonderful experience for your application.++# Examples++## Win32 C++++### Provide options to create WebView2 with a specific profile++```cpp+HRESULT AppWindow::CreateControllerWithOptions()+{+    auto webViewEnvironment4 =+        m_webViewEnvironment.try_query<ICoreWebView2Environment4>();+    if (!webViewEnvironment4)+    {+        FeatureNotAvailable();+        return S_OK;+    }++    Microsoft::WRL::ComPtr<ICoreWebView2ControllerOptions> options;+    HRESULT hr = webViewEnvironment4->CreateCoreWebView2ControllerOptions(+        m_webviewOption.profile.c_str(), m_webviewOption.isInPrivate, options.GetAddressOf());+    if (hr == E_INVALIDARG)+    {+        ShowFailure(hr, L"Unable to create WebView2 due to an invalid profile name.");

Yes. Apps should either be using hardcoded names (or otherwise computed/generated value) or taking user input and if its user input it should be sanitized. Please update sample app to sanitize.

leonhsl

comment created time in 2 days

Pull request review commentMicrosoftEdge/WebView2Feedback

API Review: multiple profile support

+API spec for multiple profile support+===++# Background++Previously, all WebView2s can only use one fixed Edge profile in the browser process, which is+normally the **Default** profile or the profile specified by the **--profile-directory** command+line switch. It means different WebView2s share a single profile directory on disk for data storage,+which might bring security concerns over cookies, autofill data, and password management etc.. Also,+they might also interfere with each other in terms of user preference settings.++Although you can make your WebView2s use different user data directories to achieve data separation,+in such way you'll have to be running multiple browser instances (each including a browser process+and a bunch of child processes), which means much more consumption for system resources including+memory, CPU footprint, disk space etc. so it is not desirable.

Profiles share some state but not share what that is. Document.

leonhsl

comment created time in 2 days

PullRequestReviewEvent

Pull request review commentMicrosoftEdge/WebView2Feedback

API Review: multiple profile support

+API spec for multiple profile support+===++# Background++Previously, all WebView2s can only use one fixed Edge profile in the browser process, which is+normally the **Default** profile or the profile specified by the **--profile-directory** command

Should document how to get default profile (empty string profile name and create by normal)

leonhsl

comment created time in 2 days

Pull request review commentMicrosoftEdge/WebView2Feedback

API Review: multiple profile support

+API spec for multiple profile support+===++# Background++Previously, all WebView2s can only use one fixed Edge profile in the browser process, which is+normally the **Default** profile or the profile specified by the **--profile-directory** command+line switch. It means different WebView2s share a single profile directory on disk for data storage,+which might bring security concerns over cookies, autofill data, and password management etc.. Also,+they might also interfere with each other in terms of user preference settings.++Although you can make your WebView2s use different user data directories to achieve data separation,+in such way you'll have to be running multiple browser instances (each including a browser process+and a bunch of child processes), which means much more consumption for system resources including+memory, CPU footprint, disk space etc. so it is not desirable.++With all above, we're adding these new APIs to support multiple profiles, so that you can have+multiple WebView2s running with separate profiles under a single user data directory (i.e. a single+browser instance at runtime), which means separate cookies, user preference settings, and various+data storage etc., to help you build a more wonderful experience for your application.++# Examples++## Win32 C++++### Provide options to create WebView2 with a specific profile++```cpp+HRESULT AppWindow::CreateControllerWithOptions()+{+    auto webViewEnvironment4 =+        m_webViewEnvironment.try_query<ICoreWebView2Environment4>();+    if (!webViewEnvironment4)+    {+        FeatureNotAvailable();+        return S_OK;+    }++    Microsoft::WRL::ComPtr<ICoreWebView2ControllerOptions> options;+    HRESULT hr = webViewEnvironment4->CreateCoreWebView2ControllerOptions(

Yes let's have no parameters to Create..ControllerOptions and just use the settable properties to make this consistent with future properties we add to the profile. Defaults should be what you would have gotten without using the profile api - empty string name and false for inprivate

leonhsl

comment created time in 2 days

Pull request review commentMicrosoftEdge/WebView2Feedback

API Review: multiple profile support

+API spec for multiple profile support+===++# Background++Previously, all WebView2s can only use one fixed Edge profile in the browser process, which is+normally the **Default** profile or the profile specified by the **--profile-directory** command+line switch. It means different WebView2s share a single profile directory on disk for data storage,+which might bring security concerns over cookies, autofill data, and password management etc.. Also,+they might also interfere with each other in terms of user preference settings.++Although you can make your WebView2s use different user data directories to achieve data separation,+in such way you'll have to be running multiple browser instances (each including a browser process+and a bunch of child processes), which means much more consumption for system resources including+memory, CPU footprint, disk space etc. so it is not desirable.++With all above, we're adding these new APIs to support multiple profiles, so that you can have+multiple WebView2s running with separate profiles under a single user data directory (i.e. a single+browser instance at runtime), which means separate cookies, user preference settings, and various+data storage etc., to help you build a more wonderful experience for your application.++# Examples++## Win32 C++++### Provide options to create WebView2 with a specific profile++```cpp+HRESULT AppWindow::CreateControllerWithOptions()+{+    auto webViewEnvironment4 =+        m_webViewEnvironment.try_query<ICoreWebView2Environment4>();+    if (!webViewEnvironment4)+    {+        FeatureNotAvailable();+        return S_OK;+    }++    Microsoft::WRL::ComPtr<ICoreWebView2ControllerOptions> options;+    HRESULT hr = webViewEnvironment4->CreateCoreWebView2ControllerOptions(+        m_webviewOption.profile.c_str(), m_webviewOption.isInPrivate, options.GetAddressOf());+    if (hr == E_INVALIDARG)+    {+        ShowFailure(hr, L"Unable to create WebView2 due to an invalid profile name.");+        CloseAppWindow();+        return S_OK;+    }+    CHECK_FAILURE(hr);++#ifdef USE_WEBVIEW2_WIN10+    if (m_dcompDevice || m_wincompCompositor)+#else+    if (m_dcompDevice)+#endif+    {+        CHECK_FAILURE(webViewEnvironment4->CreateCoreWebView2CompositionControllerWithOptions(+            m_mainWindow, options.Get(),+            Callback<ICoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler>(+                [this](+                    HRESULT result,+                    ICoreWebView2CompositionController* compositionController) -> HRESULT {+                    auto controller =+                        wil::com_ptr<ICoreWebView2CompositionController>(compositionController)+                            .query<ICoreWebView2Controller>();+                    return OnCreateCoreWebView2ControllerCompleted(result, controller.get());+                })+                .Get()));+    }+    else+    {+        CHECK_FAILURE(webViewEnvironment4->CreateCoreWebView2ControllerWithOptions(+            m_mainWindow, options.Get(),+            Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(+                this, &AppWindow::OnCreateCoreWebView2ControllerCompleted)+                .Get()));+    }++    return S_OK;+}+```++### Access the profile property of WebView2++```cpp+HRESULT AppWindow::OnCreateCoreWebView2ControllerCompleted(HRESULT result, ICoreWebView2Controller* controller)+{+    // ...++    m_controller = controller;+    +    // Gets the webview object from controller.+    wil::com_ptr<ICoreWebView2> coreWebView2;+    CHECK_FAILURE(m_controller->get_CoreWebView2(&coreWebView2));++    auto webview7 = coreWebView2.try_query<ICoreWebView2_7>();+    if (webview7)+    {+        // Gets the profile property of webview.+        wil::com_ptr<ICoreWebView2Profile> profile;+        CHECK_FAILURE(webview7->get_Profile(&profile));++        // Accesses the profile object.+        BOOL inPrivateModeEnabled = FALSE;+        CHECK_FAILURE(profile->get_IsInPrivateModeEnabled(&inPrivateModeEnabled));+        wil::unique_cotaskmem_string profile_path;+        CHECK_FAILURE(profile->get_ProfilePath(&profile_path));+        std::wstring str(profile_path.get());+        m_profileDirName = str.substr(str.find_last_of(L'\\') + 1);

Yes. Good point. Please use the ProfileName property.

leonhsl

comment created time in 2 days

Pull request review commentMicrosoftEdge/WebView2Feedback

API Review: multiple profile support

+API spec for multiple profile support+===++# Background++Previously, all WebView2s can only use one fixed Edge profile in the browser process, which is+normally the **Default** profile or the profile specified by the **--profile-directory** command+line switch. It means different WebView2s share a single profile directory on disk for data storage,+which might bring security concerns over cookies, autofill data, and password management etc.. Also,+they might also interfere with each other in terms of user preference settings.++Although you can make your WebView2s use different user data directories to achieve data separation,+in such way you'll have to be running multiple browser instances (each including a browser process+and a bunch of child processes), which means much more consumption for system resources including+memory, CPU footprint, disk space etc. so it is not desirable.++With all above, we're adding these new APIs to support multiple profiles, so that you can have+multiple WebView2s running with separate profiles under a single user data directory (i.e. a single+browser instance at runtime), which means separate cookies, user preference settings, and various+data storage etc., to help you build a more wonderful experience for your application.++# Examples++## Win32 C++++### Provide options to create WebView2 with a specific profile++```cpp+HRESULT AppWindow::CreateControllerWithOptions()+{+    auto webViewEnvironment4 =+        m_webViewEnvironment.try_query<ICoreWebView2Environment4>();+    if (!webViewEnvironment4)+    {+        FeatureNotAvailable();+        return S_OK;+    }++    Microsoft::WRL::ComPtr<ICoreWebView2ControllerOptions> options;+    HRESULT hr = webViewEnvironment4->CreateCoreWebView2ControllerOptions(+        m_webviewOption.profile.c_str(), m_webviewOption.isInPrivate, options.GetAddressOf());+    if (hr == E_INVALIDARG)+    {+        ShowFailure(hr, L"Unable to create WebView2 due to an invalid profile name.");+        CloseAppWindow();+        return S_OK;+    }+    CHECK_FAILURE(hr);++#ifdef USE_WEBVIEW2_WIN10+    if (m_dcompDevice || m_wincompCompositor)+#else+    if (m_dcompDevice)+#endif+    {+        CHECK_FAILURE(webViewEnvironment4->CreateCoreWebView2CompositionControllerWithOptions(+            m_mainWindow, options.Get(),+            Callback<ICoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler>(+                [this](+                    HRESULT result,+                    ICoreWebView2CompositionController* compositionController) -> HRESULT {+                    auto controller =+                        wil::com_ptr<ICoreWebView2CompositionController>(compositionController)+                            .query<ICoreWebView2Controller>();+                    return OnCreateCoreWebView2ControllerCompleted(result, controller.get());+                })+                .Get()));+    }+    else+    {+        CHECK_FAILURE(webViewEnvironment4->CreateCoreWebView2ControllerWithOptions(+            m_mainWindow, options.Get(),+            Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(+                this, &AppWindow::OnCreateCoreWebView2ControllerCompleted)+                .Get()));+    }++    return S_OK;+}+```++### Access the profile property of WebView2++```cpp+HRESULT AppWindow::OnCreateCoreWebView2ControllerCompleted(HRESULT result, ICoreWebView2Controller* controller)+{+    // ...++    m_controller = controller;+    +    // Gets the webview object from controller.+    wil::com_ptr<ICoreWebView2> coreWebView2;+    CHECK_FAILURE(m_controller->get_CoreWebView2(&coreWebView2));++    auto webview7 = coreWebView2.try_query<ICoreWebView2_7>();+    if (webview7)+    {+        // Gets the profile property of webview.+        wil::com_ptr<ICoreWebView2Profile> profile;+        CHECK_FAILURE(webview7->get_Profile(&profile));++        // Accesses the profile object.+        BOOL inPrivateModeEnabled = FALSE;+        CHECK_FAILURE(profile->get_IsInPrivateModeEnabled(&inPrivateModeEnabled));+        wil::unique_cotaskmem_string profile_path;+        CHECK_FAILURE(profile->get_ProfilePath(&profile_path));+        std::wstring str(profile_path.get());+        m_profileDirName = str.substr(str.find_last_of(L'\\') + 1);+        +        // update window title with m_profileDirName+        UpdateAppTitle();++        // update window icon+        SetAppIcon(inPrivate);        +    }+  +    // ...+}+```+## .NET and WinRT++### Create WebView2 with a specific profile, then access the profile property of WebView2++```csharp+CoreWebView2Environment _webViewEnvironment;+public CreateWebView2ControllerWithOptions(IntPtr parentHWND, string profileName, bool isInPrivate)+{+    CoreWebView2ControllerOptions options = _webViewEnvironment.CreateCoreWebView2ControllerOptions(profileName, isInPrivate);+    CoreWebView2Controller webView2Controller = await _webViewEnvironment.CreateCoreWebView2ControllerWithOptionsAsync(parentHWND, options);+    string profilePath = webView2Controller.CoreWebView2.Profile.ProfilePath;+    string profileDirName = profilePath.Substring(profilePath.LastIndexOf('\\') + 1);+    bool inPrivate = webView2Controller.CoreWebView2.Profile.IsInPrivateModeEnabled;++    // update window title with profileDirName+    UpdateAppTitle();++    // update window icon+    SetAppIcon(inPrivate);+}+```++# API Details++## Win32 C++++```IDL+interface ICoreWebView2ControllerOptions;+interface ICoreWebView2Environment5;+interface ICoreWebView2_7;+interface ICoreWebView2Profile;++[uuid(C2669A3A-03A9-45E9-97EA-03CD55E5DC03), object, pointer_default(unique)]+interface ICoreWebView2ControllerOptions : IUnknown {+  /// `ProfileName` property is to specify a profile name, which is only allowed to contain+  /// the following ASCII characters. It has a maximum length of 64 characters excluding the null terminator. It is+  /// ASCII case insensitive.+  ///    alphabet characters: a-z and A-Z+  ///    digit characters: 0-9+  ///    and '#', '@', '$', '(', ')', '+', '-', '_', '~', '.', ' ' (space).+  /// Note: the text must not end with a period '.' or ' ' (space). And, although upper case letters are+  /// allowed, they're treated just as lower case couterparts because the profile name will be mapped to+  /// the real profile directory path on disk and Windows file system handles path names in a case-insensitive way.+  [propget] HRESULT ProfileName([out, retval] LPWSTR* value);+  /// Sets the `ProfileName` property.+  [propput] HRESULT ProfileName([in] LPCWSTR value);++  /// `IsInPrivateModeEnabled` property is to enable/disable InPrivate mode.+  [propget] HRESULT IsInPrivateModeEnabled([out, retval] BOOL* value);+  /// Sets the `IsInPrivateModeEnabled` property.+  [propput] HRESULT IsInPrivateModeEnabled([in] BOOL value);+}++[uuid(57FD205C-39D5-4BA1-8E7B-3E53C323EA87), object, pointer_default(unique)]+interface ICoreWebView2Environment5 : IUnknown+{+  /// Create a new ICoreWebView2ControllerOptions to be passed as a parameter of+  /// CreateCoreWebView2ControllerWithOptions and CreateCoreWebView2CompositionControllerWithOptions.+  /// Returns E_INVALIDARG only in case of invalid profile name.+  HRESULT CreateCoreWebView2ControllerOptions(+      [in] LPCWSTR profileName,+      [in] BOOL isInPrivateModeEnabled,+      [out, retval] ICoreWebView2ControllerOptions** options);++  /// Create a new WebView with options.+  HRESULT CreateCoreWebView2ControllerWithOptions(+      [in] HWND parentWindow,+      [in] ICoreWebView2ControllerOptions* options,+      [in] ICoreWebView2CreateCoreWebView2ControllerCompletedHandler* handler);++  /// Create a new WebView in visual hosting mode with options.+  HRESULT CreateCoreWebView2CompositionControllerWithOptions(+      [in] HWND parentWindow,+      [in] ICoreWebView2ControllerOptions* options,+      [in] ICoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler* handler);+}++[uuid(6E5CE5F0-16E6-4A05-97D8-4E256B3EB609), object, pointer_default(unique)]+interface ICoreWebView2_7 : IUnknown {+  /// The associated `ICoreWebView2Profile` object.+  [propget] HRESULT Profile([out, retval] ICoreWebView2Profile** value);+}++[uuid(3B9A2AF2-E703-4C81-9D25-FCE44312E960), object, pointer_default(unique)]+interface ICoreWebView2Profile : IUnknown {+  /// Name of the profile.+  [propget] HRESULT ProfileName([out, retval] LPWSTR* value);++  /// InPrivate mode is enabled or not.+  [propget] HRESULT IsInPrivateModeEnabled([out, retval] BOOL* value);++  /// Full path of the profile directory.+  [propget] HRESULT ProfilePath([out, retval] LPWSTR* value);++  // TODO: All profile-wide operations/settings will be put below in the future.+}+```++## .NET and WinRT++```c#+namespace Microsoft.Web.WebView2.Core+{+    runtimeclass CoreWebView2ControllerOptions;+    runtimeclass CoreWebView2Environment;+    runtimeclass CoreWebView2;+    runtimeclass CoreWebView2Profile;++    runtimeclass CoreWebView2ControllerOptions+    {        +        String ProfileName { get; set; };++        Boolean IsInPrivateModeEnabled { get; set; };+    }+    +    runtimeclass CoreWebView2Environment+    {+        // ...+    +        CoreWebView2ControllerOptions CreateCoreWebView2ControllerOptions(+            String ProfileName, Boolean InPrivateModeEnabled);+        +        Windows.Foundation.IAsyncOperation<CoreWebView2Controller>+        CreateCoreWebView2ControllerWithOptionsAsync(+            CoreWebView2ControllerWindowReference ParentWindow,+            CoreWebView2ControllerOptions options);+        +        Windows.Foundation.IAsyncOperation<CoreWebView2CompositionController>+        CreateCoreWebView2CompositionControllerWithOptionsAsync(

Yes please add for .NET and WinRT

leonhsl

comment created time in 2 days

Pull request review commentMicrosoftEdge/WebView2Feedback

API Review: multiple profile support

+API spec for multiple profile support+===++# Background++Previously, all WebView2s can only use one fixed Edge profile in the browser process, which is+normally the **Default** profile or the profile specified by the **--profile-directory** command+line switch. It means different WebView2s share a single profile directory on disk for data storage,+which might bring security concerns over cookies, autofill data, and password management etc.. Also,+they might also interfere with each other in terms of user preference settings.++Although you can make your WebView2s use different user data directories to achieve data separation,+in such way you'll have to be running multiple browser instances (each including a browser process+and a bunch of child processes), which means much more consumption for system resources including+memory, CPU footprint, disk space etc. so it is not desirable.++With all above, we're adding these new APIs to support multiple profiles, so that you can have+multiple WebView2s running with separate profiles under a single user data directory (i.e. a single+browser instance at runtime), which means separate cookies, user preference settings, and various+data storage etc., to help you build a more wonderful experience for your application.++# Examples++## Win32 C++++### Provide options to create WebView2 with a specific profile++```cpp+HRESULT AppWindow::CreateControllerWithOptions()+{+    auto webViewEnvironment4 =+        m_webViewEnvironment.try_query<ICoreWebView2Environment4>();+    if (!webViewEnvironment4)+    {+        FeatureNotAvailable();+        return S_OK;+    }++    Microsoft::WRL::ComPtr<ICoreWebView2ControllerOptions> options;+    HRESULT hr = webViewEnvironment4->CreateCoreWebView2ControllerOptions(+        m_webviewOption.profile.c_str(), m_webviewOption.isInPrivate, options.GetAddressOf());+    if (hr == E_INVALIDARG)+    {+        ShowFailure(hr, L"Unable to create WebView2 due to an invalid profile name.");+        CloseAppWindow();+        return S_OK;+    }+    CHECK_FAILURE(hr);++#ifdef USE_WEBVIEW2_WIN10+    if (m_dcompDevice || m_wincompCompositor)+#else+    if (m_dcompDevice)+#endif+    {+        CHECK_FAILURE(webViewEnvironment4->CreateCoreWebView2CompositionControllerWithOptions(+            m_mainWindow, options.Get(),+            Callback<ICoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler>(+                [this](+                    HRESULT result,+                    ICoreWebView2CompositionController* compositionController) -> HRESULT {+                    auto controller =+                        wil::com_ptr<ICoreWebView2CompositionController>(compositionController)+                            .query<ICoreWebView2Controller>();+                    return OnCreateCoreWebView2ControllerCompleted(result, controller.get());+                })+                .Get()));+    }+    else+    {+        CHECK_FAILURE(webViewEnvironment4->CreateCoreWebView2ControllerWithOptions(+            m_mainWindow, options.Get(),+            Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(+                this, &AppWindow::OnCreateCoreWebView2ControllerCompleted)+                .Get()));+    }++    return S_OK;+}+```++### Access the profile property of WebView2++```cpp+HRESULT AppWindow::OnCreateCoreWebView2ControllerCompleted(HRESULT result, ICoreWebView2Controller* controller)+{+    // ...++    m_controller = controller;+    +    // Gets the webview object from controller.+    wil::com_ptr<ICoreWebView2> coreWebView2;+    CHECK_FAILURE(m_controller->get_CoreWebView2(&coreWebView2));++    auto webview7 = coreWebView2.try_query<ICoreWebView2_7>();+    if (webview7)+    {+        // Gets the profile property of webview.+        wil::com_ptr<ICoreWebView2Profile> profile;+        CHECK_FAILURE(webview7->get_Profile(&profile));++        // Accesses the profile object.+        BOOL inPrivateModeEnabled = FALSE;+        CHECK_FAILURE(profile->get_IsInPrivateModeEnabled(&inPrivateModeEnabled));+        wil::unique_cotaskmem_string profile_path;+        CHECK_FAILURE(profile->get_ProfilePath(&profile_path));+        std::wstring str(profile_path.get());+        m_profileDirName = str.substr(str.find_last_of(L'\\') + 1);+        +        // update window title with m_profileDirName+        UpdateAppTitle();++        // update window icon+        SetAppIcon(inPrivate);        +    }+  +    // ...+}+```+## .NET and WinRT++### Create WebView2 with a specific profile, then access the profile property of WebView2++```csharp+CoreWebView2Environment _webViewEnvironment;+public CreateWebView2ControllerWithOptions(IntPtr parentHWND, string profileName, bool isInPrivate)+{+    CoreWebView2ControllerOptions options = _webViewEnvironment.CreateCoreWebView2ControllerOptions(profileName, isInPrivate);+    CoreWebView2Controller webView2Controller = await _webViewEnvironment.CreateCoreWebView2ControllerWithOptionsAsync(parentHWND, options);+    string profilePath = webView2Controller.CoreWebView2.Profile.ProfilePath;+    string profileDirName = profilePath.Substring(profilePath.LastIndexOf('\\') + 1);+    bool inPrivate = webView2Controller.CoreWebView2.Profile.IsInPrivateModeEnabled;++    // update window title with profileDirName+    UpdateAppTitle();++    // update window icon+    SetAppIcon(inPrivate);+}+```++# API Details++## Win32 C++++```IDL+interface ICoreWebView2ControllerOptions;+interface ICoreWebView2Environment5;+interface ICoreWebView2_7;+interface ICoreWebView2Profile;++[uuid(C2669A3A-03A9-45E9-97EA-03CD55E5DC03), object, pointer_default(unique)]+interface ICoreWebView2ControllerOptions : IUnknown {+  /// `ProfileName` property is to specify a profile name, which is only allowed to contain+  /// the following ASCII characters. It has a maximum length of 64 characters excluding the null terminator. It is+  /// ASCII case insensitive.+  ///    alphabet characters: a-z and A-Z+  ///    digit characters: 0-9+  ///    and '#', '@', '$', '(', ')', '+', '-', '_', '~', '.', ' ' (space).+  /// Note: the text must not end with a period '.' or ' ' (space). And, although upper case letters are+  /// allowed, they're treated just as lower case couterparts because the profile name will be mapped to+  /// the real profile directory path on disk and Windows file system handles path names in a case-insensitive way.+  [propget] HRESULT ProfileName([out, retval] LPWSTR* value);+  /// Sets the `ProfileName` property.+  [propput] HRESULT ProfileName([in] LPCWSTR value);++  /// `IsInPrivateModeEnabled` property is to enable/disable InPrivate mode.+  [propget] HRESULT IsInPrivateModeEnabled([out, retval] BOOL* value);+  /// Sets the `IsInPrivateModeEnabled` property.+  [propput] HRESULT IsInPrivateModeEnabled([in] BOOL value);+}++[uuid(57FD205C-39D5-4BA1-8E7B-3E53C323EA87), object, pointer_default(unique)]+interface ICoreWebView2Environment5 : IUnknown+{+  /// Create a new ICoreWebView2ControllerOptions to be passed as a parameter of+  /// CreateCoreWebView2ControllerWithOptions and CreateCoreWebView2CompositionControllerWithOptions.+  /// Returns E_INVALIDARG only in case of invalid profile name.+  HRESULT CreateCoreWebView2ControllerOptions(+      [in] LPCWSTR profileName,+      [in] BOOL isInPrivateModeEnabled,+      [out, retval] ICoreWebView2ControllerOptions** options);++  /// Create a new WebView with options.+  HRESULT CreateCoreWebView2ControllerWithOptions(+      [in] HWND parentWindow,+      [in] ICoreWebView2ControllerOptions* options,+      [in] ICoreWebView2CreateCoreWebView2ControllerCompletedHandler* handler);++  /// Create a new WebView in visual hosting mode with options.+  HRESULT CreateCoreWebView2CompositionControllerWithOptions(+      [in] HWND parentWindow,+      [in] ICoreWebView2ControllerOptions* options,+      [in] ICoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler* handler);+}++[uuid(6E5CE5F0-16E6-4A05-97D8-4E256B3EB609), object, pointer_default(unique)]+interface ICoreWebView2_7 : IUnknown {+  /// The associated `ICoreWebView2Profile` object.+  [propget] HRESULT Profile([out, retval] ICoreWebView2Profile** value);+}++[uuid(3B9A2AF2-E703-4C81-9D25-FCE44312E960), object, pointer_default(unique)]+interface ICoreWebView2Profile : IUnknown {+  /// Name of the profile.+  [propget] HRESULT ProfileName([out, retval] LPWSTR* value);++  /// InPrivate mode is enabled or not.+  [propget] HRESULT IsInPrivateModeEnabled([out, retval] BOOL* value);++  /// Full path of the profile directory.+  [propget] HRESULT ProfilePath([out, retval] LPWSTR* value);++  // TODO: All profile-wide operations/settings will be put below in the future.+}+```++## .NET and WinRT++```c#+namespace Microsoft.Web.WebView2.Core+{+    runtimeclass CoreWebView2ControllerOptions;+    runtimeclass CoreWebView2Environment;+    runtimeclass CoreWebView2;+    runtimeclass CoreWebView2Profile;++    runtimeclass CoreWebView2ControllerOptions+    {        +        String ProfileName { get; set; };++        Boolean IsInPrivateModeEnabled { get; set; };+    }+    +    runtimeclass CoreWebView2Environment+    {+        // ...+    +        CoreWebView2ControllerOptions CreateCoreWebView2ControllerOptions(+            String ProfileName, Boolean InPrivateModeEnabled);+        +        Windows.Foundation.IAsyncOperation<CoreWebView2Controller>+        CreateCoreWebView2ControllerWithOptionsAsync(

Yes please add for .NET and WinRT

leonhsl

comment created time in 2 days

Pull request review commentMicrosoftEdge/WebView2Feedback

API Review: multiple profile support

+API spec for multiple profile support+===++# Background++Previously, all WebView2s can only use one fixed Edge profile in the browser process, which is+normally the **Default** profile or the profile specified by the **--profile-directory** command+line switch. It means different WebView2s share a single profile directory on disk for data storage,+which might bring security concerns over cookies, autofill data, and password management etc.. Also,+they might also interfere with each other in terms of user preference settings.++Although you can make your WebView2s use different user data directories to achieve data separation,+in such way you'll have to be running multiple browser instances (each including a browser process+and a bunch of child processes), which means much more consumption for system resources including+memory, CPU footprint, disk space etc. so it is not desirable.++With all above, we're adding these new APIs to support multiple profiles, so that you can have+multiple WebView2s running with separate profiles under a single user data directory (i.e. a single+browser instance at runtime), which means separate cookies, user preference settings, and various+data storage etc., to help you build a more wonderful experience for your application.++# Examples++## Win32 C++++### Provide options to create WebView2 with a specific profile++```cpp+HRESULT AppWindow::CreateControllerWithOptions()+{+    auto webViewEnvironment4 =+        m_webViewEnvironment.try_query<ICoreWebView2Environment4>();+    if (!webViewEnvironment4)+    {+        FeatureNotAvailable();+        return S_OK;+    }++    Microsoft::WRL::ComPtr<ICoreWebView2ControllerOptions> options;+    HRESULT hr = webViewEnvironment4->CreateCoreWebView2ControllerOptions(+        m_webviewOption.profile.c_str(), m_webviewOption.isInPrivate, options.GetAddressOf());+    if (hr == E_INVALIDARG)+    {+        ShowFailure(hr, L"Unable to create WebView2 due to an invalid profile name.");+        CloseAppWindow();+        return S_OK;+    }+    CHECK_FAILURE(hr);++#ifdef USE_WEBVIEW2_WIN10+    if (m_dcompDevice || m_wincompCompositor)+#else+    if (m_dcompDevice)+#endif+    {+        CHECK_FAILURE(webViewEnvironment4->CreateCoreWebView2CompositionControllerWithOptions(+            m_mainWindow, options.Get(),+            Callback<ICoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler>(+                [this](+                    HRESULT result,+                    ICoreWebView2CompositionController* compositionController) -> HRESULT {+                    auto controller =+                        wil::com_ptr<ICoreWebView2CompositionController>(compositionController)+                            .query<ICoreWebView2Controller>();+                    return OnCreateCoreWebView2ControllerCompleted(result, controller.get());+                })+                .Get()));+    }+    else+    {+        CHECK_FAILURE(webViewEnvironment4->CreateCoreWebView2ControllerWithOptions(+            m_mainWindow, options.Get(),+            Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(+                this, &AppWindow::OnCreateCoreWebView2ControllerCompleted)+                .Get()));+    }++    return S_OK;+}+```++### Access the profile property of WebView2++```cpp+HRESULT AppWindow::OnCreateCoreWebView2ControllerCompleted(HRESULT result, ICoreWebView2Controller* controller)+{+    // ...++    m_controller = controller;+    +    // Gets the webview object from controller.+    wil::com_ptr<ICoreWebView2> coreWebView2;+    CHECK_FAILURE(m_controller->get_CoreWebView2(&coreWebView2));++    auto webview7 = coreWebView2.try_query<ICoreWebView2_7>();+    if (webview7)+    {+        // Gets the profile property of webview.+        wil::com_ptr<ICoreWebView2Profile> profile;+        CHECK_FAILURE(webview7->get_Profile(&profile));++        // Accesses the profile object.+        BOOL inPrivateModeEnabled = FALSE;+        CHECK_FAILURE(profile->get_IsInPrivateModeEnabled(&inPrivateModeEnabled));+        wil::unique_cotaskmem_string profile_path;+        CHECK_FAILURE(profile->get_ProfilePath(&profile_path));+        std::wstring str(profile_path.get());+        m_profileDirName = str.substr(str.find_last_of(L'\\') + 1);+        +        // update window title with m_profileDirName+        UpdateAppTitle();++        // update window icon+        SetAppIcon(inPrivate);        +    }+  +    // ...+}+```+## .NET and WinRT++### Create WebView2 with a specific profile, then access the profile property of WebView2++```csharp+CoreWebView2Environment _webViewEnvironment;+public CreateWebView2ControllerWithOptions(IntPtr parentHWND, string profileName, bool isInPrivate)+{+    CoreWebView2ControllerOptions options = _webViewEnvironment.CreateCoreWebView2ControllerOptions(profileName, isInPrivate);+    CoreWebView2Controller webView2Controller = await _webViewEnvironment.CreateCoreWebView2ControllerWithOptionsAsync(parentHWND, options);+    string profilePath = webView2Controller.CoreWebView2.Profile.ProfilePath;+    string profileDirName = profilePath.Substring(profilePath.LastIndexOf('\\') + 1);+    bool inPrivate = webView2Controller.CoreWebView2.Profile.IsInPrivateModeEnabled;++    // update window title with profileDirName+    UpdateAppTitle();++    // update window icon+    SetAppIcon(inPrivate);+}+```++# API Details++## Win32 C++++```IDL+interface ICoreWebView2ControllerOptions;+interface ICoreWebView2Environment5;+interface ICoreWebView2_7;+interface ICoreWebView2Profile;++[uuid(C2669A3A-03A9-45E9-97EA-03CD55E5DC03), object, pointer_default(unique)]+interface ICoreWebView2ControllerOptions : IUnknown {+  /// `ProfileName` property is to specify a profile name, which is only allowed to contain+  /// the following ASCII characters. It has a maximum length of 64 characters excluding the null terminator. It is+  /// ASCII case insensitive.+  ///    alphabet characters: a-z and A-Z+  ///    digit characters: 0-9+  ///    and '#', '@', '$', '(', ')', '+', '-', '_', '~', '.', ' ' (space).+  /// Note: the text must not end with a period '.' or ' ' (space). And, although upper case letters are+  /// allowed, they're treated just as lower case couterparts because the profile name will be mapped to+  /// the real profile directory path on disk and Windows file system handles path names in a case-insensitive way.+  [propget] HRESULT ProfileName([out, retval] LPWSTR* value);+  /// Sets the `ProfileName` property.+  [propput] HRESULT ProfileName([in] LPCWSTR value);++  /// `IsInPrivateModeEnabled` property is to enable/disable InPrivate mode.+  [propget] HRESULT IsInPrivateModeEnabled([out, retval] BOOL* value);+  /// Sets the `IsInPrivateModeEnabled` property.+  [propput] HRESULT IsInPrivateModeEnabled([in] BOOL value);+}++[uuid(57FD205C-39D5-4BA1-8E7B-3E53C323EA87), object, pointer_default(unique)]+interface ICoreWebView2Environment5 : IUnknown+{+  /// Create a new ICoreWebView2ControllerOptions to be passed as a parameter of+  /// CreateCoreWebView2ControllerWithOptions and CreateCoreWebView2CompositionControllerWithOptions.+  /// Returns E_INVALIDARG only in case of invalid profile name.+  HRESULT CreateCoreWebView2ControllerOptions(+      [in] LPCWSTR profileName,+      [in] BOOL isInPrivateModeEnabled,+      [out, retval] ICoreWebView2ControllerOptions** options);++  /// Create a new WebView with options.+  HRESULT CreateCoreWebView2ControllerWithOptions(+      [in] HWND parentWindow,+      [in] ICoreWebView2ControllerOptions* options,+      [in] ICoreWebView2CreateCoreWebView2ControllerCompletedHandler* handler);++  /// Create a new WebView in visual hosting mode with options.+  HRESULT CreateCoreWebView2CompositionControllerWithOptions(+      [in] HWND parentWindow,+      [in] ICoreWebView2ControllerOptions* options,+      [in] ICoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler* handler);+}++[uuid(6E5CE5F0-16E6-4A05-97D8-4E256B3EB609), object, pointer_default(unique)]+interface ICoreWebView2_7 : IUnknown {+  /// The associated `ICoreWebView2Profile` object.+  [propget] HRESULT Profile([out, retval] ICoreWebView2Profile** value);+}++[uuid(3B9A2AF2-E703-4C81-9D25-FCE44312E960), object, pointer_default(unique)]+interface ICoreWebView2Profile : IUnknown {+  /// Name of the profile.+  [propget] HRESULT ProfileName([out, retval] LPWSTR* value);++  /// InPrivate mode is enabled or not.+  [propget] HRESULT IsInPrivateModeEnabled([out, retval] BOOL* value);++  /// Full path of the profile directory.+  [propget] HRESULT ProfilePath([out, retval] LPWSTR* value);++  // TODO: All profile-wide operations/settings will be put below in the future.+}+```++## .NET and WinRT++```c#+namespace Microsoft.Web.WebView2.Core+{+    runtimeclass CoreWebView2ControllerOptions;+    runtimeclass CoreWebView2Environment;+    runtimeclass CoreWebView2;+    runtimeclass CoreWebView2Profile;++    runtimeclass CoreWebView2ControllerOptions+    {        +        String ProfileName { get; set; };++        Boolean IsInPrivateModeEnabled { get; set; };+    }+    +    runtimeclass CoreWebView2Environment+    {+        // ...+    +        CoreWebView2ControllerOptions CreateCoreWebView2ControllerOptions(+            String ProfileName, Boolean InPrivateModeEnabled);

Yes, please fix.

leonhsl

comment created time in 2 days

Pull request review commentMicrosoftEdge/WebView2Feedback

API Review: multiple profile support

+API spec for multiple profile support+===++# Background++Previously, all WebView2s can only use one fixed Edge profile in the browser process, which is+normally the **Default** profile or the profile specified by the **--profile-directory** command+line switch. It means different WebView2s share a single profile directory on disk for data storage,+which might bring security concerns over cookies, autofill data, and password management etc.. Also,+they might also interfere with each other in terms of user preference settings.++Although you can make your WebView2s use different user data directories to achieve data separation,+in such way you'll have to be running multiple browser instances (each including a browser process+and a bunch of child processes), which means much more consumption for system resources including+memory, CPU footprint, disk space etc. so it is not desirable.++With all above, we're adding these new APIs to support multiple profiles, so that you can have+multiple WebView2s running with separate profiles under a single user data directory (i.e. a single+browser instance at runtime), which means separate cookies, user preference settings, and various+data storage etc., to help you build a more wonderful experience for your application.++# Examples++## Win32 C++++### Provide options to create WebView2 with a specific profile++```cpp+HRESULT AppWindow::CreateControllerWithOptions()+{+    auto webViewEnvironment4 =+        m_webViewEnvironment.try_query<ICoreWebView2Environment4>();+    if (!webViewEnvironment4)+    {+        FeatureNotAvailable();+        return S_OK;+    }++    Microsoft::WRL::ComPtr<ICoreWebView2ControllerOptions> options;+    HRESULT hr = webViewEnvironment4->CreateCoreWebView2ControllerOptions(+        m_webviewOption.profile.c_str(), m_webviewOption.isInPrivate, options.GetAddressOf());+    if (hr == E_INVALIDARG)+    {+        ShowFailure(hr, L"Unable to create WebView2 due to an invalid profile name.");+        CloseAppWindow();+        return S_OK;+    }+    CHECK_FAILURE(hr);++#ifdef USE_WEBVIEW2_WIN10

This is artifact of sample app code. For our sample in our documentation we can just assume we're using Win10+ SDK

leonhsl

comment created time in 2 days

Pull request review commentMicrosoftEdge/WebView2Feedback

API Review: multiple profile support

+API spec for multiple profile support+===++# Background++Previously, all WebView2s can only use one fixed Edge profile in the browser process, which is+normally the **Default** profile or the profile specified by the **--profile-directory** command+line switch. It means different WebView2s share a single profile directory on disk for data storage,+which might bring security concerns over cookies, autofill data, and password management etc.. Also,+they might also interfere with each other in terms of user preference settings.++Although you can make your WebView2s use different user data directories to achieve data separation,+in such way you'll have to be running multiple browser instances (each including a browser process+and a bunch of child processes), which means much more consumption for system resources including+memory, CPU footprint, disk space etc. so it is not desirable.++With all above, we're adding these new APIs to support multiple profiles, so that you can have+multiple WebView2s running with separate profiles under a single user data directory (i.e. a single+browser instance at runtime), which means separate cookies, user preference settings, and various+data storage etc., to help you build a more wonderful experience for your application.++# Examples++## Win32 C++++### Provide options to create WebView2 with a specific profile++```cpp+HRESULT AppWindow::CreateControllerWithOptions()+{+    auto webViewEnvironment4 =+        m_webViewEnvironment.try_query<ICoreWebView2Environment4>();+    if (!webViewEnvironment4)+    {+        FeatureNotAvailable();+        return S_OK;+    }++    Microsoft::WRL::ComPtr<ICoreWebView2ControllerOptions> options;+    HRESULT hr = webViewEnvironment4->CreateCoreWebView2ControllerOptions(+        m_webviewOption.profile.c_str(), m_webviewOption.isInPrivate, options.GetAddressOf());+    if (hr == E_INVALIDARG)

Correct, reused. Must document

leonhsl

comment created time in 2 days