I've a problem with a popup and print it to pdf silently.
When I push print button (on the site), it's open a popup, generate a barcode and then popup prints.
The popup contain two js functions window.print()
and then window.close()
.
I need to print this popup silently to pdf, but I don't found nothing about this method.
Currently I intercept through ILifeSpanHandler, but targetUrl contain a static link and not contain barcode generated. I think the popup must be print as is bypassing window.print()
and block print dialog.
Can someone help me?
Thank you so much.
EDITED
This is the js popup that I need to print silently to pdf. It is parent popup:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title></title>
<script src="xxxx"></script>
<script src="xxxx/js/jquery-1.11.1.min.js" type="text/javascript"></script>
<script src="xxxx/js/lib/barcode/JsBarcode.all.min.js?v=20200729001"></script>
<script src="xxxx/js/lib/qrcode/qrcode.min.js?v=20200729001"></script>
<style>
#logo, #barcodes, #qrcode{
text-align:center;
}
img{
display:initial!important;
}
</style>
</head>
<script type="text/javascript">
$(document).ready(function() {
var qrcode = window.qrcode;
var parentData = window.data;
console.log(parentData);
console.log("Start");
var c = parentData;
var id = 'id-'+c;
if(qrcode){
$("#barcodes").append("<div id='"+id+"' style=\"text-align:center;\"/><br/>");
new QRCode(document.getElementById(id), {
text: c,
width: 128,
height: 128,
colorDark : "#000000",
colorLight : "#ffffff",
correctLevel : QRCode.CorrectLevel.H
});
$('#'+id).append('<br/> <br/> <div id="qrcode" style="font-weight:bold;">' + c + '</div>');
}else{
$("#barcodes").append("<img id='"+id+"' /><br/>");
JsBarcode("#" + id, c, {format: "CODE128", height:60});
}
console.log(parentData);
console.log("End");
console.log(parentData);
});
</script>
<body>
<div id="logo">
<img style=" height: auto; width: auto; max-width: 300px; max-height: 300px;" src="xxxx">
<br>
<img style="height: auto; width: auto; max-width: 253px; max-height: 253px;" src="xxxx">
</div>
<br />
<div id="barcodes"></div>
</body>
</html>
window.data
(coupon) is passed through key cookie value.
I think that ILifeSpanHandler
must intecpet and print to pdf file and close it self.
EDITED
I've tried:
using System;
using System.IO;
using CefSharp;
namespace CefSharp
{
public class EnablePrint : ILifeSpanHandler
{
bool ILifeSpanHandler.DoClose(IWebBrowser chromiumWebBrowser, IBrowser browser)
{
var coupon = browser.PrintToPdfAsync("c://coupon//text.pdf", new PdfPrintSettings
{
MarginType = CefPdfPrintMarginType.Custom,
MarginBottom = 0,
MarginTop = 0,
MarginLeft = 0,
MarginRight = 0,
ScaleFactor = 95
});
coupon.ContinueWith(exit =>
browser.GetHost().CloseBrowser(true));
return true;
}
void ILifeSpanHandler.OnAfterCreated(IWebBrowser chromiumWebBrowser, IBrowser browser)
{
}
void ILifeSpanHandler.OnBeforeClose(IWebBrowser chromiumWebBrowser, IBrowser browser)
{
}
bool ILifeSpanHandler.OnBeforePopup(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, string targetUrl, string targetFrameName, WindowOpenDisposition targetDisposition, bool userGesture, IPopupFeatures popupFeatures, IWindowInfo windowInfo, IBrowserSettings browserSettings, ref bool noJavascriptAccess, out IWebBrowser newBrowser)
{
newBrowser = null;
return false;
}
}
}
This code generate an exception:
System.ObjectDisposedException
HResult=0x80131622
Messaggio=Impossibile accedere a un oggetto eliminato.
Nome oggetto: 'This instance of CefSharp.IBrowser been disposed!'.
Origine=CefSharp.Core
Analisi dello stack:
in CefSharp.Internals.CefWrapper.ThrowIfDisposed()
in CefSharp.Internals.CefSharpBrowserWrapper.GetHost()
in PremierClient_x86.EnablePrint.<>c__DisplayClass0_0.<CefSharp.ILifeSpanHandler.DoClose>b__0(Task`1 exit) in C:\Users\XXXXXXX\EnablePrint.cs: riga 23
in System.Threading.Tasks.ContinuationTaskFromResultTask`1.InnerInvoke()
in System.Threading.Tasks.Task.Execute()
The popup ramian on front and I cannot manually close.
Based on the example give above you'll have to close the popup window manually, which is easy enough. The code will look something like below (it compiles though I haven't tested as I don't have a working example to go from).
using System;
using System.Runtime.InteropServices;
using CefSharp;
namespace CefSharp.MinimalExample.WinForms
{
public class LifeSpanHandler : ILifeSpanHandler
{
[DllImport("user32.dll")]
private static extern bool DestroyWindow(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern IntPtr GetTopWindow(IntPtr hWnd);
bool ILifeSpanHandler.DoClose(IWebBrowser chromiumWebBrowser, IBrowser browser)
{
//Only do this for popups
if(!browser.IsPopup)
{
return false;
}
var hwnd = browser.GetHost().GetWindowHandle();
browser.PrintToPdfAsync("c://coupon//text.pdf", new PdfPrintSettings()).ContinueWith(exit =>
{
//You may need to get the top level window and close that instead
//var parentHwnd = GetTopWindow(hwnd);
//DestroyWindow(parentHwnd);
//Close the browser, if the popup window doesn't close then
//get the top level window and close that instead (code commented out above)
DestroyWindow(hwnd);
});
//Cancel close, destroy window manually after pdf generated
return true;
}
void ILifeSpanHandler.OnAfterCreated(IWebBrowser chromiumWebBrowser, IBrowser browser)
{
}
void ILifeSpanHandler.OnBeforeClose(IWebBrowser chromiumWebBrowser, IBrowser browser)
{
}
bool ILifeSpanHandler.OnBeforePopup(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, string targetUrl, string targetFrameName, WindowOpenDisposition targetDisposition, bool userGesture, IPopupFeatures popupFeatures, IWindowInfo windowInfo, IBrowserSettings browserSettings, ref bool noJavascriptAccess, out IWebBrowser newBrowser)
{
newBrowser = null;
return false;
}
}
}
Additionally to avoid showing the print dialog you can inject some javascript to override window.print and make it a noop
namespace CefSharp.MinimalExample.WinForms
{
internal class LoadHandler : ILoadHandler
{
void ILoadHandler.OnFrameLoadEnd(IWebBrowser chromiumWebBrowser, FrameLoadEndEventArgs args)
{
}
void ILoadHandler.OnFrameLoadStart(IWebBrowser chromiumWebBrowser, FrameLoadStartEventArgs args)
{
if (args.Browser.IsPopup)
{
//Override window.print so it does nothing
args.Browser.MainFrame.ExecuteJavaScriptAsync("window.print = function () { };");
}
}
void ILoadHandler.OnLoadError(IWebBrowser chromiumWebBrowser, LoadErrorEventArgs args)
{
}
void ILoadHandler.OnLoadingStateChange(IWebBrowser chromiumWebBrowser, LoadingStateChangedEventArgs args)
{
}
}
}
User contributions licensed under CC BY-SA 3.0