How to set PrinterSettings.PrintToFile and PrinterSettings.PrintFileName in WPF PrintDialogue

Deepak Joy Joseph 1 Reputation point
2021-02-25T07:55:14.393+00:00

I need to remove the Save as file dilogue box and print the pdf document into as specific location using Windows.Controls.PrintDialog in WPF.
I am able to achieve this in WinForms by
using (PrintDocument printDoc = new PrintDocument())
{
printDoc.PrinterSettings.PrintToFile = true;
printDoc.PrinterSettings.PrintFileName =filepath ;
}

Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,696 questions
{count} votes

1 answer

Sort by: Most helpful
  1. gekka 7,741 Reputation points MVP
    2021-02-27T09:01:19.847+00:00

    This is Sample.

    namespace WpfApp6
    {
        using System.Linq;
        using System.Windows;
        using System.Windows.Controls;
        using System.Windows.Documents;
        using System.Windows.Media;
        using System.IO.Packaging;//ReachFramework
        using System.Printing;//System.Printing
    
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
                Button btn = new Button();
                this.Content = btn;
                btn.Click += this.Button_Click;
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
    
                System.Windows.Controls.PrintDialog dlg = new PrintDialog();
                if (dlg.ShowDialog() != true)
                {
                    return;
                }
    
                if (dlg.PrintQueue.Name != "Microsoft Print to PDF")
                {
                    dlg.PrintDocument(CreateTestDocument().DocumentPaginator, "");
                }
                else
                {
                    string filePath = @"C:\Test\Test.pdf";
    
                    var svr = new System.Printing.LocalPrintServer();
                    var queue = svr.GetPrintQueues().FirstOrDefault(_ => _.Name == "Microsoft Print to PDF");
                    if (queue == null)
                    {
                        return;
                    }
    
    
                    var ticket = queue.DefaultPrintTicket;
                    var fixeddoc = CreateTestDocument();
    
                    System.IO.MemoryStream streamXPS = new System.IO.MemoryStream();
                    using (Package pack = Package.Open(streamXPS, System.IO.FileMode.CreateNew))
                    {
                        using (var doc = new System.Windows.Xps.Packaging.XpsDocument(pack, CompressionOption.SuperFast))
                        {
                            var writer = System.Windows.Xps.Packaging.XpsDocument.CreateXpsDocumentWriter(doc);
                            writer.Write(fixeddoc, ticket);
                        }
                    }
                    streamXPS.Position = 0;
    
                    Aspose.Plugins.AsposeVSOpenXML.XpsPrintHelper.Print(streamXPS, queue.Name, "jobname", false, filePath);
                }
            }
    
    
            private FixedPage CreateTestPage(int i)
            {
                FixedPage fp = new FixedPage();
    
                Canvas cv = new Canvas();
                TextBlock tb = new TextBlock();
                tb.Text = "test" + i.ToString(); ;
                tb.FontFamily = this.FontFamily;
                tb.FontSize = 100;
                tb.Foreground = Brushes.Black;
                Canvas.SetLeft(tb, 100);
                Canvas.SetTop(tb, 100);
                cv.Children.Add(tb);
    
                fp.Children.Add(cv);
                return fp;
            }
    
            private FixedDocument CreateTestDocument()
            {
                FixedDocument doc = new FixedDocument();
                for (int i = 1; i <= 10; i++)
                {
                    doc.Pages.Add(new PageContent() { Child = CreateTestPage(i) });
                }
                return doc;
            }
        }
    }
    
    //以下https://code.msdn.microsoft.com/office/Missing-Features-in-6a2c882b/sourcecode?fileId=153127&pathId=1941566436
    //をちょっと改造してファイル名を受け付けるように
    namespace Aspose.Plugins.AsposeVSOpenXML
    {
        using System;
        using System.ComponentModel;
        using System.IO;
        using System.Runtime.InteropServices;
    
        public class XpsPrintHelper
        {
            public static void Print(Stream stream, string printerName, string jobName, bool isWait
                , string outputFileName)//ファイル名
            {
                if (stream == null)
                    throw new ArgumentNullException("stream");
                if (printerName == null)
                    throw new ArgumentNullException("printerName");
    
                IntPtr completionEvent = CreateEvent(IntPtr.Zero, true, false, null);
                if (completionEvent == IntPtr.Zero)
                    throw new Win32Exception();
    
                try
                {
                    IXpsPrintJob job;
                    IXpsPrintJobStream jobStream;
                    StartJob(printerName, jobName, completionEvent, out job, out jobStream, outputFileName);//ファイル名
    
                    CopyJob(stream, job, jobStream);
    
                    if (isWait)
                    {
                        WaitForJob(completionEvent);
                        CheckJobStatus(job);
                    }
                }
                finally
                {
                    if (completionEvent != IntPtr.Zero)
                        CloseHandle(completionEvent);
                }
            }
    
            private static void StartJob(string printerName, string jobName, IntPtr completionEvent, out IXpsPrintJob job, out IXpsPrintJobStream jobStream
                , string outputFileName)//ファイル名
            {
                int result = StartXpsPrintJob
                    (printerName, jobName, outputFileName //ファイル名
                    , IntPtr.Zero, completionEvent
                    , null, 0, out job, out jobStream, IntPtr.Zero);
                if (result != 0)
                    throw new Win32Exception(result);
            }
    
            private static void CopyJob(Stream stream, IXpsPrintJob job, IXpsPrintJobStream jobStream)
            {
                try
                {
                    byte[] buff = new byte[4096];
                    while (true)
                    {
                        uint read = (uint)stream.Read(buff, 0, buff.Length);
                        if (read == 0)
                            break;
    
                        uint written;
                        jobStream.Write(buff, read, out written);
    
                        if (read != written)
                            throw new Exception("Failed to copy data to the print job stream.");
                    }
    
                    // Indicate that the entire document has been copied. 
                    jobStream.Close();
                }
                catch (Exception)
                {
                    // Cancel the job if we had any trouble submitting it. 
                    job.Cancel();
                    throw;
                }
            }
    
            private static void WaitForJob(IntPtr completionEvent)
            {
                const int INFINITE = -1;
                switch (WaitForSingleObject(completionEvent, INFINITE))
                {
                case WAIT_RESULT.WAIT_OBJECT_0:
                    // Expected result, do nothing. 
                    break;
                case WAIT_RESULT.WAIT_FAILED:
                    throw new Win32Exception();
                default:
                    throw new Exception("Unexpected result when waiting for the print job.");
                }
            }
    
            private static void CheckJobStatus(IXpsPrintJob job)
            {
                XPS_JOB_STATUS jobStatus;
                job.GetJobStatus(out jobStatus);
                switch (jobStatus.completion)
                {
                case XPS_JOB_COMPLETION.XPS_JOB_COMPLETED:
                    // Expected result, do nothing. 
                    break;
                case XPS_JOB_COMPLETION.XPS_JOB_FAILED:
                    throw new Win32Exception(jobStatus.jobStatus);
                default:
                    throw new Exception("Unexpected print job status.");
                }
            }
    
            [DllImport("XpsPrint.dll", EntryPoint = "StartXpsPrintJob")]
            private static extern int StartXpsPrintJob(
                [MarshalAs(UnmanagedType.LPWStr)] String printerName,
                [MarshalAs(UnmanagedType.LPWStr)] String jobName,
                [MarshalAs(UnmanagedType.LPWStr)] String outputFileName, //こいつ
                IntPtr progressEvent,   // HANDLE 
                IntPtr completionEvent, // HANDLE 
                [MarshalAs(UnmanagedType.LPArray)] byte[] printablePagesOn,
                UInt32 printablePagesOnCount,
                out IXpsPrintJob xpsPrintJob,
                out IXpsPrintJobStream documentStream,
                IntPtr printTicketStream);  // This is actually "out IXpsPrintJobStream", but we don't use it and just want to pass null, hence IntPtr. 
    
            [DllImport("Kernel32.dll", SetLastError = true)]
            private static extern IntPtr CreateEvent(IntPtr lpEventAttributes, bool bManualReset, bool bInitialState, string lpName);
    
            [DllImport("Kernel32.dll", SetLastError = true, ExactSpelling = true)]
            private static extern WAIT_RESULT WaitForSingleObject(IntPtr handle, Int32 milliseconds);
    
            [DllImport("Kernel32.dll", SetLastError = true)]
            [return: MarshalAs(UnmanagedType.Bool)]
            private static extern bool CloseHandle(IntPtr hObject);
        }
    
        [Guid("0C733A30-2A1C-11CE-ADE5-00AA0044773D")]  // This is IID of ISequenatialSteam. 
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        interface IXpsPrintJobStream
        {
            // ISequentualStream methods. 
            void Read([MarshalAs(UnmanagedType.LPArray)] byte[] pv, uint cb, out uint pcbRead);
            void Write([MarshalAs(UnmanagedType.LPArray)] byte[] pv, uint cb, out uint pcbWritten);
            // IXpsPrintJobStream methods. 
            void Close();
        }
    
        [Guid("5ab89b06-8194-425f-ab3b-d7a96e350161")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        interface IXpsPrintJob
        {
            void Cancel();
            void GetJobStatus(out XPS_JOB_STATUS jobStatus);
        }
    
        [StructLayout(LayoutKind.Sequential)]
        struct XPS_JOB_STATUS
        {
            public UInt32 jobId;
            public Int32 currentDocument;
            public Int32 currentPage;
            public Int32 currentPageTotal;
            public XPS_JOB_COMPLETION completion;
            public Int32 jobStatus; // UInt32 
        };
    
        enum XPS_JOB_COMPLETION
        {
            XPS_JOB_IN_PROGRESS = 0,
            XPS_JOB_COMPLETED = 1,
            XPS_JOB_CANCELLED = 2,
            XPS_JOB_FAILED = 3
        }
    
        enum WAIT_RESULT
        {
            WAIT_OBJECT_0 = 0,
            WAIT_ABANDONED = 0x80,
            WAIT_TIMEOUT = 0x102,
            WAIT_FAILED = -1 // 0xFFFFFFFF 
        }
    }
    
    1 person found this answer helpful.