By default in Cefsharp, the print dialog is enabled so websites can interact with it using window.print
. You can as well print the current content of the window by simply right-clicking and selecting Print from the dropdown menu. There are multiple reasons why you wouldn't like to allow such a feature in your project. Many apps that use chromium don't allow such a feature of course just as Discord, Slack, or others.
In this article, I will explain to you the basics to block printing in your WinForms project based on Cefsharp.
1. Disable or customize Cefsharp context menu
As you may know, when launching a simple instance of Cefsharp, the context menu is enabled by default and allows the user to print the page:
You may want to remove this from the context menu as well. We wrote previously 2 different articles about how to remove or customize the context menu of Cefsharp:
- How to prevent the native Context Menu from appearing on a CefSharp control in WinForms
- How to customize new items to the native Context Menu on a CefSharp control in WinForms
According to your needs, you may opt-in for one or another.
2. Override window.print
Now, if you visit a page that interacts with the option to print the document using JavaScript window.print
, it will still work of course. To remove this possibility, you need to overwrite the window.print
method to an empty function. Of course, you may do this directly in JavaScript, however, if you are working with multiple pages that may not include the same JavaScript you may simply achieve this through Cefsharp.
Simply add a method that will be triggered on the FrameLoadStart event. The callback will simply execute plain JavaScript when the frame is ready, which basically overrides the method window.print
with an empty function that shouldn't damage any code, the method won't just work as usual and that's it, the logic should be the following one during the initialization:
// 1. Initialize CefSettings
CefSettings settings = new CefSettings();
// Some settings if you have, here
// Initialize cef with the provided settings
Cef.Initialize(settings);
// 2. Create a browser component
ChromiumWebBrowser chromeBrowser = new ChromiumWebBrowser("www.somewebsite or file.com");
// 3. Assign FrameLoadStart event listener
chromeBrowser.FrameLoadStart += onFrameLoadStart;
// 4. Create listener that injects the JavaScript to prevent a webpage from accesing the window.print method.
/// <summary>
/// Attach a listener to every frame that is launched and remove the JavaScript window.print default function.
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
private void onFrameLoadStart(object sender, FrameLoadStartEventArgs args)
{
args.Frame.ExecuteJavaScriptAsync("window.print = function(){};");
}
The following code applies the mentioned logic in a single initialization of Cefsharp in a single form so you can implement it as well in your own project:
using System;
using System.Windows.Forms;
using CefSharp;
using CefSharp.WinForms;
namespace CefsharpSandbox
{
public partial class Form1 : Form
{
public ChromiumWebBrowser chromeBrowser;
public void InitializeChromium()
{
CefSettings settings = new CefSettings();
// Initialize cef with the provided settings
Cef.Initialize(settings);
// Create a browser component
chromeBrowser = new ChromiumWebBrowser("https://ourcodeworld.com");
// Assign FrameLoadStart event listener
chromeBrowser.FrameLoadStart += onFrameLoadStart;
this.Controls.Add(chromeBrowser);
chromeBrowser.Dock = DockStyle.Fill;
}
public Form1()
{
InitializeComponent();
// Start the browser after initialize global component
InitializeChromium();
}
/// <summary>
/// Attach a listener to every frame that is launched and remove the JavaScript window.print default function.
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
private void onFrameLoadStart(object sender, FrameLoadStartEventArgs args)
{
args.Frame.ExecuteJavaScriptAsync("window.print = function(){};");
}
}
}
Happy coding ❤️!