0

I want to send a pdf file to a printer programmatically and I'm wondering if there is a way of printing a file (send for example a pdf to a printer ) using .net standard libraries (PrintDowument class) or an open source one with MIT license?
Thanks

I tried this

ProcessStartInfo info = new ();
info.Verb = "print";
info.Arguments = "\"" +printerName + "\"";
info.FileName = pdfFilePath;
info.CreateNoWindow = true;
info.UseShellExecute = true;
info.WindowStyle = ProcessWindowStyle.Hidden;

using Process p = new ();
p.StartInfo = info;
p.Start();
p.WaitForInputIdle();
Thread.Sleep(3000);
if (!p.HasExited)
{
    p.Kill();
}

here I have to specify which process to use (Adobe or another) but what I want is to take a pdf and send it to a specified printer without calling an external process.

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
Eagle
  • 1

2 Answers2

0

One possibility is CoreWebView2. It is the same component used by Microsoft Edge for showing content - including PDF documents. Since this is a graphical user control, it only really makes sense for use in client facing applications (WinUI, WPF, Winforms, etc.) where you want to print documents from a document preview. It was not designed for a service even though you may be able to get it to work. (I haven't tried.)

Check these two methods:

Here's an overview of three methods for printing from the control.

Also, a hint for getting started is to make sure to use the CoreWebView2InitializationCompleted event to initialize the control or you'll run into errors related to null values while setting properties. This is a rough template for getting started. I used this with a C# Winforms application in .Net6:

private static Microsoft.Web.WebView2.Core.CoreWebView2Environment _webView2Environment;
private Microsoft.Web.WebView2.Core.CoreWebView2Deferral _webView2Deferral;
private Microsoft.Web.WebView2.Core.CoreWebView2NewWindowRequestedEventArgs _webView2Args;

public PanelDocumentViewer()
{
    InitializeComponent();
}

private void PanelDocumentViewer_Load(object sender, EventArgs e)
{
    webView2.CoreWebView2InitializationCompleted += CoreWebView2_CoreWebView2InitializationCompleted;
    webView2.EnsureCoreWebView2Async(_webView2Environment);
}

private void CoreWebView2_CoreWebView2InitializationCompleted(object? sender, CoreWebView2InitializationCompletedEventArgs e)
{
    webView2.CoreWebView2.Settings.HiddenPdfToolbarItems =
        CoreWebView2PdfToolbarItems.Search
        | CoreWebView2PdfToolbarItems.Save
        | CoreWebView2PdfToolbarItems.SaveAs;

    if (_webView2Deferral != null)
    {
        _webView2Args.NewWindow = webView2.CoreWebView2;
        _webView2Deferral.Complete();
    }

    webView2.CoreWebView2.Settings.AreDefaultContextMenusEnabled = false;
    webView2.CoreWebView2.Settings.AreDevToolsEnabled = false;

    webView2.CoreWebView2.ContextMenuRequested += CoreWebView2_ContextMenuRequested;
    webView2.CoreWebView2.NewWindowRequested += CoreWebView2_NewWindowRequested;
}

private void CoreWebView2_ContextMenuRequested(object? sender, CoreWebView2ContextMenuRequestedEventArgs e)
{
    e.Handled = true; // set to true to prevent the default right-click menu from displaying
    e.MenuItems.Clear(); // remove all right-click menu items 
}

private void CoreWebView2_NewWindowRequested(object? sender, CoreWebView2NewWindowRequestedEventArgs e)
{
    _webView2Args = e;
    _webView2Deferral = e.GetDeferral();
}

private void ButtonPrint_Click(object? sender, EventArgs e)
{
    PrintNowAsync();
}

private async Task PrintNowAsync(CancellationToken cancellationToken = default)
{
    // This prompts the user with a dialog box before printing.
     webView2.CoreWebView2.ShowPrintUI(CoreWebView2PrintDialogKind.System);
}
LSheets
  • 1
  • 1
0

You could also use SumatraPDF from a shell as you structured it above.

SumatraPdf is third-party, but it's free and open source.

  • SumatraPdf at GitHub

  • SumatraPdf Command Line Parameters

      using (var p = new Process())
      {
          p.StartInfo = new ProcessStartInfo()
          {
              FileName = @".\SumatraPDF.exe",
              Arguments = $"-print-settings {printSettings} -print-to \"{printerName}\" \"{filePath}\"",
              CreateNoWindow = true,
              UseShellExecute = false,
              RedirectStandardInput = true,
              RedirectStandardOutput = true,
              RedirectStandardError = true,
          };
    
          p.Start();
          p.WaitForExit();
      }
    
LSheets
  • 1
  • 1
  • Thank you for the updated link. It does not look like any of the print options changed. Also, thanks for the information about the print limitations. I didn't see any of that in the documentation and have been using this as a solution without any problems. It should work with most desktop and network printers, but I've never tried it on specialized printers (aka thermal, etc.) as you mentioned. – LSheets Aug 02 '23 at 16:25
  • Also, Sumatra PDF is free to distribute, but if you have commercial software, Artifex GhostScript requires you to either make the source code for your application publicly available or purchase a recurring commercial license. (The price was not available on their web site. You had to contact them for pricing.) See: https://artifex.com/licensing/commercial/ – LSheets Aug 02 '23 at 16:27