using System; using System.Runtime.InteropServices; namespace Vanara.PInvoke { /// XPS Print Api functions and interfaces. public static partial class XpsPrint { /// /// [ XPS_JOB_COMPLETION is not supported and may be altered or unavailable in the future. ] /// Indicates the completion status of a print job. /// // https://docs.microsoft.com/en-us/windows/win32/api/xpsprint/ne-xpsprint-xps_job_completion typedef enum // __MIDL___MIDL_itf_xpsprint_0000_0000_0001 { XPS_JOB_IN_PROGRESS, XPS_JOB_COMPLETED, XPS_JOB_CANCELLED, XPS_JOB_FAILED } XPS_JOB_COMPLETION; [PInvokeData("xpsprint.h", MSDNShortId = "a0bfb708-033a-4493-a878-0ebdcaae672f")] public enum XPS_JOB_COMPLETION { /// The print job is running. XPS_JOB_IN_PROGRESS, /// The print job finished without an error. XPS_JOB_COMPLETED, /// /// The print job was cancelled by a call to IXpsPrintJob::Cancel, or cancelled while it was being processed by the print spooler. /// XPS_JOB_CANCELLED, /// The print job failed. The jobStatus member of XPS_JOB_STATUS contains the error code of the failure. XPS_JOB_FAILED } /// /// [IXpsPrintJob is not supported and may be altered or unavailable in the future. ] /// Provides access to a print job that is currently in progress. /// // https://docs.microsoft.com/en-us/windows/win32/api/xpsprint/nn-xpsprint-ixpsprintjob [PInvokeData("xpsprint.h", MSDNShortId = "aa17e059-6208-4348-87f3-556a3818f2b9")] [ComImport, Guid("5ab89b06-8194-425f-ab3b-d7a96e350161"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IXpsPrintJob { /// /// [IXpsPrintJob::Cancel is not supported and may be altered or unavailable in the future.] /// Cancels the print job. /// /// If the method succeeds, it returns S_OK; otherwise, it returns an HRESULT error code. /// /// Any spooling or printing that is in progress at the time this method is called will be canceled. /// This function is thread-safe and synchronized with the job status of the print job object. /// [PreserveSig] HRESULT Cancel(); /// /// [IXpsPrintJob::GetJobSatus is not supported and may be altered or unavailable in the future.] /// Gets the current status of the print job. /// /// /// The current status of the print job. For information about the data that is returned in this structure, see XPS_JOB_STATUS. /// /// /// /// GetJobStatus may be called during the print job processing or after the print job has completed. The values returned in /// XPS_JOB_STATUS represent the current state of the print job at the time GetJobStatus is called, so it is possible to miss /// intermediate states between calls to this method. /// /// /// The values of jobStatus.currentDocument and jobStatus.currentPage are guaranteed to progress sequentially: from the first /// document to the last, and from the first page to the last within each document. /// /// /// The job ID of a print job that has been sent to the Microsoft XPS Document Writer (MXDW) is zero. If the interface is that /// of a print job that has been sent to the MXDW, zero will be returned in jobStatus.jobId. /// /// /// If no job ID has been assigned to the print job, or the print job is printed without spooling, zero will be returned in jobStatus.jobId. /// /// XPS_JOB_STATUS GetJobStatus(); } /// /// [IXpsPrintJobStream is not supported and may be altered or unavailable in the future. ] /// A write-only stream interface into which an application writes print job data. /// /// Note The Close method must be called before this interface is released. // https://docs.microsoft.com/en-us/windows/win32/api/xpsprint/nn-xpsprint-ixpsprintjobstream [PInvokeData("xpsprint.h", MSDNShortId = "a7855015-32db-48ff-8f8d-3d84d2843fde")] [ComImport, Guid("7a77dc5f-45d6-4dff-9307-d8cb846347ca"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IXpsPrintJobStream { /// /// [IXpsPrintJobStream::Close is not supported and may be altered or unavailable in the future.] /// /// Closes the stream and indicates to the print job that the entire document has been written to the print queue by the application. /// /// /// If the method succeeds, it returns S_OK; otherwise, it returns an HRESULT error code. [PreserveSig] HRESULT Close(); } /// /// [StartXpsPrintJob is not supported and may be altered or unavailable in the future. ] /// Starts printing an XPS document stream to a printer. /// /// The name of the printer with which this job will be associated. /// /// A user-specified job name to be associated with this job. If the job does not require a separate, user-specified name, this /// parameter can be set to NULL. /// /// /// The file name of the file or port into which the output of this job is to be redirected. Setting this value will cause the /// output of the print job to be directed to the specified file or port. To send the print job to the printer that is specified by /// printerName, this parameter must be set to NULL. /// /// /// An event handle that is signaled when the following print job changes occur: /// /// /// A job ID is assigned to the print job /// /// /// Printing of a page has finished /// /// /// Printing of a document has finished /// /// /// The print job has been canceled or has ended because of an error /// /// /// Note This event will not be signaled until after the application has started sending data to the print job. /// The XPS Print API does not reset this event—that is the caller's responsibility. /// If no progress notification is required, this parameter can be set to NULL. /// /// /// /// An event handle that is signaled when the print job finishes. This event is guaranteed to be signaled exactly once per /// StartXpsPrintJob call. The XPS Print API does not reset this event—that is the caller's responsibility. /// /// If no completion notification is required, this parameter can be set to NULL. /// /// /// /// The parameter references a UINT8 array whose elements specify a subset of a document's pages to be printed. As shown in the /// table that follows, the value of each element indicates whether the page is to be printed. /// /// /// /// Array Element Value /// Meaning /// /// /// 0 /// Do not print the page. /// /// /// Non-zero /// Print the page. /// /// /// Progress events will be signaled only for the pages that are designated for printing. /// /// The elements in the array represent all pages that are designated for printing, in all documents of the XPS package. For /// example, if the package contains two documents that have three pages each, the array shown in the following table designates the /// printing of pages 0 and 2 from document 1, and pages 0 and 2 from document 2. /// /// /// /// Element index /// Element Value /// Print? /// Document number /// Page number /// /// /// 5 /// 1 /// Yes /// 2 /// 2 /// /// /// 4 /// 0 /// No /// 2 /// 1 /// /// /// 3 /// 1 /// Yes /// 2 /// 0 /// /// /// 2 /// 1 /// Yes /// 1 /// 2 /// /// /// 1 /// 0 /// No /// 1 /// 1 /// /// /// 0 /// 1 /// Yes /// 1 /// 0 /// /// /// If printablePagesOn is NULL, all pages in the package will be printed. /// If printablePagesOn has more elements than there are pages in the package, the superfluous elements will be ignored. /// /// If the array has fewer elements than there are pages in the document, the value of the last array element of the array is /// applied to the remaining pages. This rule makes it easier to specify a range that is open-ended or that gets only a few pages of /// a large document printed. /// /// /// /// The number of elements in the array that is referenced by printablePagesOn. If printablePagesOn is NULL, this parameter /// is ignored. /// /// /// A pointer to the IXpsPrintJob interface that represents the print job that is created by StartXpsPrintJob. To get the /// status of the print job or to cancel it, use the IXpsPrintJob interface. If an IXpsPrintJob is not required, this /// parameter can be set to NULL. /// /// /// A pointer to the IXpsPrintJobStream interface into which the caller writes the XPS document to be printed by this print job. /// /// /// A pointer to the IXpsPrintJobStream interface that is used by the caller to write the job-level print ticket that will be /// associated with this job. If this parameter is set to NULL, the print tickets (if any exist) from the XPS document that /// is written to documentStream will be used. /// /// /// The method returns an HRESULT. Possible values include, but are not limited to, those in the following table. /// /// /// Return code /// Description /// /// /// S_OK /// The method succeeded. /// /// /// E_POINTER /// printerName or documentStream is NULL. /// /// /// E_OUTOFMEMORY /// Not enough memory to create a new IXpsPrintJob object. /// /// /// /// /// /// StartXpsPrintJob is an asynchronous function, which can return before the print spooler creates or starts a print job. /// /// /// The interfaces that are returned in xpsPrintJob, documentStream, and printTicketStream must not be used until /// StartXpsPrintJob has returned successfully. /// /// /// After the caller starts sending data, it should monitor the progress events that are signaled to the event that is passed in /// progressEvent. When the event is signaled, the caller must call IXpsPrintJob::GetJobStatus to get the current status of the /// print job. /// /// /// When the print job finishes, whether successfully or not, the event that is passed in completionEvent is signaled once and only /// once. To prevent data loss, the caller should monitor this event and the thread or the application of the caller should not be /// terminated until the event has been signaled. /// /// /// Job states are neither stored nor queued by the print spooler. Because job processing does not wait for the status to be read /// after events are signaled, the caller might miss some state changes, depending on the delay between the time the application /// received the change notification and the time it called IXpsPrintJob::GetJobStatus. To receive subsequent notifications, the /// application must reset the progress event after it has received the notification. /// /// /// If a call to StartXpsPrintJob fails, the job status will be updated, the completion and progress events will be signaled, /// and an error code will be returned. To get the status of the failed print job, call IXpsPrintJob::GetJobStatus. /// /// /// StartXpsPrintJob calls DuplicateHandle on completionEvent and progressEvent to ensure that they remain valid for /// the lifetime of the job. Because the print spooler is using a duplicate handle for the events, it is possible for the caller to /// close these handles at any point without affecting job execution. The recommended procedure, however, is for the caller to close /// these handles only after the completionEvent event has been signaled and observed by the caller. /// /// /// The IXpsPrintJobStream interfaces that are returned in documentStream and printTicketStream are write-only streams that do not /// permit seeking but that can be closed. The caller writes the XPS document and print ticket content into these streams, and then /// calls Close after all data has been written. Calls to the streams' Write method are thread-safe; however, if such calls /// are made from different threads, they are not guaranteed to be committed to the stream in the expected order. /// /// /// Note When printing to a file, the application is responsible for providing the value that will be passed in the /// outputFileName parameter for print-to-file operations. To print to a printer which uses a driver that outputs to the FILE: port, /// the caller must retrieve the file name from the user by displaying the common file dialog. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/xpsprint/nf-xpsprint-startxpsprintjob HRESULT StartXpsPrintJob( LPCWSTR // printerName, LPCWSTR jobName, LPCWSTR outputFileName, HANDLE progressEvent, HANDLE completionEvent, UINT8 *printablePagesOn, // UINT32 printablePagesOnCount, IXpsPrintJob **xpsPrintJob, IXpsPrintJobStream **documentStream, IXpsPrintJobStream // **printTicketStream ); [DllImport(Lib.XpsPrint, SetLastError = false, ExactSpelling = true)] [PInvokeData("xpsprint.h", MSDNShortId = "d982ae2e-c68f-4197-b419-22a63e61db8a")] public static extern HRESULT StartXpsPrintJob([MarshalAs(UnmanagedType.LPWStr)] string printerName, [Optional, MarshalAs(UnmanagedType.LPWStr)] string jobName, [Optional, MarshalAs(UnmanagedType.LPWStr)] string outputFileName, [Optional] IntPtr progressEvent, [Optional] IntPtr completionEvent, [Optional] byte[] printablePagesOn, uint printablePagesOnCount, out IXpsPrintJob xpsPrintJob, out IXpsPrintJobStream documentStream, out IXpsPrintJobStream printTicketStream); /// /// [StartXpsPrintJob1 is not supported and may be altered or unavailable in the future. ] /// /// Creates a print job for sending XPS document content to a printer.This function creates a more efficient print path than StartXpsPrintJob. /// /// /// The name of the printer with which this job will be associated. /// /// A user-specified job name to be associated with this job. You can set this parameter to NULL if the job does not require /// a separate, user-specified name. /// /// /// The file name of the file or port into which the output of this job is to be redirected. Setting this value will cause the /// output of the print job to be directed to the specified file or port. To send the print job to the printer that is specified by /// printerName, you must set this parameter to NULL. /// /// /// An event handle that is signaled when one of the following print job changes occur: /// /// /// A job ID is assigned to the print job /// /// /// Printing of a page has finished /// /// /// Printing of a document has finished /// /// /// The print job has been canceled or has ended because of an error /// /// /// Note This event will not be signaled until after the application has started sending data to the print job. /// The XPS Print API does not reset this event—that is the caller's responsibility. /// Set this parameter to NULL if you do not want to be notified about progress. /// /// /// /// An event handle that is signaled when the print job finishes. This event is guaranteed to be signaled exactly once per /// StartXpsPrintJob1 call. The XPS Print API does not reset this event—that is the caller's responsibility. /// /// Set this parameter to NULL if do not want to be notified about completion. /// /// /// A pointer to the IXpsPrintJob interface that represents the print job that StartXpsPrintJob1 created. To get the status /// of the print job or to cancel it, use the IXpsPrintJob interface. Set this parameter to NULL if you do not need it. /// /// /// /// A pointer to the IXpsOMPackageTarget interface that this function created. This parameter is required and you cannot set it to NULL. /// /// /// To send document content to the print job that this function created, use the IXpsOMPackageWriter interface that you create by /// calling the CreateXpsOMPackageWriter method of the IXpsOMPackageTarget interface returned in xpsOMPackageTarget. /// /// /// /// The method returns an HRESULT. Possible values include, but are not limited to, those in the following table. /// /// /// Return code /// Description /// /// /// S_OK /// The method succeeded. /// /// /// E_POINTER /// printerName or xpsOMPackageTarget is NULL. /// /// /// E_OUTOFMEMORY /// Not enough memory to create a new IXpsPrintJob object. /// /// /// /// /// /// StartXpsPrintJob1 is an asynchronous function, and therefore it can return before the print spooler creates or starts a /// print job. /// /// /// Do not use the interfaces that are returned in xpsPrintJob and xpsOMPackageTarget until StartXpsPrintJob1 has returned successfully. /// /// /// After the caller starts sending data, it is a good programming practice to monitor the progress events that are signaled to the /// event that is passed in progressEvent. When the event is signaled, the caller must call IXpsPrintJob::GetJobStatus to get the /// current status of the print job. /// /// /// When the print job finishes, whether successfully or not, the event that is passed in completionEvent is signaled only once. To /// prevent data loss, it is a good programming practice for the caller to monitor the completion event and ensure that neither the /// thread nor the application that created the print job are terminated until the completion event has been signaled. /// /// /// Job states are neither stored nor queued by the print spooler. Because job processing does not wait for the status to be read /// after events are signaled, the caller might miss some state changes, depending on the delay between the time the application /// received the change notification and the time it called IXpsPrintJob::GetJobStatus. To receive subsequent notifications, the /// application must reset the progress event after it has received the notification. /// /// /// If a call to StartXpsPrintJob1 fails, the print spooler updates the job status, signals the completion and progress /// events, and returns an error code. To get the status of the failed print job, call IXpsPrintJob::GetJobStatus. /// /// /// StartXpsPrintJob1 calls DuplicateHandle on completionEvent and progressEvent to ensure that they remain valid for /// the lifetime of the job. Because the print spooler is using a duplicate handle for the events, the caller can close these /// handles at any point without affecting job execution. However, we recommend for the caller to close these handles only after the /// completionEvent event has been signaled and the caller observed it. /// /// /// Note When your application prints to a file, the application is responsible for providing the value to pass in the /// outputFileName parameter for print-to-file operations. To print to a printer that uses a driver that outputs to the FILE: port, /// the caller must retrieve the file name from the user by displaying the common file dialog box. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/xpsprint/nf-xpsprint-startxpsprintjob1 HRESULT StartXpsPrintJob1( LPCWSTR // printerName, LPCWSTR jobName, LPCWSTR outputFileName, HANDLE progressEvent, HANDLE completionEvent, IXpsPrintJob **xpsPrintJob, // IXpsOMPackageTarget **printContentReceiver ); [DllImport(Lib.XpsPrint, SetLastError = false, ExactSpelling = true)] [PInvokeData("xpsprint.h", MSDNShortId = "91D0BA4D-60A6-43F8-8BD3-9183DC6CD50D")] public static extern HRESULT StartXpsPrintJob1([MarshalAs(UnmanagedType.LPWStr)] string printerName, [Optional, MarshalAs(UnmanagedType.LPWStr)] string jobName, [Optional, MarshalAs(UnmanagedType.LPWStr)] string outputFileName, [Optional] IntPtr progressEvent, [Optional] IntPtr completionEvent, out IXpsPrintJob xpsPrintJob, out IntPtr printContentReceiver); /// /// [ XPS_JOB_STATUS is not supported and may be altered or unavailable in the future. ] /// Contains a snapshot of job status. /// // https://docs.microsoft.com/en-us/windows/win32/api/xpsprint/ns-xpsprint-xps_job_status typedef struct // __MIDL___MIDL_itf_xpsprint_0000_0000_0002 { UINT32 jobId; INT32 currentDocument; INT32 currentPage; INT32 currentPageTotal; // XPS_JOB_COMPLETION completion; HRESULT jobStatus; } XPS_JOB_STATUS; [PInvokeData("xpsprint.h", MSDNShortId = "c4e13960-4f26-460a-b47e-98b833fcdfd5")] [StructLayout(LayoutKind.Sequential)] public struct XPS_JOB_STATUS { /// The spooler job ID that is assigned to the print job. If no job ID has yet been assigned, jobId will be 0. public uint jobId; /// /// The zero-based index of the most recently processed document in the print job; 0 is the first document, 1 is the next, and /// so on. If no documents have been processed, currentDocument will have a value of -1. /// public int currentDocument; /// /// The zero-based index of the most recently processed page in the current document; 0 is the first page, 1 is the next, and so /// on. If no pages have been processed, currentPage will have a value of -1. /// public int currentPage; /// /// A running total of the number of pages that have been processed by the print job. At the beginning of the job, this value is /// 0. As each page in each document is processed by the job, this value increases monotonically. /// public int currentPageTotal; /// /// The XPS_JOB_COMPLETION value that indicates the completion status of the job. This value will change when the event passed /// in the completionEvent parameter of StartXpsPrintJob is signaled at the end of a job. If the print job fails, this /// value will be XPS_JOB_FAILED, with jobStatus containing the error code of the failure. /// public XPS_JOB_COMPLETION completion; /// /// The error state of the job. If the job finishes without an error, this value will be S_OK. If an error causes the /// print job to exit, this value will be the error code of the failure. /// public HRESULT jobStatus; } } }