// Copyright (C) Microsoft Corporation. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Data.Common; using System.Diagnostics; using System.IO; using System.Linq; using System.Net; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.Windows.Threading; using Microsoft.Web.WebView2.Core; using Microsoft.Web.WebView2.Wpf; namespace WebView2WpfBrowser { /// /// Interaction logic for MainWindow.xaml /// public partial class MainWindow : Window { #region commands public static RoutedCommand InjectScriptCommand = new RoutedCommand(); public static RoutedCommand InjectScriptIFrameCommand = new RoutedCommand(); public static RoutedCommand InjectScriptWithResultCommand = new RoutedCommand(); public static RoutedCommand PrintToPdfCommand = new RoutedCommand(); public static RoutedCommand NavigateWithWebResourceRequestCommand = new RoutedCommand(); public static RoutedCommand DOMContentLoadedCommand = new RoutedCommand(); public static RoutedCommand WebMessagesCommand = new RoutedCommand(); public static RoutedCommand GetCookiesCommand = new RoutedCommand(); public static RoutedCommand SuspendCommand = new RoutedCommand(); public static RoutedCommand ResumeCommand = new RoutedCommand(); public static RoutedCommand CheckUpdateCommand = new RoutedCommand(); public static RoutedCommand NewBrowserVersionCommand = new RoutedCommand(); public static RoutedCommand PdfToolbarSaveCommand = new RoutedCommand(); public static RoutedCommand SmartScreenEnabledCommand = new RoutedCommand(); public static RoutedCommand AuthenticationCommand = new RoutedCommand(); public static RoutedCommand FaviconChangedCommand = new RoutedCommand(); public static RoutedCommand ClearBrowsingDataCommand = new RoutedCommand(); public static RoutedCommand SetDefaultDownloadPathCommand = new RoutedCommand(); public static RoutedCommand CreateDownloadsButtonCommand = new RoutedCommand(); public static RoutedCommand ShowExtensionsWindowCommand = new RoutedCommand(); public static RoutedCommand CustomClientCertificateSelectionCommand = new RoutedCommand(); public static RoutedCommand CustomContextMenuCommand = new RoutedCommand(); public static RoutedCommand DeferredCustomCertificateDialogCommand = new RoutedCommand(); public static RoutedCommand BackgroundColorCommand = new RoutedCommand(); public static RoutedCommand DownloadStartingCommand = new RoutedCommand(); public static RoutedCommand AddOrUpdateCookieCommand = new RoutedCommand(); public static RoutedCommand DeleteCookiesCommand = new RoutedCommand(); public static RoutedCommand DeleteAllCookiesCommand = new RoutedCommand(); public static RoutedCommand SetUserAgentCommand = new RoutedCommand(); public static RoutedCommand PasswordAutosaveCommand = new RoutedCommand(); public static RoutedCommand GeneralAutofillCommand = new RoutedCommand(); public static RoutedCommand PinchZoomCommand = new RoutedCommand(); public static RoutedCommand SwipeNavigationCommand = new RoutedCommand(); public static RoutedCommand DeleteProfileCommand = new RoutedCommand(); public static RoutedCommand NonClientRegionSupportCommand = new RoutedCommand(); public static RoutedCommand NonClientRegionSupportEnabledCommand = new RoutedCommand(); public static RoutedCommand ToggleMuteStateCommand = new RoutedCommand(); public static RoutedCommand AllowExternalDropCommand = new RoutedCommand(); public static RoutedCommand LaunchingExternalUriSchemeCommand = new RoutedCommand(); public static RoutedCommand PerfInfoCommand = new RoutedCommand(); public static RoutedCommand CustomServerCertificateSupportCommand = new RoutedCommand(); public static RoutedCommand ClearServerCertificateErrorActionsCommand = new RoutedCommand(); public static RoutedCommand NewWindowWithOptionsCommand = new RoutedCommand(); public static RoutedCommand CreateNewThreadCommand = new RoutedCommand(); public static RoutedCommand ExtensionsCommand = new RoutedCommand(); public static RoutedCommand TrackingPreventionLevelCommand = new RoutedCommand(); public static RoutedCommand EnhancedSecurityModeLevelCommand = new RoutedCommand(); public static RoutedCommand EnhancedSecurityModeGetBypassListCommand = new RoutedCommand(); public static RoutedCommand EnhancedSecurityModeSetBypassListCommand = new RoutedCommand(); public static RoutedCommand EnhancedSecurityModeGetEnforceListCommand = new RoutedCommand(); public static RoutedCommand EnhancedSecurityModeSetEnforceListCommand = new RoutedCommand(); public static RoutedCommand PrintDialogCommand = new RoutedCommand(); public static RoutedCommand PrintToDefaultPrinterCommand = new RoutedCommand(); public static RoutedCommand PrintToPrinterCommand = new RoutedCommand(); public static RoutedCommand PrintToPdfStreamCommand = new RoutedCommand(); // Commands(V2) public static RoutedCommand AboutCommand = new RoutedCommand(); public static RoutedCommand CrashBrowserProcessCommand = new RoutedCommand(); public static RoutedCommand CrashRenderProcessCommand = new RoutedCommand(); public static RoutedCommand GetDocumentTitleCommand = new RoutedCommand(); public static RoutedCommand GetUserDataFolderCommand = new RoutedCommand(); public static RoutedCommand SharedBufferRequestedCommand = new RoutedCommand(); public static RoutedCommand PostMessageStringCommand = new RoutedCommand(); public static RoutedCommand PostMessageJSONCommand = new RoutedCommand(); public static RoutedCommand CloseWebViewCommand = new RoutedCommand(); public static RoutedCommand NewWebViewCommand = new RoutedCommand(); public static RoutedCommand NewWebViewCompositionControlCommand = new RoutedCommand(); public static RoutedCommand HostObjectsAllowedCommand = new RoutedCommand(); public static RoutedCommand BrowserAcceleratorKeyEnabledCommand = new RoutedCommand(); public static RoutedCommand AddInitializeScriptCommand = new RoutedCommand(); public static RoutedCommand RemoveInitializeScriptCommand = new RoutedCommand(); public static RoutedCommand CallCdpMethodCommand = new RoutedCommand(); public static RoutedCommand OpenDevToolsCommand = new RoutedCommand(); public static RoutedCommand OpenTaskManagerCommand = new RoutedCommand(); public static RoutedCommand PermissionManagementCommand = new RoutedCommand(); public static RoutedCommand NotificationReceivedCommand = new RoutedCommand(); public static RoutedCommand SetCustomDataPartitionCommand = new RoutedCommand(); public static RoutedCommand ClearCustomDataPartitionCommand = new RoutedCommand(); public static RoutedCommand ProcessExtendedInfoCommand = new RoutedCommand(); public static RoutedCommand ProgrammaticSaveAsCommand = new RoutedCommand(); public static RoutedCommand ToggleSilentCommand = new RoutedCommand(); public static RoutedCommand ThrottlingControlCommand = new RoutedCommand(); public static RoutedCommand FileExplorerCommand = new RoutedCommand(); public static RoutedCommand ToggleScreenCaptureEnableCommand = new RoutedCommand(); public static RoutedCommand FileTypePolicyCommand = new RoutedCommand(); public static RoutedCommand ServiceWorkerRegisteredCommand = new RoutedCommand(); public static RoutedCommand GetServiceWorkerRegistrationsCommand = new RoutedCommand(); public static RoutedCommand GetServiceWorkerRegisteredForScopeCommand = new RoutedCommand(); public static RoutedCommand ServiceWorkerPostMessageCommand = new RoutedCommand(); public static RoutedCommand DedicatedWorkerCreatedCommand = new RoutedCommand(); public static RoutedCommand DedicatedWorkerPostMessageCommand = new RoutedCommand(); public static RoutedCommand SharedWorkerManagerCommand = new RoutedCommand(); public static RoutedCommand GetSharedWorkersCommand = new RoutedCommand(); public static RoutedCommand ServiceWorkerSyncManagerCommand = new RoutedCommand(); public static RoutedCommand ChildFrameEventsCommand = new RoutedCommand(); public static RoutedCommand RemoveChildFrameEventsCommand = new RoutedCommand(); public static RoutedCommand StartCommand = new RoutedCommand(); public static RoutedCommand FindNextCommand = new RoutedCommand(); public static RoutedCommand FindPreviousCommand = new RoutedCommand(); public static RoutedCommand StopFindCommand = new RoutedCommand(); public static RoutedCommand FindTermCommand = new RoutedCommand(); public static RoutedCommand GetMatchCountCommand = new RoutedCommand(); public static RoutedCommand GetActiveMatchIndexCommand = new RoutedCommand(); public static RoutedCommand ToggleCaseSensitiveCommand = new RoutedCommand(); public static RoutedCommand ToggleShouldHighlightAllMatchesCommand = new RoutedCommand(); public static RoutedCommand ToggleShouldMatchWordCommand = new RoutedCommand(); public static RoutedCommand ToggleSuppressDefaultFindDialogCommand = new RoutedCommand(); #endregion commands bool _isNavigating = false; // for add/remove initialize script string m_lastInitializeScriptId; CoreWebView2Settings _webViewSettings; CoreWebView2Settings WebViewSettings { get { if (_webViewSettings == null && _iWebView2?.CoreWebView2 != null) { _webViewSettings = _iWebView2.CoreWebView2.Settings; } return _webViewSettings; } } CoreWebView2Environment _webViewEnvironment; CoreWebView2Environment WebViewEnvironment { get { if (_webViewEnvironment == null && _iWebView2?.CoreWebView2 != null) { _webViewEnvironment = _iWebView2.CoreWebView2.Environment; } return _webViewEnvironment; } } CoreWebView2Profile _webViewProfile; CoreWebView2Profile WebViewProfile { get { if (_webViewProfile == null && _iWebView2?.CoreWebView2 != null) { // _webViewProfile = _iWebView2.CoreWebView2.Profile; // } return _webViewProfile; } } // Try not to set these directly. Instead these should be updated by calling SetWebView(). // We can switch between using a WebView2 or WebView2CompositionControl element. bool _useCompositionControl = false; WebView2CompositionControl webView2CompositionControlXamlElement = null; private FrameworkElement _webView2FrameworkElement; // Helper reference pointing to the current WV2 control. private IWebView2 _iWebView2; // Helper reference pointing to the current WV2 control. bool _isNewWindowRequest = false; List _webViewFrames = new List(); IReadOnlyList _processList = new List(); IDictionary<(string, CoreWebView2PermissionKind, bool), bool> _cachedPermissions = new Dictionary<(string, CoreWebView2PermissionKind, bool), bool>(); List _permissionKinds = new List { CoreWebView2PermissionKind.Microphone, CoreWebView2PermissionKind.Camera, CoreWebView2PermissionKind.Geolocation, CoreWebView2PermissionKind.Notifications, CoreWebView2PermissionKind.OtherSensors, CoreWebView2PermissionKind.ClipboardRead, CoreWebView2PermissionKind.MultipleAutomaticDownloads, CoreWebView2PermissionKind.FileReadWrite, CoreWebView2PermissionKind.Autoplay, CoreWebView2PermissionKind.LocalFonts, CoreWebView2PermissionKind.MidiSystemExclusiveMessages, CoreWebView2PermissionKind.WindowManagement, }; List _permissionStates = new List { CoreWebView2PermissionState.Allow, CoreWebView2PermissionState.Deny, CoreWebView2PermissionState.Default }; List _saveAsKindList = new List { CoreWebView2SaveAsKind.Default, CoreWebView2SaveAsKind.HtmlOnly, CoreWebView2SaveAsKind.SingleFile, CoreWebView2SaveAsKind.Complete, }; public CoreWebView2CreationProperties CreationProperties { get; set; } = null; public MainWindow() : this(null, false) { } public MainWindow( CoreWebView2CreationProperties creationProperties = null, bool isNewWindowRequest = false) { this.CreationProperties = creationProperties; DataContext = this; Loaded += MainWindow_Loaded; _isNewWindowRequest = isNewWindowRequest; InitializeComponent(); } private async void MainWindow_Loaded(object sender, RoutedEventArgs e) { // We default to a regular WebView2 control. this.CreationProperties = this.CreationProperties ?? webView2XamlElement.CreationProperties; SetWebView(webView2XamlElement, false /*useCompositionControl*/); await InitializeWebView(webView2XamlElement); SetWebViewVisibility(true); } // Calling this function sets the various WebView2 control references and updates // the _useCompositionControl value. private void SetWebView(IWebView2 newWebView2, bool useCompositionControl) { if (useCompositionControl) { webView2CompositionControlXamlElement = newWebView2 as WebView2CompositionControl; } else { webView2XamlElement = newWebView2 as WebView2; } _webView2FrameworkElement = newWebView2 as FrameworkElement; _iWebView2 = newWebView2; _useCompositionControl = useCompositionControl; // We display the type of control in the window title, so update that now. UpdateTitle(); } async Task InitializeWebView(IWebView2 webView2) { if (this.CreationProperties != null) { webView2.CreationProperties = this.CreationProperties; } AttachControlEventHandlers(webView2); // Set background transparent webView2.DefaultBackgroundColor = System.Drawing.Color.Transparent; await webView2.EnsureCoreWebView2Async(); } // In general, re-initializing a WebView2 involves creating and initializing a new WebView2, and then // swapping it when ready. // We do it in this order to avoid any race conditions of closing the existing WebView2 and having the browser // process exit before the new WebView2 is spun up. async Task ReinitializeWebView(bool useCompositionControl) { // First, create a new control, add it to the visual tree hidden, and initialize it. IWebView2 newWebView = CreateReplacementControl(false /*useNewEnvironment*/, useCompositionControl); (newWebView as FrameworkElement).Visibility = Visibility.Hidden; AttachControlToVisualTree(newWebView as FrameworkElement); await InitializeWebView(newWebView); // Next, remove the existing WebView2 and close it. CloseWebView(); // Add the new control to the visual tree and set it as the current control. SetWebView(newWebView, useCompositionControl); SetWebViewVisibility(true); } void CloseWebView(bool recreate = false) { shouldAttemptReinitOnBrowserExit = recreate; RemoveControlFromVisualTree(_webView2FrameworkElement); _iWebView2?.Dispose(); _webView2FrameworkElement = null; _iWebView2 = null; } void AttachControlEventHandlers(IWebView2 control) { control.NavigationStarting += WebView_NavigationStarting; control.NavigationCompleted += WebView_NavigationCompleted; control.CoreWebView2InitializationCompleted += WebView_CoreWebView2InitializationCompleted; (control as FrameworkElement).KeyDown += WebView_KeyDown; } private void OnWebViewVisibleChecked(object sender, RoutedEventArgs e) { SetWebViewVisibility(true); } private void OnWebViewVisibleUnchecked(object sender, RoutedEventArgs e) { SetWebViewVisibility(false); } private void SetWebViewVisibility(bool visible) { if (_webView2FrameworkElement != null) { _webView2FrameworkElement.Visibility = (visible ? Visibility.Visible : Visibility.Hidden); } webViewVisible.IsChecked = visible; } private bool IsWebViewVisible() { return _webView2FrameworkElement.Visibility == Visibility.Visible; } bool IsWebViewValid() { try { return _iWebView2 != null && _iWebView2.CoreWebView2 != null; } catch (Exception ex) when (ex is ObjectDisposedException || ex is InvalidOperationException) { return false; } } void AssertCondition(bool condition, string message) { if (condition) return; MessageBox.Show(message, "Assertion Failed"); } void NewCmdExecuted(object sender, ExecutedRoutedEventArgs e) { new MainWindow().Show(); } void CloseCmdExecuted(object sender, ExecutedRoutedEventArgs e) { if (_isPrintToPdfInProgress) { var selection = MessageBox.Show( "Print to PDF in progress. Continue closing?", "Print to PDF", MessageBoxButton.YesNo); if (selection == MessageBoxResult.No) { return; } } CloseWebView(); this.Close(); // Close the window } void BackCmdCanExecute(object sender, CanExecuteRoutedEventArgs e) { e.CanExecute = _iWebView2 != null && _iWebView2.CanGoBack; } void BackCmdExecuted(object target, ExecutedRoutedEventArgs e) { _iWebView2.GoBack(); } void ForwardCmdCanExecute(object sender, CanExecuteRoutedEventArgs e) { e.CanExecute = _iWebView2 != null && _iWebView2.CanGoForward; } void ForwardCmdExecuted(object target, ExecutedRoutedEventArgs e) { _iWebView2.GoForward(); } void RefreshCmdCanExecute(object sender, CanExecuteRoutedEventArgs e) { e.CanExecute = IsWebViewValid() && !_isNavigating; } void RefreshCmdExecuted(object target, ExecutedRoutedEventArgs e) { _iWebView2.Reload(); } void BrowseStopCmdCanExecute(object sender, CanExecuteRoutedEventArgs e) { e.CanExecute = IsWebViewValid() && _isNavigating; } void BrowseStopCmdExecuted(object target, ExecutedRoutedEventArgs e) { _iWebView2.Stop(); } void WebViewRequiringCmdsCanExecute(object sender, CanExecuteRoutedEventArgs e) { e.CanExecute = _iWebView2 != null; } void CoreWebView2RequiringCmdsCanExecute(object sender, CanExecuteRoutedEventArgs e) { e.CanExecute = IsWebViewValid(); } void EpxerimentalCmdsCanExecute(object sender, CanExecuteRoutedEventArgs e) { #if USE_WEBVIEW2_EXPERIMENTAL e.CanExecute = true; #else e.CanExecute = false; #endif } void CustomClientCertificateSelectionCmdExecuted(object target, ExecutedRoutedEventArgs e) { EnableCustomClientCertificateSelection(); } void DeferredCustomCertificateDialogCmdExecuted(object target, ExecutedRoutedEventArgs e) { DeferredCustomClientCertificateSelectionDialog(); } void LaunchingExternalUriSchemeCmdExecuted(object target, ExecutedRoutedEventArgs e) { EnableLaunchingExternalUriSchemeSupport(); } void CustomServerCertificateSupportCmdExecuted(object target, ExecutedRoutedEventArgs e) { ToggleCustomServerCertificateSupport(); } void ClearServerCertificateErrorActionsCmdExecuted(object target, ExecutedRoutedEventArgs e) { ClearServerCertificateErrorActions(); } void PrintDialogCmdExecuted(object target, ExecutedRoutedEventArgs e) { ShowPrintUI(target, e); } void PrintToDefaultPrinterCmdExecuted(object target, ExecutedRoutedEventArgs e) { PrintToDefaultPrinter(); } void PrintToPrinterCmdExecuted(object target, ExecutedRoutedEventArgs e) { PrintToPrinter(); } void PrintToPdfStreamCmdExecuted(object target, ExecutedRoutedEventArgs e) { PrintToPdfStream(); } private bool _isControlInVisualTree = true; void RemoveControlFromVisualTree(UIElement control) { if (_isControlInVisualTree) { Layout.Children.Remove(control); } _isControlInVisualTree = false; } void AttachControlToVisualTree(UIElement control) { Layout.Children.Add(control); _isControlInVisualTree = true; } IWebView2 CreateReplacementControl(bool useNewEnvironment, bool useCompositionControl) { IWebView2 replacementControl; if (useCompositionControl) { replacementControl = new WebView2CompositionControl(); } else { replacementControl = new WebView2(); } if (_iWebView2?.CreationProperties != null) { // Setup properties and bindings. if (useNewEnvironment) { // Create a new CoreWebView2CreationProperties instance so the environment // is made anew. replacementControl.CreationProperties = new CoreWebView2CreationProperties(); replacementControl.CreationProperties.BrowserExecutableFolder = _iWebView2.CreationProperties.BrowserExecutableFolder; replacementControl.CreationProperties.Language = _iWebView2.CreationProperties.Language; replacementControl.CreationProperties.UserDataFolder = _iWebView2.CreationProperties.UserDataFolder; replacementControl.CreationProperties.AdditionalBrowserArguments = _iWebView2.CreationProperties.AdditionalBrowserArguments; shouldAttachEnvironmentEventHandlers = true; } else { replacementControl.CreationProperties = _iWebView2.CreationProperties; } } Binding urlBinding = new Binding() { Source = replacementControl, Path = new PropertyPath("Source"), Mode = BindingMode.OneWay }; url.SetBinding(TextBox.TextProperty, urlBinding); AttachControlEventHandlers(replacementControl); return replacementControl; } void WebView_ProcessFailed(object sender, CoreWebView2ProcessFailedEventArgs e) { void ReinitIfSelectedByUser(string caption, string message) { this.Dispatcher.InvokeAsync(() => { var selection = MessageBox.Show(message, caption, MessageBoxButton.YesNo); if (selection == MessageBoxResult.Yes) { // The control cannot be re-initialized so we setup a new instance to replace it. // Note the previous instance of the control is disposed of and removed from the // visual tree before attaching the new one. _ = ReinitializeWebView(_useCompositionControl); } }); } void ReloadIfSelectedByUser(string caption, string message) { this.Dispatcher.InvokeAsync(() => { var selection = MessageBox.Show(message, caption, MessageBoxButton.YesNo); if (selection == MessageBoxResult.Yes) { _iWebView2.Reload(); // Set background transparent _iWebView2.DefaultBackgroundColor = System.Drawing.Color.Transparent; } }); } bool IsAppContentUri(Uri source) { // Sample virtual host name for the app's content. // See CoreWebView2.SetVirtualHostNameToFolderMapping: https://learn.microsoft.com/dotnet/api/microsoft.web.webview2.core.corewebview2.setvirtualhostnametofoldermapping return source.Host == "appassets.example"; } if (e.ProcessFailedKind == CoreWebView2ProcessFailedKind.FrameRenderProcessExited) { // A frame-only renderer has exited unexpectedly. Check if reload is needed. // In this sample we only reload if the app's content has been impacted. foreach (CoreWebView2FrameInfo frameInfo in e.FrameInfosForFailedProcess) { if (IsAppContentUri(new System.Uri(frameInfo.Source))) { System.Threading.SynchronizationContext.Current.Post((_) => { ReloadIfSelectedByUser("App content frame unresponsive", "Browser render process for app frame exited unexpectedly. Reload page?"); }, null); } } return; } // Show the process failure details. Apps can collect info for their logging purposes. this.Dispatcher.InvokeAsync(() => { StringBuilder messageBuilder = new StringBuilder(); messageBuilder.AppendLine($"Process kind: {e.ProcessFailedKind}"); messageBuilder.AppendLine($"Reason: {e.Reason}"); messageBuilder.AppendLine($"Exit code: {e.ExitCode}"); messageBuilder.AppendLine($"Process description: {e.ProcessDescription}"); MessageBox.Show(messageBuilder.ToString(), "Child process failed", MessageBoxButton.OK); }); if (e.ProcessFailedKind == CoreWebView2ProcessFailedKind.BrowserProcessExited) { ReinitIfSelectedByUser("Browser process exited", "Browser process exited unexpectedly. Recreate webview?"); } else if (e.ProcessFailedKind == CoreWebView2ProcessFailedKind.RenderProcessUnresponsive) { ReinitIfSelectedByUser("Web page unresponsive", "Browser render process has stopped responding. Recreate webview?"); } else if (e.ProcessFailedKind == CoreWebView2ProcessFailedKind.RenderProcessExited) { ReloadIfSelectedByUser("Web page unresponsive", "Browser render process exited unexpectedly. Reload page?"); } } double ZoomStep() { if (_iWebView2.ZoomFactor < 1) { return 0.25; } else if (_iWebView2.ZoomFactor < 2) { return 0.5; } else { return 1; } } void IncreaseZoomCmdExecuted(object target, ExecutedRoutedEventArgs e) { _iWebView2.ZoomFactor += ZoomStep(); } void DecreaseZoomCmdCanExecute(object sender, CanExecuteRoutedEventArgs e) { e.CanExecute = (_iWebView2 != null) && (_iWebView2.ZoomFactor - ZoomStep() > 0.0); } void DecreaseZoomCmdExecuted(object target, ExecutedRoutedEventArgs e) { _iWebView2.ZoomFactor -= ZoomStep(); } void BackgroundColorCmdExecuted(object target, ExecutedRoutedEventArgs e) { // System.Drawing.Color backgroundColor = System.Drawing.Color.FromName(e.Parameter.ToString()); _iWebView2.DefaultBackgroundColor = backgroundColor; // } async void InjectScriptCmdExecuted(object target, ExecutedRoutedEventArgs e) { // var dialog = new TextInputDialog( title: "Inject Script", description: "Enter some JavaScript to be executed in the context of this page.", defaultInput: "window.getComputedStyle(document.body).backgroundColor"); if (dialog.ShowDialog() == true) { string scriptResult = await _iWebView2.ExecuteScriptAsync(dialog.Input.Text); MessageBox.Show(this, scriptResult, "Script Result"); } // } async void InjectScriptIFrameCmdExecuted(object target, ExecutedRoutedEventArgs e) { // string iframesData = WebViewFrames_ToString(); string iframesInfo = "Enter iframe to run the JavaScript code in.\r\nAvailable iframes: " + iframesData; var dialogIFrames = new TextInputDialog( title: "Inject Script Into IFrame", description: iframesInfo, defaultInput: "0"); if (dialogIFrames.ShowDialog() == true) { int iframeNumber = -1; try { iframeNumber = Int32.Parse(dialogIFrames.Input.Text); } catch (FormatException) { Console.WriteLine("Can not convert " + dialogIFrames.Input.Text + " to int"); } if (iframeNumber >= 0 && iframeNumber < _webViewFrames.Count) { var dialog = new TextInputDialog( title: "Inject Script", description: "Enter some JavaScript to be executed in the context of iframe " + dialogIFrames.Input.Text, defaultInput: "window.getComputedStyle(document.body).backgroundColor"); if (dialog.ShowDialog() == true) { string scriptResult = await _webViewFrames[iframeNumber].ExecuteScriptAsync(dialog.Input.Text); MessageBox.Show(this, scriptResult, "Script Result"); } } } // } private bool _isPrintToPdfInProgress = false; async void PrintToPdfCmdExecuted(object target, ExecutedRoutedEventArgs e) { if (_isPrintToPdfInProgress) { MessageBox.Show(this, "Print to PDF in progress", "Print To PDF"); return; } try { // CoreWebView2PrintSettings printSettings = null; string orientationString = e.Parameter.ToString(); if (orientationString == "Landscape") { printSettings = WebViewEnvironment.CreatePrintSettings(); printSettings.Orientation = CoreWebView2PrintOrientation.Landscape; } Microsoft.Win32.SaveFileDialog saveFileDialog = new Microsoft.Win32.SaveFileDialog(); saveFileDialog.InitialDirectory = "C:\\"; saveFileDialog.Filter = "Pdf Files|*.pdf"; Nullable result = saveFileDialog.ShowDialog(); if (result == true) { _isPrintToPdfInProgress = true; bool isSuccessful = await _iWebView2.CoreWebView2.PrintToPdfAsync( saveFileDialog.FileName, printSettings); _isPrintToPdfInProgress = false; string message = (isSuccessful) ? "Print to PDF succeeded" : "Print to PDF failed"; MessageBox.Show(this, message, "Print To PDF Completed"); } // } catch (NotImplementedException exception) { MessageBox.Show(this, "Print to PDF Failed: " + exception.Message, "Print to PDF"); } } // Shows the user a print dialog. If `printDialogKind` is browser print preview, // opens a browser print preview dialog, CoreWebView2PrintDialogKind.System opens a system print dialog. void ShowPrintUI(object target, ExecutedRoutedEventArgs e) { string printDialog = e.Parameter.ToString(); if (printDialog == "Browser") { // Opens the browser print preview dialog. _iWebView2.CoreWebView2.ShowPrintUI(); } else { // Opens the system print dialog. _iWebView2.CoreWebView2.ShowPrintUI(CoreWebView2PrintDialogKind.System); } } // This example prints the current web page without a print dialog to default printer. async void PrintToDefaultPrinter() { string title = _iWebView2.CoreWebView2.DocumentTitle; try { // Passing null for `PrintSettings` results in default print settings used. // Prints current web page with the default page and printer settings. CoreWebView2PrintStatus printStatus = await _iWebView2.CoreWebView2.PrintAsync(null); if (printStatus == CoreWebView2PrintStatus.Succeeded) { MessageBox.Show(this, "Printing " + title + " document to printer is succeeded", "Print"); } else if (printStatus == CoreWebView2PrintStatus.PrinterUnavailable) { MessageBox.Show(this, "Printer is not available, offline or error state", "Print"); } else { MessageBox.Show(this, "Printing " + title + " document to printer is failed", "Print"); } } catch (Exception) { MessageBox.Show(this, "Printing " + title + " document already in progress", "Print"); } } // // Function to get printer name by displaying printer text input dialog to the user. // User has to specify the desired printer name by querying the installed printers list on the // OS to print the web page. // You may also choose to display printers list to the user and return user selected printer. string GetPrinterName() { string printerName = ""; var dialog = new TextInputDialog( title: "Printer Name", description: "Specify a printer name from the installed printers list on the OS.", defaultInput: ""); if (dialog.ShowDialog() == true) { printerName = dialog.Input.Text; } return printerName; // or // // Use GetPrintQueues() of LocalPrintServer from System.Printing to get list of locally installed printers. // Display the printer list to the user and get the desired printer to print. // Return the user selected printer name. } // Function to get print settings for the selected printer. // You may also choose get the capabilities from the native printer API, display to the user to get // the print settings for the current web page and for the selected printer. CoreWebView2PrintSettings GetSelectedPrinterPrintSettings(string printerName) { CoreWebView2PrintSettings printSettings = null; printSettings = WebViewEnvironment.CreatePrintSettings(); printSettings.ShouldPrintBackgrounds = true; printSettings.ShouldPrintHeaderAndFooter = true; return printSettings; // or // // Get PrintQueue for the selected printer and use GetPrintCapabilities() of PrintQueue from System.Printing // to get the capabilities of the selected printer. // Display the printer capabilities to the user along with the page settings. // Return the user selected settings. } // This example prints the current web page to the specified printer with the settings. async void PrintToPrinter() { string printerName = GetPrinterName(); CoreWebView2PrintSettings printSettings = GetSelectedPrinterPrintSettings(printerName); string title = _iWebView2.CoreWebView2.DocumentTitle; try { CoreWebView2PrintStatus printStatus = await _iWebView2.CoreWebView2.PrintAsync(printSettings); if (printStatus == CoreWebView2PrintStatus.Succeeded) { MessageBox.Show(this, "Printing " + title + " document to printer is succeeded", "Print to printer"); } else if (printStatus == CoreWebView2PrintStatus.PrinterUnavailable) { MessageBox.Show(this, "Selected printer is not found, not available, offline or error state", "Print to printer"); } else { MessageBox.Show(this, "Printing " + title + " document to printer is failed", "Print"); } } catch (ArgumentException) { MessageBox.Show(this, "Invalid settings provided for the specified printer", "Print"); } catch (Exception) { MessageBox.Show(this, "Printing " + title + " document already in progress", "Print"); } } // // // This example prints the Pdf data of the current web page to a stream. async void PrintToPdfStream() { try { string title = _iWebView2.CoreWebView2.DocumentTitle; // Passing null for `PrintSettings` results in default print settings used. System.IO.Stream stream = await _iWebView2.CoreWebView2.PrintToPdfStreamAsync(null); DisplayPdfDataInPrintDialog(stream); MessageBox.Show(this, "Printing" + title + " document to PDF Stream " + ((stream != null) ? "succeeded" : "failed"), "Print To PDF Stream"); } catch (Exception exception) { MessageBox.Show(this, "Printing to PDF Stream failed: " + exception.Message, "Print to PDF Stream"); } } // Function to display current page pdf data in a custom print preview dialog. void DisplayPdfDataInPrintDialog(Stream pdfData) { // You can display the printable pdf data in a custom print preview dialog to the end user. } // void TrackingPreventionLevelCommandExecuted(object target, ExecutedRoutedEventArgs e) { string level = e.Parameter.ToString(); if (level == "None") { SetTrackingPreventionLevel(CoreWebView2TrackingPreventionLevel.None); } else if (level == "Basic") { SetTrackingPreventionLevel(CoreWebView2TrackingPreventionLevel.Basic); } else if (level == "Balanced") { SetTrackingPreventionLevel(CoreWebView2TrackingPreventionLevel.Balanced); } else { SetTrackingPreventionLevel(CoreWebView2TrackingPreventionLevel.Strict); } } // void SetTrackingPreventionLevel(CoreWebView2TrackingPreventionLevel value) { WebViewProfile.PreferredTrackingPreventionLevel = value; MessageBox.Show(this, "Tracking prevention level is set successfully", "Tracking Prevention Level"); } // void EnhancedSecurityModeLevelCommandExecuted(object target, ExecutedRoutedEventArgs e) { } void EnhancedSecurityModeGetBypassListCommandExecuted(object target, ExecutedRoutedEventArgs e) { } void EnhancedSecurityModeSetBypassListCommandExecuted(object target, ExecutedRoutedEventArgs e) { } void EnhancedSecurityModeGetEnforceListCommandExecuted(object target, ExecutedRoutedEventArgs e) { } void EnhancedSecurityModeSetEnforceListCommandExecuted(object target, ExecutedRoutedEventArgs e) { } async void GetCookiesCmdExecuted(object target, ExecutedRoutedEventArgs e) { // List cookieList = await _iWebView2.CoreWebView2.CookieManager.GetCookiesAsync("https://www.bing.com"); StringBuilder cookieResult = new StringBuilder(cookieList.Count + " cookie(s) received from https://www.bing.com\n"); for (int i = 0; i < cookieList.Count; ++i) { CoreWebView2Cookie cookie = _iWebView2.CoreWebView2.CookieManager.CreateCookieWithSystemNetCookie(cookieList[i].ToSystemNetCookie()); cookieResult.Append($"\n{cookie.Name} {cookie.Value} {(cookie.IsSession ? "[session cookie]" : cookie.Expires.ToString("G"))}"); } MessageBox.Show(this, cookieResult.ToString(), "GetCookiesAsync"); // } void AddOrUpdateCookieCmdExecuted(object target, ExecutedRoutedEventArgs e) { // CoreWebView2Cookie cookie = _iWebView2.CoreWebView2.CookieManager.CreateCookie("CookieName", "CookieValue", ".bing.com", "/"); _iWebView2.CoreWebView2.CookieManager.AddOrUpdateCookie(cookie); // } void DeleteAllCookiesCmdExecuted(object target, ExecutedRoutedEventArgs e) { _iWebView2.CoreWebView2.CookieManager.DeleteAllCookies(); } void DeleteCookiesCmdExecuted(object target, ExecutedRoutedEventArgs e) { _iWebView2.CoreWebView2.CookieManager.DeleteCookiesWithDomainAndPath("CookieName", ".bing.com", "/"); } void SetUserAgentCmdExecuted(object target, ExecutedRoutedEventArgs e) { var dialog = new TextInputDialog( title: "SetUserAgent", description: "Enter UserAgent"); if (dialog.ShowDialog() == true) { // WebViewSettings.UserAgent = dialog.Input.Text; // } } void SetCustomDataPartitionCmdExecuted(object target, ExecutedRoutedEventArgs e) { #if USE_WEBVIEW2_EXPERIMENTAL // var dialog = new TextInputDialog( title: "Custom Data Partition", description: "Enter Custom Data Partition Id", defaultInput: _iWebView2.CoreWebView2.CustomDataPartitionId); if (dialog.ShowDialog() == true) { _iWebView2.CoreWebView2.CustomDataPartitionId = dialog.Input.Text; } // #endif } async void ClearCustomDataPartitionCmdExecuted(object target, ExecutedRoutedEventArgs e) { #if USE_WEBVIEW2_EXPERIMENTAL // var dialog = new TextInputDialog( title: "Clear Custom Data Partition", description: "Enter Custom Data Partition Id to clear", defaultInput: _iWebView2.CoreWebView2.CustomDataPartitionId); if (dialog.ShowDialog() == true) { try { await WebViewProfile.ClearCustomDataPartitionAsync(dialog.Input.Text); MessageBox.Show(this, "Completed", "Clear Custom Data Partition"); } catch (Exception exception) { MessageBox.Show(this, "ClearCustomDataPartitionAsync Failed: " + exception.Message, "Clear Custom Data Partition"); } } // #else await Task.CompletedTask; #endif } void WebMessagesCmdExecuted(object target, ExecutedRoutedEventArgs e) { _iWebView2.CoreWebView2.WebMessageReceived += WebView_WebMessageReceived; _iWebView2.CoreWebView2.FrameCreated += WebView_FrameCreatedWebMessages; _iWebView2.CoreWebView2.SetVirtualHostNameToFolderMapping( "appassets.example", "assets", CoreWebView2HostResourceAccessKind.DenyCors); _iWebView2.CoreWebView2.Navigate("https://appassets.example/webMessages.html"); } void HandleWebMessage(CoreWebView2WebMessageReceivedEventArgs args) { try { if (args.Source != "https://appassets.example/webMessages.html") { // Throw exception from untrusted sources. throw new Exception(); } string message = args.TryGetWebMessageAsString(); if (message.Contains("SetTitleText")) { int msgLength = "SetTitleText".Length; this.Title = message.Substring(msgLength); } else if (message == "GetWindowBounds") { string reply = "{\"WindowBounds\":\"Left:" + 0 + "\\nTop:" + 0 + "\\nRight:" + _webView2FrameworkElement.ActualWidth + "\\nBottom:" + _webView2FrameworkElement.ActualHeight + "\"}"; _iWebView2.CoreWebView2.PostWebMessageAsJson(reply); } else { // Ignore unrecognized messages, but log them // since it suggests a mismatch between the web content and the host. Debug.WriteLine($"Unexpected message received: {message}"); } } catch (Exception e) { MessageBox.Show($"Unexpected message received: {e.Message}"); } } void WebView_WebMessageReceived(object sender, CoreWebView2WebMessageReceivedEventArgs args) { HandleWebMessage(args); } // void WebView_FrameCreatedWebMessages(object sender, CoreWebView2FrameCreatedEventArgs args) { args.Frame.WebMessageReceived += (WebMessageReceivedSender, WebMessageReceivedArgs) => { HandleWebMessage(WebMessageReceivedArgs); }; } // // void DOMContentLoadedCmdExecuted(object target, ExecutedRoutedEventArgs e) { _iWebView2.CoreWebView2.DOMContentLoaded += WebView_DOMContentLoaded; _iWebView2.CoreWebView2.FrameCreated += WebView_FrameCreatedDOMContentLoaded; _iWebView2.NavigateToString(@"" + "

DOMContentLoaded sample page

" + "

The content to the iframe and below will be added after DOM content is loaded

" + "