From 945d381524a3dea5fa94a54f4f9636f7a6e89da3 Mon Sep 17 00:00:00 2001 From: David Hall Date: Tue, 10 Dec 2019 06:56:36 -0700 Subject: [PATCH] Added initial PInvoke.Printing project with winspool.h implementations --- PInvoke/Printing/PrntvPt.cs | 180 + PInvoke/Printing/Vanara.PInvoke.Printing.csproj | 49 + PInvoke/Printing/WinSpool.Enums.cs | 1323 ++++ PInvoke/Printing/WinSpool.Funcs.cs | 7403 +++++++++++++++++++++++ PInvoke/Printing/WinSpool.Structs.cs | 3789 ++++++++++++ PInvoke/Shared/Lib.cs | 6 + UnitTests/PInvoke/Printing/Printing.csproj | 78 + UnitTests/PInvoke/Printing/PrintingTests.cs | 248 + Vanara.sln | 18 + 9 files changed, 13094 insertions(+) create mode 100644 PInvoke/Printing/PrntvPt.cs create mode 100644 PInvoke/Printing/Vanara.PInvoke.Printing.csproj create mode 100644 PInvoke/Printing/WinSpool.Enums.cs create mode 100644 PInvoke/Printing/WinSpool.Funcs.cs create mode 100644 PInvoke/Printing/WinSpool.Structs.cs create mode 100644 UnitTests/PInvoke/Printing/Printing.csproj create mode 100644 UnitTests/PInvoke/Printing/PrintingTests.cs diff --git a/PInvoke/Printing/PrntvPt.cs b/PInvoke/Printing/PrntvPt.cs new file mode 100644 index 00000000..4a57f437 --- /dev/null +++ b/PInvoke/Printing/PrntvPt.cs @@ -0,0 +1,180 @@ +using System; +using System.Runtime.InteropServices; + +namespace Vanara.PInvoke +{ + /// Functions and structures from prntvpt.h. + public static partial class PrntvPt + { + /// + /// + /// [This function is not supported and might be disabled or deleted in future versions of Windows. PTOpenProviderEx provides + /// equivalent functionality and should be used instead.] + /// + /// Opens an instance of a print ticket provider. + /// + /// The full name of a print queue. + /// The latest version of the Print Schema that the caller supports. + /// The version of the Print Schema requested by the caller. + /// A pointer to a handle to the print ticket provider. + /// The version of the Print Schema that the print ticket provider will use. + /// + /// If the method succeeds, it returns S_OK; otherwise, it returns an HRESULT error code. For more information about + /// COM error codes, see Error Handling. + /// + /// Before calling this function, the calling thread must initialize COM by calling CoInitializeEx. + // https://docs.microsoft.com/en-us/windows/win32/printdocs/bindptproviderthunk HRESULT BindPTProviderThunk( _In_ LPTSTR + // pszPrinterName, _In_ INT maxVersion, _In_ INT prefVersion, _Out_ HPTPROVIDER *phProvider, _Out_ INT *usedVersion ); + [DllImport(Lib.PrntvPt, SetLastError = false, CharSet = CharSet.Auto)] + [PInvokeData("", MSDNShortId = "815cc360-8dcd-4c58-a64d-5d77436a8623")] + public static extern HRESULT BindPTProviderThunk(string pszPrinterName, int maxVersion, int prefVersion, out SafeHPTPROVIDER phProvider, out int usedVersion); + + /// + /// [This function is not supported and might be disabled or deleted in future versions of Windows. PTGetPrintCapabilities provides equivalent functionality and should be used instead.] + /// Retrieves the printer's capabilities formatted in compliance with the XML Print Schema. + /// + /// A handle to an open print ticket provider. This handle is returned by the BindPTProviderThunk function. + /// The buffer that contains the print ticket data, expressed in XML as described in the Print Schema. + /// The size, in bytes, of the buffer referenced by pPrintTicket. + /// The address of the buffer that is allocated by this function and contains the valid print capabilities information, encoded as XML. This function calls CoTaskMemAlloc to allocate this buffer. When the buffer is no longer needed, the caller must free it by calling CoTaskMemFree. + /// The size, in bytes, of the buffer referenced by ppbPrintCapabilities. + /// A pointer to a string that specifies what, if anything, is invalid about pPrintTicket. If it is valid, this value is NULL. If pbstrErrorMessage is not NULL when the function returns, the caller must free the string with SysFreeString. + /// If the method succeeds, it returns S_OK; otherwise, it returns an HRESULT error code. For more information about COM error codes, see Error Handling. + // https://docs.microsoft.com/en-us/windows/win32/printdocs/getprintcapabilitiesthunk2 + // HRESULT GetPrintCapabilitiesThunk2( _In_ HPTPROVIDER hProvider, _In_ BYTE *pPrintTicket, _In_ INT cbPrintTicket, _Out_ BYTE **ppbPrintCapabilities, _Out_ INT *pcbPrintCapabilitiesLength, _Out_opt_ BSTR *pbstrErrorMessage ); + [DllImport(Lib.PrntvPt, SetLastError = false, ExactSpelling = true)] + [PInvokeData("winspool.h", MSDNShortId = "15219c19-b64c-4c51-9357-15a797557693")] + public static extern HRESULT GetPrintCapabilitiesThunk2(HPTPROVIDER hProvider, [In] IntPtr pPrintTicket, int cbPrintTicket, out IntPtr ppbPrintCapabilities, out int pcbPrintCapabilitiesLength, [MarshalAs(UnmanagedType.BStr)] out string pbstrErrorMessage); + + /// Closes a print ticket provider handle. + /// A handle to the provider. This handle is returned by the PTOpenProvider or PTOpenProviderEx function. + /// + /// If the operation succeeds, the return value is S_OK, otherwise the HRESULT contains an error code. + /// If hProvider was opened in a different thread, the HRESULT is E_INVALIDARG. + /// For more information about COM error codes, see Error Handling. + /// + /// + /// + /// Note This is a blocking or synchronous function and might not return immediately. How quickly this function returns + /// depends on run-time factors such as network status, print server configuration, and printer driver implementation—factors that + /// are difficult to predict when writing an application. Calling this function from a thread that manages interaction with the user + /// interface could make the application appear to be unresponsive. + /// + /// + /// The hProvider parameter must be a handle that was opened in the same thread as the thread in which it is used for this function. + /// + /// A handle cannot be used after it is closed. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/prntvpt/nf-prntvpt-ptcloseprovider HRESULT PTCloseProvider( HPTPROVIDER + // hProvider ); + [DllImport(Lib.PrntvPt, SetLastError = false, ExactSpelling = true)] + [PInvokeData("prntvpt.h", MSDNShortId = "28e85b53-fd0c-4210-ae2b-794efaf65bd4")] + public static extern HRESULT PTCloseProvider(HPTPROVIDER hProvider); + + /// + /// + /// [This function is not supported and might be disabled or deleted in future versions of Windows. PTCloseProvider provides + /// equivalent functionality and should be used instead.] + /// + /// Closes a handle to a print ticket provider. + /// + /// + /// A handle to an open print ticket provider. This handle is returned by the BindPTProviderThunk function. + /// + /// + /// If the method succeeds, it returns S_OK; otherwise, it returns an HRESULT error code. For more information about + /// COM error codes, see Error Handling. + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/unbindptproviderthunk HRESULT UnbindPTProviderThunk( _In_ HPTPROVIDER + // hProvider ); + [DllImport(Lib.PrntvPt, SetLastError = false, ExactSpelling = true)] + [PInvokeData("", MSDNShortId = "ce979c89-9f9d-4e89-b142-beed414caa3f")] + public static extern HRESULT UnbindPTProviderThunk(HPTPROVIDER hProvider); + + /// Provides a handle to a print provider. + [StructLayout(LayoutKind.Sequential)] + public struct HPTPROVIDER : IHandle + { + private IntPtr handle; + + /// Initializes a new instance of the struct. + /// An object that represents the pre-existing handle to use. + public HPTPROVIDER(IntPtr preexistingHandle) => handle = preexistingHandle; + + /// Returns an invalid handle by instantiating a object with . + public static HPTPROVIDER NULL => new HPTPROVIDER(IntPtr.Zero); + + /// Gets a value indicating whether this instance is a null handle. + public bool IsNull => handle == IntPtr.Zero; + + /// Performs an explicit conversion from to . + /// The handle. + /// The result of the conversion. + public static explicit operator IntPtr(HPTPROVIDER h) => h.handle; + + /// Performs an implicit conversion from to . + /// The pointer to a handle. + /// The result of the conversion. + public static implicit operator HPTPROVIDER(IntPtr h) => new HPTPROVIDER(h); + + /// Implements the operator !=. + /// The first handle. + /// The second handle. + /// The result of the operator. + public static bool operator !=(HPTPROVIDER h1, HPTPROVIDER h2) => !(h1 == h2); + + /// Implements the operator ==. + /// The first handle. + /// The second handle. + /// The result of the operator. + public static bool operator ==(HPTPROVIDER h1, HPTPROVIDER h2) => h1.Equals(h2); + + /// + public override bool Equals(object obj) => obj is HPTPROVIDER h ? handle == h.handle : false; + + /// + public override int GetHashCode() => handle.GetHashCode(); + + /// + public IntPtr DangerousGetHandle() => handle; + } + + /// Provides a for that is disposed using . + public class SafeHPTPROVIDER : SafeHANDLE + { + /// Initializes a new instance of the class and assigns an existing handle. + /// An object that represents the pre-existing handle to use. + /// + /// to reliably release the handle during the finalization phase; otherwise, (not recommended). + /// + public SafeHPTPROVIDER(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { } + + /// Initializes a new instance of the class. + private SafeHPTPROVIDER() : base() { } + + /// Performs an implicit conversion from to . + /// The safe handle instance. + /// The result of the conversion. + public static implicit operator HPTPROVIDER(SafeHPTPROVIDER h) => h.handle; + + /// + protected override bool InternalReleaseHandle() => PTCloseProvider(handle).Succeeded; + } + + /* + ConvertDevModeToPrintTicketThunk2 + ConvertPrintTicketToDevModeThunk2 + MergeAndValidatePrintTicketThunk2 + PTConvertDevModeToPrintTicket + PTConvertPrintTicketToDevMode + PTGetPrintCapabilities + PTGetPrintDeviceCapabilities + PTGetPrintDeviceResources + PTMergeAndValidatePrintTicket + PTOpenProvider + PTOpenProviderEx + PTQuerySchemaVersionSupport + PTReleaseMemory + */ + } +} \ No newline at end of file diff --git a/PInvoke/Printing/Vanara.PInvoke.Printing.csproj b/PInvoke/Printing/Vanara.PInvoke.Printing.csproj new file mode 100644 index 00000000..938bc233 --- /dev/null +++ b/PInvoke/Printing/Vanara.PInvoke.Printing.csproj @@ -0,0 +1,49 @@ + + + + Printing.dll + + + PInvoke API (methods, structures and constants imported from Windows Printing.dll. + Copyright © 2017-2019 + $(AssemblyName) + 3.1.0 + net20;net35;net40;net45;netstandard2.0;netcoreapp2.0;netcoreapp2.1;netcoreapp3.0 + Vanara.PInvoke.Printing + $(AssemblyName) + Vanara.PInvoke + David Hall + https://github.com/dahall/vanara + MIT + Vanara64x64.png + https://github.com/dahall/vanara + Git + pinvoke;vanara;net-extensions;interop;Printing + en-US + true + true + GitHub Community + Vanara + True + + latest + true + ..\..\Vanara.snk + + + true + bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PInvoke/Printing/WinSpool.Enums.cs b/PInvoke/Printing/WinSpool.Enums.cs new file mode 100644 index 00000000..e4bedba1 --- /dev/null +++ b/PInvoke/Printing/WinSpool.Enums.cs @@ -0,0 +1,1323 @@ +using System; +using Vanara.InteropServices; + +namespace Vanara.PInvoke +{ + public static partial class WinSpool + { + /// Indicates that some notifications had to be discarded. + public const uint PRINTER_NOTIFY_INFO_DISCARDED = 0x01; + + /// Specifies additional information about the print job. + [PInvokeData("wingdi.h", MSDNShortId = "329bf0d9-399b-4f64-a029-361ef7558aeb")] + public enum DI + { + /// Applications that use banding should set this flag for optimal performance during printing. + DI_APPBANDING = 0x00000001, + + /// The application will use raster operations that involve reading from the destination surface. + DI_ROPS_READ_DESTINATION = 0x00000002 + } + + /// Device mode flags. + [PInvokeData("winspool.h", MSDNShortId = "e89a2f6f-2bac-4369-b526-f8e15028698b")] + [Flags] + public enum DM + { + /// + /// When used, the DocumentProperties function returns the number of bytes required by the printer driver's DEVMODE data structure. + /// + DM_SIZEOF = 0, + + /// + DM_UPDATE = 1, + + /// + DM_COPY = 2, + + /// + DM_PROMPT = 4, + + /// + DM_MODIFY = 8, + + /// No description available. + DM_OUT_DEFAULT = DM_UPDATE, + + /// + /// Output value. The function writes the printer driver's current print settings, including private data, to the DEVMODE data + /// structure specified by the pDevModeOutput parameter. The caller must allocate a buffer sufficiently large to contain the + /// information. If the bit DM_OUT_BUFFER sets is clear, the pDevModeOutput parameter can be NULL. This value is also defined as . + /// + DM_OUT_BUFFER = DM_COPY, + + /// + /// Input value. The function presents the printer driver's Print Setup property sheet and then changes the settings in the + /// printer's DEVMODE data structure to those values specified by the user. This value is also defined as . + /// + DM_IN_PROMPT = DM_PROMPT, + + /// + /// Input value. Before prompting, copying, or updating, the function merges the printer driver's current print settings with + /// the settings in the DEVMODE structure specified by the pDevModeInput parameter. The function updates the structure only for + /// those members specified by the DEVMODE structure's dmFields member. This value is also defined as . + /// In cases of conflict during the merge, the settings in the DEVMODE structure specified by pDevModeInput override the printer + /// driver's current print settings. + /// + DM_IN_BUFFER = DM_MODIFY, + } + + /// An escape code that identifies the event to be handled. + [PInvokeData("winspool.h", MSDNShortId = "1250116e-55c7-470f-97f6-36f27a31a841")] + public enum DOCUMENTEVENT + { + /// GDI is about to process a call to its CreateDC or CreateIC function. + //[CorrespondingType(typeof(DOCEVENT_CREATEDPRE), CorrespondingAction.Set)] + [CorrespondingType(typeof(DEVMODE), CorrespondingAction.Get)] + DOCUMENTEVENT_CREATEDCPRE = 1, + + /// + /// GDI has just processed a call to its CreateDC or CreateIC function. + /// This escape code should not be used unless there has been a previous call to DocumentEvent with iEsc set to DOCUMENTEVENT_CREATEDCPRE. + /// + [CorrespondingType(typeof(DEVMODE), CorrespondingAction.Set)] + DOCUMENTEVENT_CREATEDCPOST = 2, + + /// GDI is about to process a call to its ResetDC function. + [CorrespondingType(typeof(DEVMODE), CorrespondingAction.GetSet)] + DOCUMENTEVENT_RESETDCPRE = 3, + + /// + /// GDI has just processed a call to its ResetDC function. + /// This escape code should not be used unless there has been a previous call to DocumentEvent with iEsc set to DOCUMENTEVENT_RESETDCPRE. + /// + [CorrespondingType(typeof(DEVMODE), CorrespondingAction.Set)] + DOCUMENTEVENT_RESETDCPOST = 4, + + /// GDI is about to process a call to its StartDoc function. + [CorrespondingType(typeof(DOCINFO), CorrespondingAction.Set)] + DOCUMENTEVENT_STARTDOC = 5, + + /// GDI is about to process a call to its StartDoc function. + [CorrespondingType(typeof(DOCINFO), CorrespondingAction.Set)] + DOCUMENTEVENT_STARTDOCPRE = 5, + + /// GDI is about to process a call to its StartPage function. + DOCUMENTEVENT_STARTPAGE = 6, + + /// GDI is about to process a call to its EndPage function. + DOCUMENTEVENT_ENDPAGE = 7, + + /// GDI is about to process a call to its EndDoc function. + DOCUMENTEVENT_ENDDOC = 8, + + /// GDI is about to process a call to its EndDoc function. + DOCUMENTEVENT_ENDDOCPRE = 8, + + /// GDI is about to process a call to its AbortDoc function. + DOCUMENTEVENT_ABORTDOC = 9, + + /// GDI is about to process a call to its DeleteDC function. + DOCUMENTEVENT_DELETEDC = 10, + + /// GDI is about to process a call to its ExtEscape function. + //[CorrespondingType(typeof(DOCEVENT_ESCAPE), CorrespondingAction.Set)] + DOCUMENTEVENT_ESCAPE = 11, + + /// GDI has just processed a call to its EndDoc function. + DOCUMENTEVENT_ENDDOCPOST = 12, + + /// GDI has just processed a call to its StartDoc function. + [CorrespondingType(typeof(int), CorrespondingAction.Set)] + DOCUMENTEVENT_STARTDOCPOST = 13, + + /// + /// The DOCUMENTEVENT_QUERYFILTER event represents an opportunity for the spooler to query the driver for a list of the + /// DOCUMENTEVENT_ XXX events to which the driver will respond. This event is issued just prior to a call to DocumentEvent that + /// passes the DOCUMENTEVENT_CREATEDCPRE event. + /// + //[CorrespondingType(typeof(DOCEVENT_CREATEDPRE), CorrespondingAction.Set)] + //[CorrespondingType(typeof(DOCEVENT_FILTER), CorrespondingAction.Get)] + DOCUMENTEVENT_QUERYFILTER = 14, + } + + /// + /// Indicates the action for the SetPrinter function to perform. For the GetPrinter function, this member indicates + /// whether the specified printer is published. + /// + [PInvokeData("winspool.h", MSDNShortId = "9443855e-df7d-41a1-a0df-5649a97b2915")] + [Flags] + public enum DSPRINT : uint + { + /// + /// GetPrinter: Indicates that the system is attempting to complete a publish or unpublish operation started by a SetPrinter call. + /// SetPrinter: This value is not valid. + /// + DSPRINT_PENDING = 0x80000000, + + /// + /// SetPrinter: Publishes the printer's data in the DS. + /// GetPrinter: Indicates the printer is published. + /// + DSPRINT_PUBLISH = 0x00000001, + + /// + /// SetPrinter: The DS data for the printer is unpublished and then published again, refreshing all properties in the published + /// printer. Re-publishing also changes the GUID of the published printer. + /// GetPrinter: Never returns this value. + /// + DSPRINT_REPUBLISH = 0x00000008, + + /// + /// SetPrinter: Removes the printer's published data from the DS. + /// GetPrinter: Indicates the printer is not published. + /// + DSPRINT_UNPUBLISH = 0x00000004, + + /// + /// SetPrinter: Updates the printer's published data in the DS. + /// GetPrinter: Never returns this value. + /// + DSPRINT_UPDATE = 0x00000002, + } + + /// + /// The EPrintPropertyType enumeration defines the data types for different printing properties. + /// + // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-par/9c30d688-be09-4a19-9e41-cb21a55f3884 + [PInvokeData("winspool.h")] + public enum EPrintPropertyType + { + /// The data type is string. + kPropertyTypeString = 1, + + /// The data type is a 32-bit signed integer. + kPropertyTypeInt32, + + /// The data type is a 64-bit signed integer. + kPropertyTypeInt64, + + /// The data type is a BYTE. + kPropertyTypeByte, + + /// The data type is SYSTEMTIME_CONTAINER, as specified in [MS-RPRN] section 2.2.1.2.16. + kPropertyTypeTime, + + /// The data type is DEVMODE_CONTAINER, as specified in [MS-RPRN] section 2.2.1.2.1. + kPropertyTypeDevMode, + + /// The data type is SECURITY_CONTAINER, as specified in [MS-RPRN] section 2.2.1.2.13. + kPropertyTypeSD, + + /// The data type is NOTIFY_REPLY_CONTAINER, as specified in section 2.2.7. + kPropertyTypeNotificationReply, + + /// The data type is NOTIFY_OPTIONS_CONTAINER, as specified in section 2.2.6. + kPropertyTypeNotificationOptions + } + + /// Specifies whether an XPS print job is in the spooling or the rendering phase. + /// This enumeration is primarily used as a parameter for the ReportJobProcessingProgress function. + // https://docs.microsoft.com/en-us/windows/win32/printdocs/eprintxpsjoboperation typedef enum tagEPrintXPSJobOperation { + // kJobProduction, kJobConsumption } EPrintXPSJobOperation; + [PInvokeData("Winspool.h", MSDNShortId = "14871d29-59e4-45a2-9697-12550c58396c")] + public enum EPrintXPSJobOperation + { + /// The XPS job is spooling. + kJobProduction = 1, + + /// The XPS job is rendering. + kJobConsumption, + } + + /// Specifies what the spooler is currently doing as it processes an XPS print job. + /// + /// This enumeration is primarily used as a parameter for the ReportJobProcessingProgress function. + /// These values can refer to either the spooling or the rendering phase of a print job. + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/eprintxpsjobprogress typedef enum tagEPrintXPSJobProgress { + // kAddingDocumentSequence, kDocumentSequenceAdded, kAddingFixedDocument, kFixedDocumentAdded, kAddingFixedPage, kFixedPageAdded, + // kResourceAdded, kFontAdded, kImageAdded, kXpsDocumentCommitted } EPrintXPSJobProgress; + [PInvokeData("Winspool.h", MSDNShortId = "4fa5b749-e4f9-4f08-97b5-e58f82d0b485")] + public enum EPrintXPSJobProgress + { + /// A document sequence is about to be added to the XPS job. + kAddingDocumentSequence, + + /// A document sequence has been added to the XPS job. + kDocumentSequenceAdded, + + /// A fixed document is about to be added to the XPS job. + kAddingFixedDocument, + + /// A fixed document has been added to the XPS job. + kFixedDocumentAdded, + + /// A page is about to be added to the XPS job. + kAddingFixedPage, + + /// A page has been added to the XPS job. + kFixedPageAdded, + + /// A resource had been added to the XPS job. + kResourceAdded, + + /// A font has been added to the XPS job. + kFontAdded, + + /// An image has been added to the XPS job. + kImageAdded, + + /// The data for the XPS job has been committed. + kXpsDocumentCommitted, + } + + /// The form properties. + [PInvokeData("winspool.h", MSDNShortId = "1c42ea6c-82cf-463c-bc67-44a8d8c4a1e7")] + public enum FormFlags + { + /// + /// If this bit flag is set, the form has been defined by the user. Forms with this flag set are defined in the registry. + /// + FORM_USER, + + /// + /// If this bit-flag is set, the form is part of the spooler. Form definitions with this flag set do not appear in the registry. + /// + FORM_BUILTIN, + + /// If this bit flag is set, the form is associated with a certain printer, and its definition appears in the registry. + FORM_PRINTER + } + + /// Specifies how a localized display name for the form is obtained at runtime. + [PInvokeData("winspool.h")] + [Flags] + public enum FormStringType + { + /// There is no localized display name. + STRING_NONE = 0x00000001, + + /// + /// The display name is extracted from the Multilingual User Interface localized resources DLL specified in pMuiDll. The ID is + /// in the dwResourceId member. + /// + STRING_MUIDLL = 0x00000002, + + /// The display name and language ID are provided directly by pDisplayName and the language is specified by wLangId. + STRING_LANGPAIR = 0x00000004 + } + + /// The print job operation to perform. + [PInvokeData("winspool.h")] + public enum JOB_CONTROL + { + /// Pause the print job. + JOB_CONTROL_PAUSE = 1, + + /// Resume a paused print job. + JOB_CONTROL_RESUME = 2, + + /// Do not use. To delete a print job, use JOB_CONTROL_DELETE. + JOB_CONTROL_CANCEL = 3, + + /// Restart the print job. A job can only be restarted if it was printing. + JOB_CONTROL_RESTART = 4, + + /// Delete the print job. + JOB_CONTROL_DELETE = 5, + + /// Used by port monitors to end the print job. + JOB_CONTROL_SENT_TO_PRINTER = 6, + + /// Used by language monitors to end the print job. + JOB_CONTROL_LAST_PAGE_EJECTED = 7, + + /// Windows Vista and later: Keep the job in the queue after it prints. + JOB_CONTROL_RETAIN = 8, + + /// Windows Vista and later: Release the print job. + JOB_CONTROL_RELEASE = 9, + } + + /// + /// Possible values for when is . + /// + [PInvokeData("winspool.h", MSDNShortId = "7a7b9e01-32e0-47f8-a5b1-5f7e6a663714")] + public enum JOB_NOTIFY_FIELD : ushort + { + /// pBuf is a pointer to a null-terminated string containing the name of the printer for which the job is spooled. + JOB_NOTIFY_FIELD_PRINTER_NAME = 0x00, + + /// + /// pBuf is a pointer to a null-terminated string that specifies the name of the machine that created the print job. + /// + JOB_NOTIFY_FIELD_MACHINE_NAME = 0x01, + + /// + /// pBuf is a pointer to a null-terminated string that identifies the port(s) used to transmit data to the printer. If a printer + /// is connected to more than one port, the names of the ports are separated by commas (for example, "LPT1:,LPT2:,LPT3:"). + /// + JOB_NOTIFY_FIELD_PORT_NAME = 0x02, + + /// pBuf is a pointer to a null-terminated string that specifies the name of the user who sent the print job. + JOB_NOTIFY_FIELD_USER_NAME = 0x03, + + /// + /// pBuf is a pointer to a null-terminated string that specifies the name of the user who should be notified when the job has + /// been printed or when an error occurs while printing the job. + /// + JOB_NOTIFY_FIELD_NOTIFY_NAME = 0x04, + + /// pBuf is a pointer to a null-terminated string that specifies the type of data used to record the print job. + JOB_NOTIFY_FIELD_DATATYPE = 0x05, + + /// + /// pBuf is a pointer to a null-terminated string that specifies the name of the print processor to be used to print the job. + /// + JOB_NOTIFY_FIELD_PRINT_PROCESSOR = 0x06, + + /// pBuf is a pointer to a null-terminated string that specifies print-processor parameters. + JOB_NOTIFY_FIELD_PARAMETERS = 0x07, + + /// + /// pBuf is a pointer to a null-terminated string that specifies the name of the printer driver that should be used to process + /// the print job. + /// + JOB_NOTIFY_FIELD_DRIVER_NAME = 0x08, + + /// + /// pBuf is a pointer to a DEVMODE structure that contains device-initialization and environment data for the printer driver. + /// + JOB_NOTIFY_FIELD_DEVMODE = 0x09, + + /// adwData [0] specifies the job status. For a list of possible values, see the JOB_INFO_2 structure. + JOB_NOTIFY_FIELD_STATUS = 0x0A, + + /// pBuf is a pointer to a null-terminated string that specifies the status of the print job. + JOB_NOTIFY_FIELD_STATUS_STRING = 0x0B, + + /// Not supported. + JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR = 0x0C, + + /// + /// pBuf is a pointer to a null-terminated string that specifies the name of the print job (for example, "MS-WORD: Review.doc"). + /// + JOB_NOTIFY_FIELD_DOCUMENT = 0x0D, + + /// adwData [0] specifies the job priority. + JOB_NOTIFY_FIELD_PRIORITY = 0x0E, + + /// adwData [0] specifies the job's position in the print queue. + JOB_NOTIFY_FIELD_POSITION = 0x0F, + + /// pBuf is a pointer to a SYSTEMTIME structure that specifies the time when the job was submitted. + JOB_NOTIFY_FIELD_SUBMITTED = 0x10, + + /// + /// adwData [0] specifies the earliest time that the job can be printed. (This value is specified in minutes elapsed since 12:00 A.M.) + /// + JOB_NOTIFY_FIELD_START_TIME = 0x11, + + /// + /// adwData [0] specifies the latest time that the job can be printed. (This value is specified in minutes elapsed since 12:00 A.M.) + /// + JOB_NOTIFY_FIELD_UNTIL_TIME = 0x12, + + /// adwData [0] specifies the total time, in seconds, that has elapsed since the job began printing. + JOB_NOTIFY_FIELD_TIME = 0x13, + + /// adwData [0] specifies the size, in pages, of the job. + JOB_NOTIFY_FIELD_TOTAL_PAGES = 0x14, + + /// adwData [0] specifies the number of pages that have printed. + JOB_NOTIFY_FIELD_PAGES_PRINTED = 0x15, + + /// adwData [0] specifies the size, in bytes, of the job. + JOB_NOTIFY_FIELD_TOTAL_BYTES = 0x16, + + /// + /// adwData [0] specifies the number of bytes that have been printed on this job. For this field, the change notification object + /// is signaled when bytes are sent to the printer. + /// + JOB_NOTIFY_FIELD_BYTES_PRINTED = 0x17, + + /// + JOB_NOTIFY_FIELD_REMOTE_JOB_ID = 0x18, + } + + /// The job priority. + [PInvokeData("winspool.h", MSDNShortId = "d42ada89-6bc7-4006-81d9-dbcc0347edd3")] + public enum JOB_PRIORITY + { + /// No priority. + NO_PRIORITY = 0, + + /// The maximum priority/ + MAX_PRIORITY = 99, + + /// The minimum priority. + MIN_PRIORITY = 1, + + /// The default priority. + DEF_PRIORITY = 1, + } + + /// The job status. + [PInvokeData("winspool.h", MSDNShortId = "d42ada89-6bc7-4006-81d9-dbcc0347edd3")] + public enum JOB_STATUS : uint + { + /// The job is paused. + JOB_STATUS_PAUSED = 0x00000001, + + /// An error is associated with the job. + JOB_STATUS_ERROR = 0x00000002, + + /// Job is being deleted. + JOB_STATUS_DELETING = 0x00000004, + + /// The job is spooling. + JOB_STATUS_SPOOLING = 0x00000008, + + /// The job is printing. + JOB_STATUS_PRINTING = 0x00000010, + + /// Printer is offline. + JOB_STATUS_OFFLINE = 0x00000020, + + /// Printer is out of paper. + JOB_STATUS_PAPEROUT = 0x00000040, + + /// Job has printed. + JOB_STATUS_PRINTED = 0x00000080, + + /// Job has been deleted. + JOB_STATUS_DELETED = 0x00000100, + + /// The driver cannot print the job. + JOB_STATUS_BLOCKED_DEVQ = 0x00000200, + + /// Printer has an error that requires the user to do something. + JOB_STATUS_USER_INTERVENTION = 0x00000400, + + /// Job has been restarted. + JOB_STATUS_RESTART = 0x00000800, + + /// + /// Windows XP and later: Job is sent to the printer, but the job may not be printed yet. + /// See Remarks for more information. + /// + JOB_STATUS_COMPLETE = 0x00001000, + + /// + /// + /// Windows Vista and later: Job has been retained in the print queue and cannot be deleted. This can be caused by the following: + /// + /// + /// The job was manually retained by a call to SetJob and the spooler is waiting for the job to be released. + /// The job has not finished printing and must finish printing before it can be automatically deleted. + /// + /// See SetJob for more information about print job commands. + /// + JOB_STATUS_RETAINED = 0x00002000, + + /// + JOB_STATUS_RENDERING_LOCALLY = 0x00004000, + } + + /// Indicates the type of information provided by . + [PInvokeData("winspool.h", MSDNShortId = "7a7b9e01-32e0-47f8-a5b1-5f7e6a663714")] + public enum NOTIFY_TYPE : ushort + { + /// Indicates that the Field member specifies a JOB_NOTIFY_FIELD_* constant. + JOB_NOTIFY_TYPE = 0x01, + + /// Indicates that the Field member specifies a PRINTER_NOTIFY_FIELD_* constant. + PRINTER_NOTIFY_TYPE = 0x00, + } + + /// The new port status. + [PInvokeData("winspool.h", MSDNShortId = "0939353f-284b-4dbb-89a2-04918c934430")] + public enum PORT_STATUS + { + /// Clears the printer port status. + PORT_STATUS_CLEAR = 0x00000000, + + /// The port’s printer is offline. + PORT_STATUS_OFFLINE = 0x00000001, + + /// The port’s printer has a paper jam. + PORT_STATUS_PAPER_JAM = 0x00000002, + + /// The port’s printer is out of paper. + PORT_STATUS_PAPER_OUT = 0x00000003, + + /// The port’s printer's output bin is full. + PORT_STATUS_OUTPUT_BIN_FULL = 0x00000004, + + /// The port’s printer has a paper problem. + PORT_STATUS_PAPER_PROBLEM = 0x00000005, + + /// The port’s printer is out of toner. + PORT_STATUS_NO_TONER = 0x00000006, + + /// The door of the port’s printer is open. + PORT_STATUS_DOOR_OPEN = 0x00000007, + + /// The port’s printer requires user intervention. + PORT_STATUS_USER_INTERVENTION = 0x00000008, + + /// The port’s printer is out of memory. + PORT_STATUS_OUT_OF_MEMORY = 0x00000009, + + /// The port’s printer is low on toner. + PORT_STATUS_TONER_LOW = 0x0000000A, + + /// The port’s printer is warming up. + PORT_STATUS_WARMING_UP = 0x0000000B, + + /// The port’s printer is in a power-conservation mode. + PORT_STATUS_POWER_SAVE = 0x0000000C, + } + + /// The severity of the port status value. + [PInvokeData("winspool.h", MSDNShortId = "0939353f-284b-4dbb-89a2-04918c934430")] + public enum PORT_STATUS_TYPE + { + /// The port status value indicates an error. + PORT_STATUS_TYPE_ERROR = 0x00000001, + + /// The port status value is a warning. + PORT_STATUS_TYPE_WARNING = 0x00000002, + + /// The port status value is informational. + PORT_STATUS_TYPE_INFO = 0x00000003, + } + + /// A bit field that specifies attributes of the printer port. + [PInvokeData("winspool.h", MSDNShortId = "93675294-61d4-40e4-b84c-f252978e0285")] + [Flags] + public enum PORT_TYPE + { + /// The port can be written to. + PORT_TYPE_WRITE = 0x00000001, + + /// The port can be read from. + PORT_TYPE_READ = 0x00000002, + + /// The port is a Terminal Services redirected port. + PORT_TYPE_REDIRECTED = 0x00000004, + + /// The port is a network TCP/IP port. + PORT_TYPE_NET_ATTACHED = 0x00000008, + } + + /// Print processor border options. + [PInvokeData("winspool.h", MSDNShortId = "70120739-a4e0-4b87-ac7a-40a42fb509ee")] + [Flags] + public enum PPCAPS_BORDER + { + /// + /// Indicates that when multiple document pages are being printed on a single side of a physical sheet, the printer can be told + /// whether or not to print a border around the imageable area of each document page. + /// + PPCAPS_BORDER_PRINT = 0x00000001, + } + + /// The available patterns when multiple document pages are printed on the same side of a sheet of paper. + [PInvokeData("winspool.h", MSDNShortId = "70120739-a4e0-4b87-ac7a-40a42fb509ee")] + [Flags] + public enum PPCAPS_DIRECTION + { + /// Pages appear in rows from right to left, each subsequent row below its predecessor. + PPCAPS_RIGHT_THEN_DOWN = 0x00000001, + + /// Pages appear in columns from top to bottom, each subsequent column to the right of its predecessor. + PPCAPS_DOWN_THEN_RIGHT = 0x00000001 << 1, + + /// Pages appear in rows from left to right, each subsequent row below its predecessor. + PPCAPS_LEFT_THEN_DOWN = 0x00000001 << 2, + + /// Pages appear in columns from top to bottom, each subsequent column to the left of its predecessor. + PPCAPS_DOWN_THEN_LEFT = 0x00000001 << 3, + } + + /// Print processor duplux handling options. + [PInvokeData("winspool.h", MSDNShortId = "70120739-a4e0-4b87-ac7a-40a42fb509ee")] + [Flags] + public enum PPCAPS_DUPLEX + { + /// + /// When printing in reverse order and duplexing, the processor can print swap the order of each pair of pages, so instead of + /// printing in order 4,3,2,1, they will print in the order 3,4,1,2. + /// + PPCAPS_REVERSE_PAGES_FOR_REVERSE_DUPLEX = 0x00000001, + + /// + /// When duplexing, the Print Processor can be told not to send an extra page when there is an odd number of document pages. The + /// processor will honor the value as best as it can, but in cases where preventing an extra blank page would cause improper + /// output, the extra pages may still be sent. + /// + PPCAPS_DONT_SEND_EXTRA_PAGES_FOR_DUPLEX = 0x00000002 + } + + /// Print processor booklet handling. + [PInvokeData("winspool.h", MSDNShortId = "70120739-a4e0-4b87-ac7a-40a42fb509ee")] + [Flags] + public enum PPCAPS_EDGE + { + /// Indicates that the printer can print booklet style. + PPCAPS_BOOKLET_EDGE = 0x00000001, + } + + /// Print processor scaling options. + [PInvokeData("winspool.h", MSDNShortId = "70120739-a4e0-4b87-ac7a-40a42fb509ee")] + [Flags] + public enum PPCAPS_SCALING + { + /// Indicates that the printer can scale the page image. + PPCAPS_SQUARE_SCALING = 0x00000001, + } + + /// Represents the execution context when GetPrintExecutionData is called. + // https://docs.microsoft.com/en-us/windows/win32/printdocs/print-execution-context typedef enum PRINT_EXECUTION_CONTEXT; + [PInvokeData("Winspool.h", MSDNShortId = "b6c026b2-8519-45d3-9614-b502eec23cde")] + public enum PRINT_EXECUTION_CONTEXT + { + /// The caller is running in an application. + PRINT_EXECUTION_CONTEXT_APPLICATION = 0, + + /// The caller is running in the spooler service (spoolsv.exe). + PRINT_EXECUTION_CONTEXT_SPOOLER_SERVICE = 1, + + /// The caller is running in the print isolation host (PrintIsolationHost.exe) + PRINT_EXECUTION_CONTEXT_SPOOLER_ISOLATION_HOST = 2, + + /// The caller is running in the print filter pipeline (printfilterpipelinesvc.exe) + PRINT_EXECUTION_CONTEXT_FILTER_PIPELINE = 3, + + /// The caller is running in splwow64.exe + PRINT_EXECUTION_CONTEXT_WOW64 = 4, + } + + /// The printer attributes. + [PInvokeData("winspool.h", MSDNShortId = "944cbfcd-9edf-4b60-a45c-9bb1839f8141")] + [Flags] + public enum PRINTER_ATTRIBUTE + { + /// Indicates the printer is the default printer in the system. + PRINTER_ATTRIBUTE_DEFAULT = 0x00000004, + + /// Job is sent directly to the printer (it is not spooled). + PRINTER_ATTRIBUTE_DIRECT = 0x00000002, + + /// If set and printer is set for print-while-spooling, any jobs that have completed spooling are scheduled to print + /// before jobs that have not completed spooling.<185> + PRINTER_ATTRIBUTE_DO_COMPLETE_FIRST = 0x00000200, + + /// Indicates whether bidirectional communications are enabled for the printer.<186> + PRINTER_ATTRIBUTE_ENABLE_BIDI = 0x00000800, + + /// Setting this flag causes mismatched documents to be held in the queue.<187> + PRINTER_ATTRIBUTE_ENABLE_DEVQ = 0x00000080, + + /// If set, printer is a fax printer. + PRINTER_ATTRIBUTE_FAX = 0x00004000, + + /// If set, jobs are kept after they are printed. If cleared, jobs are deleted.<188> + PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS = 0x00000100, + + /// Printer is a local printer. + PRINTER_ATTRIBUTE_LOCAL = 0x00000040, + + /// Printer is a network printer connection. + PRINTER_ATTRIBUTE_NETWORK = 0x00000010, + + /// Indicates whether the printer is published in the directory service (DS).<189> + PRINTER_ATTRIBUTE_PUBLISHED = 0x00002000, + + /// + /// If set, the printer spools and starts printing after the last page is spooled. If cleared, and PRINTER_ATTRIBUTE_DIRECT is + /// not set, the printer spools and prints while spooling. + /// + PRINTER_ATTRIBUTE_QUEUED = 0x00000001, + + /// Indicates that only RAW data type print jobs MUST be spooled.<190> + PRINTER_ATTRIBUTE_RAW_ONLY = 0x00001000, + + /// Printer is shared. + PRINTER_ATTRIBUTE_SHARED = 0x00000008, + + /// Printer is a redirected terminal server printer. + PRINTER_ATTRIBUTE_TS = 0x00008000, + + /// Indicates whether the printer is currently connected. If the printer is not currently connected, print jobs + /// continue to spool.<191> + PRINTER_ATTRIBUTE_WORK_OFFLINE = 0x00000400, + + /// Reserved. + PRINTER_ATTRIBUTE_HIDDEN = 0x00000020, + + /// The printer was installed by using the Push Printer Connections user policy. + PRINTER_ATTRIBUTE_PUSHED_USER = 0x00020000, + + /// The printer was installed by using the Push Printer Connections computer policy. + PRINTER_ATTRIBUTE_PUSHED_MACHINE = 0x00040000, + + /// Printer is a per-machine connection. + PRINTER_ATTRIBUTE_MACHINE = 0x00080000, + + /// A computer has connected to this printer and given it a friendly name. + PRINTER_ATTRIBUTE_FRIENDLY_NAME = 0x00100000, + + /// + PRINTER_ATTRIBUTE_TS_GENERIC_DRIVER = 0x00200000, + + /// + PRINTER_ATTRIBUTE_PER_USER = 0x00400000, + + /// + PRINTER_ATTRIBUTE_ENTERPRISE_CLOUD = 0x00800000, + } + + /// + /// The conditions that will cause the change notification object to enter a signaled state. A change notification occurs when one + /// or more of the specified conditions are met. + /// + [PInvokeData("", MSDNShortId = "4155ef5c-cd96-4960-919b-d9a495bb73a5")] + [Flags] + public enum PRINTER_CHANGE : uint + { + /// A printer was added to the server. + PRINTER_CHANGE_ADD_PRINTER = 0x00000001, + + /// A printer was set. + PRINTER_CHANGE_SET_PRINTER = 0x00000002, + + /// A printer was deleted. + PRINTER_CHANGE_DELETE_PRINTER = 0x00000004, + + /// A printer connection has failed. + PRINTER_CHANGE_FAILED_CONNECTION_PRINTER = 0x00000008, + + /// + /// Notify of any changes to a printer. You can set this general flag or one or more of the following specific flags: + /// PRINTER_CHANGE_ADD_PRINTER PRINTER_CHANGE_SET_PRINTER PRINTER_CHANGE_DELETE_PRINTER PRINTER_CHANGE_FAILED_CONNECTION_PRINTER + /// + PRINTER_CHANGE_PRINTER = 0x000000FF, + + /// A print job was sent to the printer. + PRINTER_CHANGE_ADD_JOB = 0x00000100, + + /// A job was set. + PRINTER_CHANGE_SET_JOB = 0x00000200, + + /// A job was deleted. + PRINTER_CHANGE_DELETE_JOB = 0x00000400, + + /// Job data was written. + PRINTER_CHANGE_WRITE_JOB = 0x00000800, + + /// + /// Notify of any changes to a job. You can set this general flag or one or more of the following specific flags: + /// PRINTER_CHANGE_ADD_JOB PRINTER_CHANGE_SET_JOB PRINTER_CHANGE_DELETE_JOB PRINTER_CHANGE_WRITE_JOB + /// + PRINTER_CHANGE_JOB = 0x0000FF00, + + /// A form was added to the server. + PRINTER_CHANGE_ADD_FORM = 0x00010000, + + /// A form was set on the server. + PRINTER_CHANGE_SET_FORM = 0x00020000, + + /// A form was deleted from the server. + PRINTER_CHANGE_DELETE_FORM = 0x00040000, + + /// + /// Notify of any changes to a form. You can set this general flag or one or more of the following specific flags: + /// PRINTER_CHANGE_ADD_FORM PRINTER_CHANGE_SET_FORM PRINTER_CHANGE_DELETE_FORM + /// + PRINTER_CHANGE_FORM = 0x00070000, + + /// A port or monitor was added to the server. + PRINTER_CHANGE_ADD_PORT = 0x00100000, + + /// A port was configured on the server. + PRINTER_CHANGE_CONFIGURE_PORT = 0x00200000, + + /// A port or monitor was deleted from the server. + PRINTER_CHANGE_DELETE_PORT = 0x00400000, + + /// + /// Notify of any changes to a port. You can set this general flag or one or more of the following specific flags: + /// PRINTER_CHANGE_ADD_PORT PRINTER_CHANGE_CONFIGURE_PORT PRINTER_CHANGE_DELETE_PORT + /// + PRINTER_CHANGE_PORT = 0x00700000, + + /// A print processor was added to the server. + PRINTER_CHANGE_ADD_PRINT_PROCESSOR = 0x01000000, + + /// A print processor was deleted from the server. + PRINTER_CHANGE_DELETE_PRINT_PROCESSOR = 0x04000000, + + /// + /// Notify of any changes to a print processor. You can set this general flag or one or more of the following specific flags: + /// PRINTER_CHANGE_ADD_PRINT_PROCESSOR PRINTER_CHANGE_DELETE_PRINT_PROCESSOR + /// + PRINTER_CHANGE_PRINT_PROCESSOR = 0x07000000, + + /// + /// Windows 7: Notify of any changes to the server. This flag is not included in the changes monitored by setting the + /// PRINTER_CHANGE_ALL value. + /// + PRINTER_CHANGE_SERVER = 0x08000000, + + /// A printer driver was added to the server. + PRINTER_CHANGE_ADD_PRINTER_DRIVER = 0x10000000, + + /// A printer driver was set. + PRINTER_CHANGE_SET_PRINTER_DRIVER = 0x20000000, + + /// A printer driver was deleted from the server. + PRINTER_CHANGE_DELETE_PRINTER_DRIVER = 0x40000000, + + /// + /// Notify of any changes to a printer driver. You can set this general flag or one or more of the following specific flags: + /// PRINTER_CHANGE_ADD_PRINTER_DRIVER PRINTER_CHANGE_SET_PRINTER_DRIVER PRINTER_CHANGE_DELETE_PRINTER_DRIVER + /// + PRINTER_CHANGE_PRINTER_DRIVER = 0x70000000, + + /// The job timed out. + PRINTER_CHANGE_TIMEOUT = 0x80000000, + + /// Notify if any of the preceding changes occur. + PRINTER_CHANGE_ALL, + } + + /// Specifies the caching of a handle for a printer opened with OpenPrinter2. + public enum PRINTER_CONNECTION_FLAGS + { + /// + /// If this bit-flag is set, the printer connection is mismatched. The user can supply a local print driver as pszDriverName and + /// use it to do the rendering instead of using the driver installed on the server printer to which the user is connected. + /// + PRINTER_CONNECTION_MISMATCH = 0x00000020, + + /// + /// If this bit-flag is set then this call cannot display a dialog box. If a dialog box must be displayed to install a printer + /// driver from the server and this bit-flag is set, the printer driver will not be installed, the printer connection will not + /// be added, and the call will fail. + /// + /// Windows 7: In Windows 7 and later versions of Windows, if this flag is set and the user is running in elevated mode, the Do + /// you trust this printer? dialog will not be shown. + /// + /// + PRINTER_CONNECTION_NO_UI = 0x00000040, + } + + public enum PRINTER_CONTROL + { + /// Pause the printer. + PRINTER_CONTROL_PAUSE = 1, + + /// Resume a paused printer. + PRINTER_CONTROL_RESUME = 2, + + /// Delete all print jobs in the printer. + PRINTER_CONTROL_PURGE = 3, + + /// + /// Set the printer status. Set the pPrinter parameter to a pointer to a DWORD value that specifies the new printer status. + /// + PRINTER_CONTROL_SET_STATUS = 4, + } + + /// Specifies information about the returned data. + [PInvokeData("winspool.h", MSDNShortId = "0b0e2d0e-2625-4cab-a8f9-536185479443")] + [Flags] + public enum PRINTER_ENUM + { + /// Returns information about a default printer. Use . + PRINTER_ENUM_DEFAULT = 0x00000001, + + /// + /// If the PRINTER_ENUM_NAME flag is not also passed, the function ignores the Name parameter, and enumerates the locally + /// installed printers. If PRINTER_ENUM_NAME is also passed, the function enumerates the local printers on Name. + /// + PRINTER_ENUM_LOCAL = 0x00000002, + + /// The function enumerates the list of printers to which the user has made previous connections. + PRINTER_ENUM_CONNECTIONS = 0x00000004, + + /// The function enumerates printers that are in the favorites list. + PRINTER_ENUM_FAVORITE = 0x00000004, + + /// + /// The function enumerates the printer identified by Name. This can be a server, a domain, or a print provider. If Name is + /// NULL, the function enumerates available print providers. + /// + PRINTER_ENUM_NAME = 0x00000008, + + /// + /// The function enumerates network printers and print servers in the computer's domain. This value is valid only if Level is 1. + /// + PRINTER_ENUM_REMOTE = 0x00000010, + + /// + /// The function enumerates printers that have the shared attribute. Cannot be used in isolation; use an OR operation to combine + /// with another PRINTER_ENUM type. + /// + PRINTER_ENUM_SHARED = 0x00000020, + + /// The function enumerates network printers in the computer's domain. This value is valid only if Level is 1. + PRINTER_ENUM_NETWORK = 0x00000040, + + /// + /// A print provider can set this flag as a hint to a calling application to enumerate this object further if default expansion + /// is enabled. For example, when domains are enumerated, a print provider might indicate the user's domain by setting this flag. + /// + PRINTER_ENUM_EXPAND = 0x00004000, + + /// + /// If this flag is set, the printer object may contain enumerable objects. For example, the object may be a print server that + /// contains printers. + /// + PRINTER_ENUM_CONTAINER = 0x00008000, + + /// A mask value for all icon values. + PRINTER_ENUM_ICONMASK = 0x00ff0000, + + /// + /// Indicates that, where appropriate, an application should display an icon identifying the object as a top-level network name, + /// such as Microsoft Windows Network. + /// + PRINTER_ENUM_ICON1 = 0x00010000, + + /// + /// Indicates that, where appropriate, an application should display an icon that identifies the object as a network domain. + /// + PRINTER_ENUM_ICON2 = 0x00020000, + + /// + /// Indicates that, where appropriate, an application should display an icon that identifies the object as a print server. + /// + PRINTER_ENUM_ICON3 = 0x00040000, + + /// Reserved. + PRINTER_ENUM_ICON4 = 0x00080000, + + /// Reserved. + PRINTER_ENUM_ICON5 = 0x00100000, + + /// Reserved. + PRINTER_ENUM_ICON6 = 0x00200000, + + /// Reserved. + PRINTER_ENUM_ICON7 = 0x00400000, + + /// Indicates that, where appropriate, an application should display an icon that identifies the object as a printer. + PRINTER_ENUM_ICON8 = 0x00800000, + + /// Indicates that an application cannot display the printer object. + PRINTER_ENUM_HIDE = 0x01000000, + + /// The function enumerates all print devices, including 3D printers. + PRINTER_ENUM_CATEGORY_ALL = 0x02000000, + + /// The function enumerates only 3D printers. + PRINTER_ENUM_CATEGORY_3D = 0x04000000, + } + + /// The flag that determines the category of printers for which notifications will work. + [PInvokeData("", MSDNShortId = "4155ef5c-cd96-4960-919b-d9a495bb73a5")] + public enum PRINTER_NOTIFY_CATEGORY + { + /// FindNextPrinterChangeNotification returns notifications for 2D printers. + PRINTER_NOTIFY_CATEGORY_2D = 0, + + /// FindNextPrinterChangeNotification returns notifications for both 2D and 3D printers. + PRINTER_NOTIFY_CATEGORY_ALL = 0x001000, + + /// FindNextPrinterChangeNotification returns notifications only for 3D printers. + PRINTER_NOTIFY_CATEGORY_3D = 0x002000, + } + + /// + /// Possible values for when is . + /// + [PInvokeData("winspool.h", MSDNShortId = "7a7b9e01-32e0-47f8-a5b1-5f7e6a663714")] + public enum PRINTER_NOTIFY_FIELD : ushort + { + /// Not supported. + PRINTER_NOTIFY_FIELD_SERVER_NAME = 0x00, + + /// pBuf is a pointer to a null-terminated string containing the name of the printer. + PRINTER_NOTIFY_FIELD_PRINTER_NAME = 0x01, + + /// pBuf is a pointer to a null-terminated string that identifies the share point for the printer. + PRINTER_NOTIFY_FIELD_SHARE_NAME = 0x02, + + /// + /// pBuf is a pointer to a null-terminated string containing the name of the port that the print jobs will be printed to. If + /// "Printer Pooling" is selected, this is a comma separated list of ports. + /// + PRINTER_NOTIFY_FIELD_PORT_NAME = 0x03, + + /// pBuf is a pointer to a null-terminated string containing the name of the printer's driver. + PRINTER_NOTIFY_FIELD_DRIVER_NAME = 0x04, + + /// + /// pBuf is a pointer to a null-terminated string containing the new comment string, which is typically a brief description of + /// the printer. + /// + PRINTER_NOTIFY_FIELD_COMMENT = 0x05, + + /// + /// pBuf is a pointer to a null-terminated string containing the new physical location of the printer (for example, "Bldg. 38, + /// Room 1164"). + /// + PRINTER_NOTIFY_FIELD_LOCATION = 0x06, + + /// + /// pBuf is a pointer to a DEVMODE structure that defines default printer data such as the paper orientation and the resolution. + /// + PRINTER_NOTIFY_FIELD_DEVMODE = 0x07, + + /// + /// pBuf is a pointer to a null-terminated string that specifies the name of the file used to create the separator page. This + /// page is used to separate print jobs sent to the printer. + /// + PRINTER_NOTIFY_FIELD_SEPFILE = 0x08, + + /// pBuf is a pointer to a null-terminated string that specifies the name of the print processor used by the printer. + PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR = 0x09, + + /// pBuf is a pointer to a null-terminated string that specifies the default print-processor parameters. + PRINTER_NOTIFY_FIELD_PARAMETERS = 0x0A, + + /// pBuf is a pointer to a null-terminated string that specifies the data type used to record the print job. + PRINTER_NOTIFY_FIELD_DATATYPE = 0x0B, + + /// + /// pBuf is a pointer to a SECURITY_DESCRIPTOR structure for the printer. The pointer may be NULL if there is no security descriptor. + /// + PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR = 0x0C, + + /// + /// adwData [0] specifies the printer attributes, which can be one of the following values: PRINTER_ATTRIBUTE_QUEUED, + /// PRINTER_ATTRIBUTE_DIRECT, PRINTER_ATTRIBUTE_DEFAULT, PRINTER_ATTRIBUTE_SHARED + /// + PRINTER_NOTIFY_FIELD_ATTRIBUTES = 0x0D, + + /// adwData [0] specifies a priority value that the spooler uses to route print jobs. + PRINTER_NOTIFY_FIELD_PRIORITY = 0x0E, + + /// adwData [0] specifies the default priority value assigned to each print job. + PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY = 0x0F, + + /// + /// adwData [0] specifies the earliest time at which the printer will print a job. (This value is specified in minutes elapsed + /// since 12:00 A.M.) + /// + PRINTER_NOTIFY_FIELD_START_TIME = 0x10, + + /// + /// adwData [0] specifies the latest time at which the printer will print a job. (This value is specified in minutes elapsed + /// since 12:00 A.M.) + /// + PRINTER_NOTIFY_FIELD_UNTIL_TIME = 0x11, + + /// adwData [0] specifies the printer status. For a list of possible values, see the PRINTER_INFO_2 structure. + PRINTER_NOTIFY_FIELD_STATUS = 0x12, + + /// Not supported. + PRINTER_NOTIFY_FIELD_STATUS_STRING = 0x13, + + /// adwData [0] specifies the number of print jobs that have been queued for the printer. + PRINTER_NOTIFY_FIELD_CJOBS = 0x14, + + /// adwData [0] specifies the average number of pages per minute that have been printed on the printer. + PRINTER_NOTIFY_FIELD_AVERAGE_PPM = 0x15, + + /// Not supported. + PRINTER_NOTIFY_FIELD_TOTAL_PAGES = 0x16, + + /// Not supported. + PRINTER_NOTIFY_FIELD_PAGES_PRINTED = 0x17, + + /// Not supported. + PRINTER_NOTIFY_FIELD_TOTAL_BYTES = 0x18, + + /// Not supported. + PRINTER_NOTIFY_FIELD_BYTES_PRINTED = 0x19, + + /// This is set if the object GUID changes. + PRINTER_NOTIFY_FIELD_OBJECT_GUID = 0x1A, + + /// This is set if the printer connection is renamed. + PRINTER_NOTIFY_FIELD_FRIENDLY_NAME = 0x1B, + + /// + PRINTER_NOTIFY_FIELD_BRANCH_OFFICE_PRINTING = 0x1C, + } + + /// Bit flags for . + [PInvokeData("", MSDNShortId = "712c546d-dbb3-4f78-b14e-fbb8619b57f9")] + [Flags] + public enum PRINTER_NOTIFY_OPTIONS_FLAG + { + /// Provides current data for all monitored printer information fields. + PRINTER_NOTIFY_OPTIONS_REFRESH = 1 + } + + // https://docs.microsoft.com/en-us/windows/win32/printdocs/printer-option-flags typedef enum tagPRINTER_OPTION_FLAGS { + // PRINTER_OPTION_NO_CACHE, PRINTER_OPTION_CACHE, PRINTER_OPTION_CLIENT_CHANGE } PRINTER_OPTION_FLAGS; + [PInvokeData("Winspool.h", MSDNShortId = "e5a62322-723c-490d-8de1-f74dcac9e22d")] + [Flags] + public enum PRINTER_OPTION_FLAGS + { + /// The handle is not cached. All functions applied to a handle returned by OpenPrinter2 will go to the remote computer. + PRINTER_OPTION_NO_CACHE = 1, + + /// The handle is cached. All functions applied to a handle returned by OpenPrinter2 will go to the local cache. + PRINTER_OPTION_CACHE = 2, + + /// The handle returned by OpenPrinter2 can be used by SetPrinter to rename the printer connection. + PRINTER_OPTION_CLIENT_CHANGE = 4, + + /// + PRINTER_OPTION_NO_CLIENT_DATA = 8, + } + + /// The printer status. + [PInvokeData("winspool.h", MSDNShortId = "944cbfcd-9edf-4b60-a45c-9bb1839f8141")] + public enum PRINTER_STATUS + { + /// The printer is busy. + PRINTER_STATUS_BUSY = 0x00000200, + + /// The printer door is open. + PRINTER_STATUS_DOOR_OPEN = 0x00400000, + + /// The printer is in an error state. + PRINTER_STATUS_ERROR = 0x00000002, + + /// The printer is initializing. + PRINTER_STATUS_INITIALIZING = 0x00008000, + + /// The printer is in an active input or output state. + PRINTER_STATUS_IO_ACTIVE = 0x00000100, + + /// The printer is in a manual feed state. + PRINTER_STATUS_MANUAL_FEED = 0x00000020, + + /// The printer is not available for printing. + PRINTER_STATUS_NOT_AVAILABLE = 0x00001000, + + /// The printer is out of toner. + PRINTER_STATUS_NO_TONER = 0x00040000, + + /// The printer is offline. + PRINTER_STATUS_OFFLINE = 0x00000080, + + /// The printer's output bin is full. + PRINTER_STATUS_OUTPUT_BIN_FULL = 0x00000800, + + /// The printer has run out of memory. + PRINTER_STATUS_OUT_OF_MEMORY = 0x00200000, + + /// The printer cannot print the current page. + PRINTER_STATUS_PAGE_PUNT = 0x00080000, + + /// Paper is stuck in the printer. + PRINTER_STATUS_PAPER_JAM = 0x00000008, + + /// The printer is out of paper. + PRINTER_STATUS_PAPER_OUT = 0x00000010, + + /// The printer has an unspecified paper problem. + PRINTER_STATUS_PAPER_PROBLEM = 0x00000040, + + /// The printer is paused. + PRINTER_STATUS_PAUSED = 0x00000001, + + /// + /// The printer is being deleted as a result of a client's call to RpcDeletePrinter. No new jobs can be submitted on existing + /// printer objects for that printer. + /// + PRINTER_STATUS_PENDING_DELETION = 0x00000004, + + /// The printer is in power-save mode.<182> + PRINTER_STATUS_POWER_SAVE = 0x01000000, + + /// The printer is printing. + PRINTER_STATUS_PRINTING = 0x00000400, + + /// The printer is processing a print job. + PRINTER_STATUS_PROCESSING = 0x00004000, + + /// The printer is offline.<183> + PRINTER_STATUS_SERVER_OFFLINE = 0x02000000, + + /// The printer status is unknown.<184> + PRINTER_STATUS_SERVER_UNKNOWN = 0x00800000, + + /// The printer is low on toner. + PRINTER_STATUS_TONER_LOW = 0x00020000, + + /// The printer has an error that requires the user to do something. + PRINTER_STATUS_USER_INTERVENTION = 0x00100000, + + /// The printer is waiting. + PRINTER_STATUS_WAITING = 0x00002000, + + /// The printer is warming up. + PRINTER_STATUS_WARMING_UP = 0x00010000, + + /// The printer driver needs an update. + PRINTER_STATUS_DRIVER_UPDATE_NEEDED = 0x04000000, + } + + /// Attribute flags for printer drivers. + [PInvokeData("winspool.h", MSDNShortId = "6237def2-ffd4-4d93-b3a4-56f225793457")] + [Flags] + public enum PrinterDriverAttributes + { + /// The printer driver is part of a driver package. Windows Vista + PRINTER_DRIVER_PACKAGE_AWARE = 0x00000001, + + /// The printer driver supports the Microsoft XPS format described in the XML Paper Specification: Overview, and also + /// in Product Behavior, section <27>. Windows 8, Windows Server 2012 + PRINTER_DRIVER_XPS = 0x00000002, + + /// The printer driver is compatible with printer driver isolation. For more information, see Product Behavior, section + /// <28>. Windows 7, Windows Server 2008 R2 + PRINTER_DRIVER_SANDBOX_ENABLED = 0x00000004, + + /// The printer driver is a class printer driver. Windows 8, Windows Server 2012 + PRINTER_DRIVER_CLASS = 0x00000008, + + /// The printer driver is a derived printer driver. Windows 8, Windows Server 2012 + PRINTER_DRIVER_DERIVED = 0x00000010, + + /// Printers using this printer driver cannot be shared. Windows 8, Windows Server 2012 + PRINTER_DRIVER_NOT_SHAREABLE = 0x00000020, + + /// The printer driver is intended for use with fax printers. Windows 8, Windows Server 2012 + PRINTER_DRIVER_CATEGORY_FAX = 0x00000040, + + /// The printer driver is intended for use with file printers. Windows 8, Windows Server 2012 + PRINTER_DRIVER_CATEGORY_FILE = 0x00000080, + + /// The printer driver is intended for use with virtual printers. Windows 8, Windows Server 2012 + PRINTER_DRIVER_CATEGORY_VIRTUAL = 0x00000100, + + /// The printer driver is intended for use with service printers. Windows 8, Windows Server 2012 + PRINTER_DRIVER_CATEGORY_SERVICE = 0x00000200, + + /// Printers that use this printer driver should follow the guidelines outlined in the USB Device Class Definition. For + /// more information, see Product Behavior, section <36> Windows 8, Windows Server 2012 + PRINTER_DRIVER_SOFT_RESET_REQUIRED = 0x00000400, + } + } +} \ No newline at end of file diff --git a/PInvoke/Printing/WinSpool.Funcs.cs b/PInvoke/Printing/WinSpool.Funcs.cs new file mode 100644 index 00000000..17da4988 --- /dev/null +++ b/PInvoke/Printing/WinSpool.Funcs.cs @@ -0,0 +1,7403 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel.Design; +using System.Linq; +using System.Runtime.InteropServices; +using System.Runtime.Serialization; +using System.Runtime.Serialization.Formatters.Binary; +using System.Text; +using Vanara.Extensions; +using Vanara.InteropServices; + +namespace Vanara.PInvoke +{ + public static partial class WinSpool + { + /// The AbortPrinter function deletes a printer's spool file if the printer is configured for spooling. + /// + /// Handle to the printer from which the spool file is deleted. Use the OpenPrinter or AddPrinter function to retrieve + /// a printer handle. + /// + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + /// + /// If the printer is not configured for spooling, the AbortPrinter function has no effect. + /// The sequence for a print job is as follows: + /// + /// + /// To begin a print job, call StartDocPrinter. + /// + /// + /// To begin each page, call StartPagePrinter. + /// + /// + /// To write data to a page, call WritePrinter. + /// + /// + /// To end each page, call EndPagePrinter. + /// + /// + /// Repeat 2, 3, and 4 for as many pages as necessary. + /// + /// + /// To end the print job, call EndDocPrinter. + /// + /// + /// + /// When a page in a spooled file exceeds approximately 350 MB, it can fail to print and not send an error message. For example, + /// this can occur when printing large EMF files. The page size limit depends on many factors including the amount of virtual memory + /// available, the amount of memory allocated by calling processes, and the amount of fragmentation in the process heap. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/abortprinter BOOL AbortPrinter( _In_ HANDLE hPrinter ); + [DllImport(Lib.Winspool, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winspool.h", MSDNShortId = "b361fba5-e4e7-4c9e-ab32-b8ab88dcb1dc")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool AbortPrinter(HPRINTER hPrinter); + + /// The AddForm function adds a form to the list of available forms that can be selected for the specified printer. + /// + /// A handle to the printer that supports printing with the specified form. Use the OpenPrinter or AddPrinter function + /// to retrieve a printer handle. + /// + /// The level of the structure to which pForm points. This value must be 1 or 2. + /// A pointer to a FORM_INFO_1 or FORM_INFO_2 structure. + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + /// + /// An application can determine which forms are available for a printer by calling the EnumForms function. + /// + /// If pForm points to a FORM_INFO_2, then AddForm will fail if either a form with the specified name already exists + /// or the structure's pKeyword value already exists. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/addform BOOL AddForm( _In_ HANDLE hPrinter, _In_ DWORD Level, _In_ + // LPBYTE pForm ); + [DllImport(Lib.Winspool, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "17b59019-f93a-4b57-86fb-91c61aecbac4")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool AddForm(HPRINTER hPrinter, uint Level, IntPtr pForm); + + /// The AddForm function adds a form to the list of available forms that can be selected for the specified printer. + /// The type of the structure used in . + /// + /// A handle to the printer that supports printing with the specified form. Use the OpenPrinter or AddPrinter function + /// to retrieve a printer handle. + /// + /// A FORM_INFO_1 or FORM_INFO_2 structure. + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + /// + /// + /// An application can determine which forms are available for a printer by calling the EnumForms function. + /// + /// If pForm points to a FORM_INFO_2, then AddForm will fail if either a form with the specified name already exists + /// or the structure's pKeyword value already exists. + /// + /// + [PInvokeData("winspool.h", MSDNShortId = "17b59019-f93a-4b57-86fb-91c61aecbac4")] + public static bool AddForm(HPRINTER hPrinter, T pForm) where T : struct + { + if (!TryGetLevel("FORM_INFO_", out var lvl)) + throw new ArgumentException($"{nameof(SetPrinter)} cannot process a structure of type {typeof(T).Name}."); + using var mem = SafeCoTaskMemHandle.CreateFromStructure(pForm); + return AddForm(hPrinter, lvl, mem); + } + + /// + /// The AddJob function adds a print job to the list of print jobs that can be scheduled by the print spooler. The function + /// retrieves the name of the file you can use to store the job. + /// + /// + /// A handle that specifies the printer for the print job. This must be a local printer that is configured as a spooled printer. If + /// hPrinter is a handle to a remote printer connection, or if the printer is configured for direct printing, the AddJob + /// function fails. Use the OpenPrinter or AddPrinter function to retrieve a printer handle. + /// + /// + /// The version of the print job information data structure that the function stores into the buffer pointed to by pData. Set this + /// parameter to one. + /// + /// A pointer to a buffer that receives an data structure and a path string. + /// + /// The size, in bytes, of the buffer pointed to by pData. The buffer needs to be large enough to contain an ADDJOB_INFO_1 + /// structure and a path string. + /// + /// + /// A pointer to a variable that receives the total size, in bytes, of the data structure plus the path + /// string. If this value is less than or equal to cbBuf and the function succeeds, this is the actual number of bytes written to + /// the buffer pointed to by pData. If this number is greater than cbBuf, the buffer is too small, and you must call the function + /// again with a buffer size at least as large as *pcbNeeded. + /// + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + /// + /// You can call the CreateFile function to open the spool file specified by the Path member of the + /// ADDJOB_INFO_1 structure, and then call the WriteFile function to write print job data to it. After that is done, + /// call the ScheduleJob function to notify the print spooler that the print job can now be scheduled by the spooler for printing. + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/addjob BOOL AddJob( _In_ HANDLE hPrinter, _In_ DWORD Level, _Out_ LPBYTE + // pData, _In_ DWORD cbBuf, _Out_ LPDWORD pcbNeeded ); + [DllImport(Lib.Winspool, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "cfafa874-6022-4bf4-bf3d-096213eb0c98")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool AddJob(HPRINTER hPrinter, uint Level, IntPtr pData, uint cbBuf, out uint pcbNeeded); + + /// + /// The AddJob function adds a print job to the list of print jobs that can be scheduled by the print spooler. The function + /// retrieves the name of the file you can use to store the job. + /// + /// + /// A handle that specifies the printer for the print job. This must be a local printer that is configured as a spooled printer. If + /// hPrinter is a handle to a remote printer connection, or if the printer is configured for direct printing, the AddJob + /// function fails. Use the OpenPrinter or AddPrinter function to retrieve a printer handle. + /// + /// The path and file name that the application can use to store the print job. + /// A handle to the print job. + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + /// + /// You can call the CreateFile function to open the spool file specified by , and then call the + /// WriteFile function to write print job data to it. After that is done, call the ScheduleJob function to notify the + /// print spooler that the print job can now be scheduled by the spooler for printing. + /// + [PInvokeData("winspool.h", MSDNShortId = "cfafa874-6022-4bf4-bf3d-096213eb0c98")] + public static bool AddJob(HPRINTER hPrinter, out string path, out uint jobId) + { + path = null; jobId = 0; + AddJob(hPrinter, 1, default, 0, out var sz); + if (sz == 0) return false; + using var mem = new SafeCoTaskMemHandle(sz); + if (!AddJob(hPrinter, 1, mem, sz, out sz)) + return false; + var str = mem.ToStructure(); + path = str.Path; + jobId = str.JobId; + return true; + } + + /// The AddPrinter function adds a printer to the list of supported printers for a specified server. + /// + /// A pointer to a null-terminated string that specifies the name of the server on which the printer should be installed. If this + /// string is NULL, the printer is installed locally. + /// + /// The version of the structure to which pPrinter points. This value must be 2. + /// + /// A pointer to a PRINTER_INFO_2 structure that contains information about the printer. You must specify non- NULL + /// values for the pPrinterName, pPortName, pDriverName, and pPrintProcessor members of this structure + /// before calling AddPrinter. + /// + /// + /// + /// If the function succeeds, the return value is a handle (not thread safe) to a new printer object. When you are finished with the + /// handle, pass it to the ClosePrinter function to close it. + /// + /// If the function fails, the return value is NULL. + /// + /// + /// Do not call this method in DllMain. + /// The caller must have the SeLoadDriverPrivilege. + /// + /// The returned handle is not thread safe. If callers need to use it concurrently on multiple threads, they must provide custom + /// synchronization access to the printer handle using the Synchronization Functions. To avoid writing custom code the application + /// can open a printer handle on each thread, as needed. + /// + /// + /// The following are the members of the PRINTER_INFO_2 structure that can be set before the AddPrinter function is called: + /// + /// + /// + /// Attributes + /// + /// + /// pPrintProcessor + /// + /// + /// DefaultPriority + /// + /// + /// Priority + /// + /// + /// pComment + /// + /// + /// pSecurityDescriptor + /// + /// + /// pDatatype + /// + /// + /// pSepFile + /// + /// + /// pDevMode + /// + /// + /// pShareName + /// + /// + /// pLocation + /// + /// + /// StartTime + /// + /// + /// pParameters + /// + /// + /// UntilTime + /// + /// + /// + /// The Status, cJobs, and AveragePPM members of the PRINTER_INFO_2 structure are reserved for use by + /// the GetPrinter function. They must not be set before calling AddPrinter. + /// + /// + /// If pSecurityDescriptor is NULL, the system assigns a default security descriptor to the printer. The default + /// security descriptor has the following permissions. + /// + /// + /// + /// Value + /// Description + /// + /// + /// Administrators and Power Users + /// + /// Full control on the print queue. This means members of these groups can print, manage the queue (can delete the queue, change + /// any setting of the queue, including the security descriptor), and manage the print jobs of all users (delete, pause, resume, + /// restart jobs).Note that Power Users do not exist before Windows XP Professional. + /// + /// + /// + /// Creator/Owner + /// Can manage own jobs. This means that user who submit jobs can manage (delete, pause, resume, restart) their own jobs. + /// + /// + /// Everyone + /// + /// Execute and standard read control. This means that members of the everyone group can print and read properties of the print queue. + /// + /// + /// + /// + /// After an application creates a printer object with the AddPrinter function, it must use the PrinterProperties + /// function to specify the correct settings for the printer driver associated with the printer object. + /// + /// + /// The AddPrinter function returns an error if a printer object with the same name already exists, unless that object is + /// marked as pending deletion. In that case, the existing printer is not deleted, and the AddPrinter creation parameters are + /// used to change the existing printer settings (as if the application had used the SetPrinter function). + /// + /// + /// Use the EnumPrintProcessors function to enumerate the set of print processors installed on a server. Use the + /// EnumPrintProcessorDatatypes function to enumerate the set of data types that a print processor supports. Use the + /// EnumPorts function to enumerate the set of available ports. Use the EnumPrinterDrivers function to enumerate the + /// installed printer drivers. + /// + /// + /// The caller of the AddPrinter function must have SERVER_ACCESS_ADMINISTER access to the server on which the printer is to + /// be created. The handle returned by the function will have PRINTER_ALL_ACCESS permission, and can be used to perform + /// administrative operations on the printer. + /// + /// + /// If the DrvPrinterEvent function is passed the PRINTER_EVENT_FLAG_NO_UI flag, the driver should not use a UI call during + /// DrvPrinterEvent. To do UI-related jobs, the installer should either use the VendorSetup entry in the printer's + /// .inf file or, for Plug and Play devices, the installer can use a device-specific co-installer. For more information about + /// VendorSetup, see the Microsoft Windows Driver Development Kit (DDK). + /// + /// + /// The Internet Connection Firewall (ICF) blocks printer ports by default, but an exception for File and Print Sharing is enabled + /// when you run AddPrinter. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/addprinter HANDLE AddPrinter( _In_ LPTSTR *pName, _In_ DWORD Level, _In_ + // LPBYTE pPrinter ); + [DllImport(Lib.Winspool, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "ffc4fee8-46c6-47ad-803d-623bf8efdefd")] + public static extern SafeHPRINTER AddPrinter([Optional] string pName, uint Level, in PRINTER_INFO_2 pPrinter); + + /// The AddPrinterConnection function adds a connection to the specified printer for the current user. + /// + /// A pointer to a null-terminated string that specifies the name of a printer to which the current user wishes to establish a connection. + /// + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + /// + /// + /// When Windows makes a connection to a printer, it may need to copy printer driver files to the server to which the printer is + /// attached. If the user does not have permission to copy files to the appropriate location, the AddPrinterConnection + /// function fails, and GetLastError returns ERROR_ACCESS_DENIED. + /// + /// + /// A printer connection established by calling AddPrinterConnection will be enumerated when EnumPrinters is called + /// with dwType set to PRINTER_ENUM_CONNECTION. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/addprinterconnection BOOL AddPrinterConnection( _In_ LPTSTR pName ); + [DllImport(Lib.Winspool, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "6decf89a-1411-4e7e-aa20-60e7068658c2")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool AddPrinterConnection(string pName); + + /// Adds a connection to the specified printer for the current user and specifies connection details. + /// + /// A handle to the parent window in which the dialog box will be displayed if the print system must download a printer driver from + /// the print server for this connection. + /// + /// + /// A pointer to a constant null-terminated string specifying the name of the printer to which the current user wishes to connect. + /// + /// + /// The version of the structure pointed to by pConnectionInfo. Currently, only level 1 is defined so the value of dwLevel must be 1. + /// + /// + /// A pointer to a structure. See the Remarks section for more about this parameter. + /// + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. For extended error information, call GetLastError. + /// + /// + /// + /// When Windows Vista makes a connection to a printer, it may need to copy printer driver files from the server to which the + /// printer is attached. If the user does not have permission to copy files to the appropriate location, the + /// AddPrinterConnection2 function fails and GetLastError returns ERROR_ACCESS_DENIED. + /// + /// + /// If the printer driver files must be copied from the print server but cannot be copied silently due to the group policies that + /// are in effect and PRINTER_CONNECTION_NO_UI is set in pConnectionInfo->dwFlags, no dialog boxes will be displayed and the call + /// will fail. + /// + /// + /// If the local printer driver can be used to render print jobs for this printer and the version of the local driver must not match + /// the version of the printer driver on the server, set PRINTER_CONNECTION_MISMATCH in pConnectionInfo->dwFlags and assign the + /// pointer to a string variable that contains the path to the local printer driver to pConnectionInfo->pszDriverName. + /// + /// + /// A printer connection that is established by calling AddPrinterConnection2 will be enumerated when EnumPrinters is + /// called with dwType set to PRINTER_ENUM_CONNECTION. + /// + /// The ANSI version of this function, AddPrinterConnection2A, is not supported and returns ERROR_NOT_SUPPORTED. + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/addprinterconnection2 BOOL AddPrinterConnection2( _In_ HWND hWnd, _In_ + // LPCTSTR pszName, DWORD dwLevel, _In_ PVOID pConnectionInfo ); + [DllImport(Lib.Winspool, SetLastError = true, CharSet = CharSet.Unicode)] + [PInvokeData("winspool.h", MSDNShortId = "5ae98157-5978-449e-beb1-4787110925fa")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool AddPrinterConnection2([Optional] HWND hWnd, string pszName, uint dwLevel, IntPtr pConnectionInfo); + + /// + /// Adds a connection to the specified printer for the current user and specifies connection details. + /// + /// A handle to the parent window in which the dialog box will be displayed if the print system must download a printer driver from + /// the print server for this connection. + /// A pointer to a constant null-terminated string specifying the name of the printer to which the current user wishes to connect. + /// + /// The following values are defined: + /// + /// + /// Value + /// Meaning + /// + /// + /// PRINTER_CONNECTION_MISMATCH (0x00000020) + /// + /// If this bit-flag is set, the printer connection is mismatched. The user can supply a local print driver as pszDriverName and + /// use it to do the rendering instead of using the driver installed on the server printer to which the user is connected. + /// + /// + /// + /// PRINTER_CONNECTION_NO_UI (0x00000040) + /// + /// If this bit-flag is set then this call cannot display a dialog box. If a dialog box must be displayed to install a printer + /// driver from the server and this bit-flag is set, the printer driver will not be installed, the printer connection will not + /// be added, and the call will fail. Windows 7: In Windows 7 and later versions of Windows, if this flag is set and the user is + /// running in elevated mode, the Do you trust this printer? dialog will not be shown. + /// + /// + /// + /// + /// The name of the driver. + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. For extended error information, call GetLastError. + /// + /// + /// + /// When Windows Vista makes a connection to a printer, it may need to copy printer driver files from the server to which the + /// printer is attached. If the user does not have permission to copy files to the appropriate location, the + /// AddPrinterConnection2 function fails and GetLastError returns ERROR_ACCESS_DENIED. + /// + /// + /// If the printer driver files must be copied from the print server but cannot be copied silently due to the group policies that + /// are in effect and PRINTER_CONNECTION_NO_UI is set in , no dialog boxes will be displayed and the call + /// will fail. + /// + /// + /// If the local printer driver can be used to render print jobs for this printer and the version of the local driver must not match + /// the version of the printer driver on the server, set PRINTER_CONNECTION_MISMATCH in and assign the + /// string variable that contains the path to the local printer driver to . + /// + /// + /// A printer connection that is established by calling AddPrinterConnection2 will be enumerated when EnumPrinters is + /// called with dwType set to PRINTER_ENUM_CONNECTION. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/addprinterconnection2 BOOL AddPrinterConnection2( _In_ HWND hWnd, _In_ + // LPCTSTR pszName, DWORD dwLevel, _In_ PVOID pConnectionInfo ); + [PInvokeData("winspool.h", MSDNShortId = "5ae98157-5978-449e-beb1-4787110925fa")] + public static bool AddPrinterConnection2([Optional] HWND hWnd, string pszName, PRINTER_CONNECTION_FLAGS flags, string driverName = null) => + AddPrinterConnection2(hWnd, pszName, 1, new PRINTER_CONNECTION_INFO_1 { dwFlags = flags, pszDriverName = driverName }); + + /// + /// + /// The AdvancedDocumentProperties function displays a printer-configuration dialog box for the specified printer, allowing + /// the user to configure that printer. + /// + /// This function is a special case of the DocumentProperties function. For more details, see the Remarks section. + /// + /// A handle to the parent window of the printer-configuration dialog box. + /// + /// A handle to a printer object. Use the OpenPrinter or AddPrinter function to retrieve a printer handle. + /// + /// + /// A pointer to a null-terminated string specifying the name of the device for which a printer-configuration dialog box should be displayed. + /// + /// + /// A pointer to a DEVMODE structure that will contain the configuration data specified by the user. + /// + /// + /// A pointer to a DEVMODE structure that contains the configuration data used to initialize the controls of the + /// printer-configuration dialog box. + /// + /// + /// If the DocumentProperties function with these parameters is successful, the return value of + /// AdvancedDocumentProperties is 1. Otherwise, the return value is zero. + /// + /// + /// + /// This function can only display the printer-configuration dialog box so a user can configure it. For more control, use + /// DocumentProperties. The input parameters for this function are passed directly to DocumentProperties and the fMode + /// value is set to DM_IN_BUFFER | DM_IN_PROMPT | DM_OUT_BUFFER. Unlike DocumentProperties, this function only returns 1 or + /// 0. Thus, you cannot determine the required size of DEVMODE by setting pDevMode to zero. + /// + /// + /// An application can obtain the name pointed to by the pDeviceName parameter by calling the GetPrinter function and then + /// examining the pPrinterName member of the PRINTER_INFO_2 structure. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/advanceddocumentproperties LONG AdvancedDocumentProperties( _In_ HWND + // hWnd, _In_ HANDLE hPrinter, _In_ LPTSTR pDeviceName, _Out_ PDEVMODE pDevModeOutput, _In_ PDEVMODE pDevModeInput ); + [DllImport(Lib.Winspool, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "29e33f34-f6ec-4989-b076-e1fef8eb5bc4")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool AdvancedDocumentProperties(HWND hWnd, HPRINTER hPrinter, string pDeviceName, ref DEVMODE pDevModeOutput, in DEVMODE pDevModeInput); + + /// + /// + /// The AdvancedDocumentProperties function displays a printer-configuration dialog box for the specified printer, allowing + /// the user to configure that printer. + /// + /// This function is a special case of the DocumentProperties function. For more details, see the Remarks section. + /// + /// A handle to the parent window of the printer-configuration dialog box. + /// + /// A handle to a printer object. Use the OpenPrinter or AddPrinter function to retrieve a printer handle. + /// + /// + /// A pointer to a null-terminated string specifying the name of the device for which a printer-configuration dialog box should be displayed. + /// + /// + /// A pointer to a DEVMODE structure that will contain the configuration data specified by the user. + /// + /// + /// A pointer to a DEVMODE structure that contains the configuration data used to initialize the controls of the + /// printer-configuration dialog box. + /// + /// + /// If the DocumentProperties function with these parameters is successful, the return value of + /// AdvancedDocumentProperties is 1. Otherwise, the return value is zero. + /// + /// + /// + /// This function can only display the printer-configuration dialog box so a user can configure it. For more control, use + /// DocumentProperties. The input parameters for this function are passed directly to DocumentProperties and the fMode + /// value is set to DM_IN_BUFFER | DM_IN_PROMPT | DM_OUT_BUFFER. Unlike DocumentProperties, this function only returns 1 or + /// 0. Thus, you cannot determine the required size of DEVMODE by setting pDevMode to zero. + /// + /// + /// An application can obtain the name pointed to by the pDeviceName parameter by calling the GetPrinter function and then + /// examining the pPrinterName member of the PRINTER_INFO_2 structure. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/advanceddocumentproperties LONG AdvancedDocumentProperties( _In_ HWND + // hWnd, _In_ HANDLE hPrinter, _In_ LPTSTR pDeviceName, _Out_ PDEVMODE pDevModeOutput, _In_ PDEVMODE pDevModeInput ); + [DllImport(Lib.Winspool, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "29e33f34-f6ec-4989-b076-e1fef8eb5bc4")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool AdvancedDocumentProperties(HWND hWnd, HPRINTER hPrinter, string pDeviceName, [Out] IntPtr pDevModeOutput = default, [In] IntPtr pDevModeInput = default); + + /// The ClosePrinter function closes the specified printer object. + /// + /// A handle to the printer object to be closed. This handle is returned by the OpenPrinter or AddPrinter function. + /// + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + /// + /// When the ClosePrinter function returns, the handle hPrinter is invalid, regardless of whether the function has succeeded + /// or failed. + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/closeprinter BOOL ClosePrinter( _In_ HANDLE hPrinter ); + [DllImport(Lib.Winspool, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winspool.h", MSDNShortId = "95cc3eca-e65c-4fa6-8975-479e8e728dca")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool ClosePrinter(HPRINTER hPrinter); + + /// + /// The CloseSpoolFileHandle function closes a handle to a spool file associated with the print job currently submitted by + /// the application. + /// + /// + /// A handle to the printer to which the job was submitted. This should be the same handle that was used to obtain hSpoolFile with GetSpoolFileHandle. + /// + /// + /// A handle to the spool file being closed. If CommitSpoolData has not been called since GetSpoolFileHandle was + /// called, then this should be the same handle that was returned by GetSpoolFileHandle. Otherwise, it should be the handle + /// that was returned by the most recent call to CommitSpoolData. + /// + /// TRUE, if it succeeds, FALSE otherwise. + /// + /// Your application must not call ClosePrinter on hPrinter until after it has accessed the spool file for the last time. + /// Then it should call CloseSpoolFileHandle followed by ClosePrinter. Attempts to access the spool file handle after + /// the original hPrinter has been closed will fail even if the file handle itself has not been closed. CloseSpoolFileHandle + /// will fail if ClosePrinter is called first. + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/closespoolfilehandle BOOL CloseSpoolFileHandle( _In_ HANDLE hPrinter, + // _In_ HANDLE hSpoolFile ); + [DllImport(Lib.Winspool, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winspool.h", MSDNShortId = "e2c0e68f-b72e-4a97-ba18-8943bc5789c1")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool CloseSpoolFileHandle(HPRINTER hPrinter, HSPOOLFILE hSpoolFile); + + /// + /// The CommitSpoolData function notifies the print spooler that a specified amount of data has been written to a specified + /// spool file and is ready to be rendered. + /// + /// + /// A handle to the printer to which the job was submitted. This should be the same handle that was used to obtain hSpoolFile with GetSpoolFileHandle. + /// + /// + /// A handle to the spool file being changed. On the first call of CommitSpoolData, this should be the same handle that was + /// returned by GetSpoolFileHandle. Subsequent calls to CommitSpoolData should pass the handle returned by the + /// preceding call. See Remarks. + /// + /// The number of bytes committed to the print spooler. + /// + /// If the function succeeds, it returns a handle to the spool file. + /// If the function fails, it returns INVALID_HANDLE_VALUE. + /// + /// + /// + /// Applications submitting a spooler print job can call GetSpoolFileHandle and then directly write data to the spool file + /// handle by calling WriteFile. To notify the print spooler that the file contains data which is ready to be rendered, the + /// application must call CommitSpoolData and provide the number of available bytes. + /// + /// + /// If CommitSpoolData is called multiple times, each call must use the spool file handle returned by the previous call. When + /// no more data will be written to the spool file, CloseSpoolFileHandle should be called for the file handle returned by the + /// last call to CommitSpoolData. + /// + /// + /// Before calling CommitSpoolData, applications must set the file pointer to the position it had before it wrote data to the + /// file. In the process of rendering the data in the spooler file, the print spooler will move the spool file pointer cbCommit + /// bytes from the current value of file pointer. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/commitspooldata HANDLE CommitSpoolData( _In_ HANDLE hPrinter, _In_ + // HANDLE hSpoolFile, DWORD cbCommit ); + [DllImport(Lib.Winspool, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winspool.h", MSDNShortId = "cb8899e0-2fdf-4928-adff-17ef5af39f63")] + public static extern HANDLE CommitSpoolData(HPRINTER hPrinter, HSPOOLFILE hSpoolFile, uint cbCommit); + + /// The ConfigurePort function displays the port-configuration dialog box for a port on the specified server. + /// + /// Pointer to a null-terminated string that specifies the name of the server on which the specified port exists. If this parameter + /// is NULL, the port is local. + /// + /// Handle to the parent window of the port-configuration dialog box. + /// Pointer to a null-terminated string that specifies the name of the port to be configured. + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + /// + /// Before calling the ConfigurePort function, an application should call the EnumPorts function to determine valid + /// port names. + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/configureport BOOL ConfigurePort( _In_ LPTSTR pName, _In_ HWND hWnd, + // _In_ LPTSTR pPortName ); + [DllImport(Lib.Winspool, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "a65e9876-d6af-48c2-9e6b-8bd8695db130")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool ConfigurePort([Optional] string pName, HWND hWnd, string pPortName); + + /// + /// The ConnectToPrinterDlg function displays a dialog box that lets users browse and connect to printers on a network. If + /// the user selects a printer, the function attempts to create a connection to it; if a suitable driver is not installed on the + /// server, the user is given the option of creating a printer locally. + /// + /// Specifies the parent window of the dialog box. + /// This parameter is reserved and must be zero. + /// + /// If the function succeeds and the user selects a printer, the return value is a handle to the selected printer. + /// If the function fails, or the user cancels the dialog box without selecting a printer, the return value is NULL. + /// + /// + /// + /// The ConnectToPrinterDlg function attempts to create a connection to the selected printer. However, if the server on which + /// the printer resides does not have a suitable driver installed, the function offers the user the option of creating a printer + /// locally. A calling application can determine whether the function has created a printer locally by calling GetPrinter + /// with a PRINTER_INFO_2 structure, then examining that structure's Attributes member. + /// + /// + /// An application should call DeletePrinter to delete a local printer. An application should call + /// DeletePrinterConnection to delete a connection to a printer. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/connecttoprinterdlg HANDLE ConnectToPrinterDlg( _In_ HWND hwnd, _In_ + // DWORD Flags ); + [DllImport(Lib.Winspool, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winspool.h", MSDNShortId = "7cb9108b-8b65-4af3-88c8-a69771ed8e3f")] + public static extern SafeHPRINTER ConnectToPrinterDlg(HWND hwnd, uint Flags = 0); + + /// The DeleteForm function removes a form name from the list of supported forms. + /// + /// Indicates the open printer handle that this function is to be performed upon. Use the OpenPrinter or AddPrinter + /// function to retrieve a printer handle. + /// + /// Pointer to the form name to be removed. + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + /// DeleteForm can only delete form names that were added by using the AddForm function. + // https://docs.microsoft.com/en-us/windows/win32/printdocs/deleteform BOOL DeleteForm( _In_ HANDLE hPrinter, _In_ LPTSTR pFormName ); + [DllImport(Lib.Winspool, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "a2d0345f-2469-46ab-935f-777f2b33b621")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool DeleteForm(HPRINTER hPrinter, string pFormName); + + /// The DeletePrinter function deletes the specified printer object. + /// + /// Handle to a printer object that will be deleted. Use the OpenPrinter or AddPrinter function to retrieve a printer handle. + /// + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + /// + /// + /// If there are print jobs remaining to be processed for the specified printer, DeletePrinter marks the printer for pending + /// deletion, and then deletes it when all the print jobs have been printed. No print jobs can be added to a printer that is marked + /// for pending deletion. + /// + /// + /// A printer marked for pending deletion cannot be held, but its print jobs can be held, resumed, and restarted. If the printer is + /// held and there are jobs for the printer, DeletePrinter fails with ERROR_ACCESS_DENIED. + /// + /// Note that DeletePrinter does not close the handle that is passed to it. Thus, the application must still call ClosePrinter. + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/deleteprinter BOOL DeletePrinter( _Inout_ HANDLE hPrinter ); + [DllImport(Lib.Winspool, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winspool.h", MSDNShortId = "04d9c073-b795-4307-ba89-d4984bc5b354")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool DeletePrinter(HPRINTER hPrinter); + + /// + /// The DeletePrinterConnection function deletes a connection to a printer that was established by a call to + /// AddPrinterConnection or ConnectToPrinterDlg. + /// + /// Pointer to a null-terminated string that specifies the name of the printer connection to delete. + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + /// + /// The DeletePrinterConnection function does not delete any printer driver files that were copied to the server to which the + /// printer is attached. + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/deleteprinterconnection BOOL DeletePrinterConnection( _In_ LPTSTR pName ); + [DllImport(Lib.Winspool, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "7b056eea-fbd9-4a08-a2dc-7326caeec387")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool DeletePrinterConnection(string pName); + + /// + /// + /// The DeletePrinterData function deletes specified configuration data for a printer. A printer's configuration data + /// consists of a set of named and typed values. The DeletePrinterData function deletes one of these values, specified by its + /// value name. + /// + /// + /// Calling DeletePrinterData is equivalent to calling the DeletePrinterDataEx function with the pKeyName parameter + /// set to "PrinterDriverData". + /// + /// + /// + /// A handle to the printer whose configuration data is to be deleted. Use the OpenPrinter or AddPrinter function to + /// retrieve a printer handle. + /// + /// A pointer to the null-terminated name of the configuration data value to be deleted. + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. + /// If the function fails, the return value is a system error code. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/deleteprinterdata DWORD DeletePrinterData( _In_ HANDLE hPrinter, _In_ + // LPTSTR pValueName ); + [DllImport(Lib.Winspool, SetLastError = false, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "03c0bd75-d6de-46e3-b8e9-5a55df5135ea")] + public static extern Win32Error DeletePrinterData(HPRINTER hPrinter, string pValueName); + + /// + /// + /// The DeletePrinterDataEx function deletes a specified value from the configuration data for a printer. A printer's + /// configuration data consists of a set of named and typed values stored in a hierarchy of registry keys. The function deletes a + /// specified value under a specified key. + /// + /// + /// Like the DeletePrinterData function, DeletePrinterDataEx can delete values stored by the SetPrinterData + /// function. In addition, DeletePrinterDataEx can delete values stored under a specified key by the SetPrinterDataEx function. + /// + /// + /// + /// A handle to the printer for which the function deletes a value. Use the OpenPrinter or AddPrinter function to + /// retrieve a printer handle. + /// + /// + /// + /// A pointer to a null-terminated string that specifies the key containing the value to delete. Use the backslash ( \ ) character + /// as a delimiter to specify a path that has one or more subkeys. + /// + /// If pKeyName is NULL or an empty string, DeletePrinterDataEx returns ERROR_INVALID_PARAMETER. + /// + /// A pointer to a null-terminated string that specifies the name of the value to delete. + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. + /// If the function fails, the return value is a system error code. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/deleteprinterdataex DWORD DeletePrinterDataEx( _In_ HANDLE hPrinter, + // _In_ LPCTSTR pKeyName, _In_ LPCTSTR pValueName ); + [DllImport(Lib.Winspool, SetLastError = false, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "bcc9cdb3-0fbf-40b6-9de2-1479c3c0ff55")] + public static extern Win32Error DeletePrinterDataEx(HPRINTER hPrinter, string pKeyName, string pValueName); + + /// The DeletePrinterKey function deletes a specified key and all its subkeys for a specified printer. + /// + /// A handle to the printer for which the function deletes a key. Use the OpenPrinter or AddPrinter function to + /// retrieve a printer handle. + /// + /// + /// + /// A pointer to a null-terminated string that specifies the key to delete. Use the backslash ( \ ) character as a delimiter to + /// specify a path with one or more subkeys. + /// + /// + /// If pKeyName is an empty string (""), DeletePrinterKey deletes all keys below the top-level key for the printer. If + /// pKeyName is NULL, DeletePrinterKey returns ERROR_INVALID_PARAMETER. + /// + /// + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. + /// If the function fails, the return value is a system error code. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/deleteprinterkey DWORD DeletePrinterKey( _In_ HANDLE hPrinter, _In_ + // LPCTSTR pKeyName ); + [DllImport(Lib.Winspool, SetLastError = false, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "0bd81b43-5c1e-4989-8350-2ec0dc215f28")] + public static extern Win32Error DeletePrinterKey(HPRINTER hPrinter, string pKeyName); + + /// The DocumentEvent function is an event handler for events associated with printing a document. + /// + /// A handle to a printer object. Use the OpenPrinter or AddPrinter function to retrieve a printer handle. + /// + /// + /// A device context handle that is generated by a call of CreateDC. This is zero if iEsc is set to + /// DOCUMENTEVENT_CREATEDCPRE. For restrictions on printing from a 32-bit application on a 64-bit version of Windows, see Remarks. + /// + /// + /// An escape code that identifies the event to be handled. This parameter can be one of the following integer constants. + /// + /// + /// Constant + /// Event + /// + /// + /// DOCUMENTEVENT_ABORTDOC + /// GDI is about to process a call to its AbortDoc function. + /// + /// + /// DOCUMENTEVENT_CREATEDCPOST + /// + /// GDI has just processed a call to its CreateDC or CreateIC function. This escape code should not be used unless there has been a + /// previous call to DocumentEvent with iEsc set to DOCUMENTEVENT_CREATEDCPRE. + /// + /// + /// + /// DOCUMENTEVENT_CREATEDCPRE + /// GDI is about to process a call to its CreateDC or CreateIC function. + /// + /// + /// DOCUMENTEVENT_DELETEDC + /// GDI is about to process a call to its DeleteDC function. + /// + /// + /// DOCUMENTEVENT_ENDDOCPOST + /// GDI has just processed a call to its EndDoc function. + /// + /// + /// DOCUMENTEVENT_ENDDOCPRE or DOCUMENTEVENT_ENDDOC + /// GDI is about to process a call to its EndDoc function. + /// + /// + /// DOCUMENTEVENT_ENDPAGE + /// GDI is about to process a call to its EndPage function. + /// + /// + /// DOCUMENTEVENT_ESCAPE + /// GDI is about to process a call to its ExtEscape function. + /// + /// + /// DOCUMENTEVENT_QUERYFILTER + /// + /// The DOCUMENTEVENT_QUERYFILTER event represents an opportunity for the spooler to query the driver for a list of the + /// DOCUMENTEVENT_ XXX events to which the driver will respond. This event is issued just prior to a call to DocumentEvent that + /// passes the DOCUMENTEVENT_CREATEDCPRE event. + /// + /// + /// + /// DOCUMENTEVENT_RESETDCPOST + /// + /// GDI has just processed a call to its ResetDC function. This escape code should not be used unless there has been a previous call + /// to DocumentEvent with iEsc set to DOCUMENTEVENT_RESETDCPRE. + /// + /// + /// + /// DOCUMENTEVENT_RESETDCPRE + /// GDI is about to process a call to its ResetDC function. + /// + /// + /// DOCUMENTEVENT_STARTDOCPOST + /// GDI has just processed a call to its StartDoc function. + /// + /// + /// DOCUMENTEVENT_STARTDOCPRE or DOCUMENTEVENT_STARTDOC + /// GDI is about to process a call to its StartDoc function. + /// + /// + /// DOCUMENTEVENT_STARTPAGE + /// GDI is about to process a call to its StartPage function. + /// + /// + /// + /// The size, in bytes, of the buffer pointed to by pvIn. + /// + /// A pointer to a buffer. What the buffer contains depends on the value of iEsc, as shown in the following table. + /// + /// + /// Constant + /// pvin Contents + /// + /// + /// DOCUMENTEVENT_ABORTDOC + /// Not used. + /// + /// + /// DOCUMENTEVENT_CREATEDCPOST + /// + /// pvIn contains the address of a pointer to the DEVMODE structure specified in the pvOut parameter in a previous call to this + /// function, for which the iEsc parameter was set to DOCUMENTEVENT_CREATEDCPRE. + /// + /// + /// + /// DOCUMENTEVENT_CREATEDCPRE + /// pvIn points to a DOCEVENT_CREATEDCPRE structure which is documented in the Windows Driver Development Kit. + /// + /// + /// DOCUMENTEVENT_DELETEDC + /// Not used. + /// + /// + /// DOCUMENTEVENT_ENDDOCPOST + /// Not used. + /// + /// + /// DOCUMENTEVENT_ENDDOCPRE or DOCUMENTEVENT_ENDDOC + /// Not used. + /// + /// + /// DOCUMENTEVENT_ENDPAGE + /// Not used. + /// + /// + /// DOCUMENTEVENT_ESCAPE + /// pvIn points to a DOCEVENT_ESCAPE structure which is documented in the Windows Driver Development Kit. + /// + /// + /// DOCUMENTEVENT_QUERYFILTER + /// Same as for DOCUMENTEVENT_CREATEDCPRE. + /// + /// + /// DOCUMENTEVENT_RESETDCPOST + /// + /// pvIn contains the address of a pointer to the DEVMODE structure specified in the pvOut parameter in a previous call to this + /// function, for which the iEsc parameter was set to DOCUMENTEVENT_RESETDCPRE. + /// + /// + /// + /// DOCUMENTEVENT_RESETDCPRE + /// pvIn contains the address of a pointer to the DEVMODE structure supplied by the caller of ResetDC. + /// + /// + /// DOCUMENTEVENT_STARTDOCPOST + /// pvIn points to a LONG that specifies the print job identifier returned by StartDoc. + /// + /// + /// DOCUMENTEVENT_STARTDOCPRE or DOCUMENTEVENT_STARTDOC + /// pvIn contains the address of a pointer to a DOCINFO structure supplied by the caller of StartDoc. + /// + /// + /// DOCUMENTEVENT_STARTPAGE + /// Not used. + /// + /// + /// + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// IDOCUMENTEVENT_QUERYFILTER + /// The size, in bytes, of the buffer pointer to by pvOut. + /// + /// + /// DOCUMENTEVENT_ESCAPE + /// A value that is used as the cbOutput parameter for ExtEscape. + /// + /// + /// For all other values + /// iEsc is not used. + /// + /// + /// + /// + /// A pointer to a buffer. The contents of the buffer depend on the value supplied for iEsc, as shown in the following table. + /// + /// + /// Constant + /// pvOut Contents + /// + /// + /// DOCUMENTEVENT_CREATEDCPRE + /// + /// A pointer to a driver-supplied DEVMODE structure, which GDI uses instead of the one supplied by the CreateDC caller. (If NULL, + /// GDI uses the caller-supplied structure.) + /// + /// + /// + /// DOCUMENTEVENT_ESCAPE + /// A pointer to a buffer that is used as the lpszOutData parameter for ExtEscape. + /// + /// + /// DOCUMENTEVENT_QUERYFILTER + /// A pointer to buffer containing a DOCEVENT_FILTER structure which is documented in the Windows Driver Development Kit. + /// + /// + /// DOCUMENTEVENT_RESETDCPRE + /// + /// A pointer to a driver-supplied DEVMODE structure, which GDI uses instead of the one supplied by the ResetDC caller. (If NULL, + /// GDI uses the caller-supplied structure.) + /// + /// + /// + /// + /// + /// + /// The function's return value is dependent on the escape supplied for iEsc. For some escape codes, the return value is not used + /// (see below). If the function supplies a return value, it must be one of the following. + /// + /// + /// + /// Return Value + /// Meaning + /// + /// + /// DOCUMENTEVENT_FAILURE + /// The driver supports the escape code identified by iEsc, but a failure occurred. + /// + /// + /// DOCUMENTEVENT_SUCCESS + /// The driver successfully handled the escape code identified by iEsc. + /// + /// + /// DOCUMENTEVENT_UNSUPPORTED + /// The driver does not support the escape code identified by iEsc. + /// + /// + /// + /// The following list indicates which escape codes that require a return value and which do not, and explains the meaning of the + /// DOCUMENTEVENT_SUCCESS, DOCUMENTEVENT_FAILURE, and DOCUMENTEVENT_UNSUPPORTED return codes. + /// + /// + /// + /// Return Value + /// Meaning + /// + /// + /// DOCUMENTEVENT_ABORTDOC + /// The return value is not used and should not be read. + /// + /// + /// DOCUMENTEVENT_CREATEDCPOST + /// The return value is not used and should not be read. + /// + /// + /// DOCUMENTEVENT_CREATEDCPRE + /// + /// DOCUMENTEVENT_FAILURE - GDI does not create the device context or information context, and provides a return value of 0 for + /// CreateDC or CreateIC. + /// + /// + /// + /// DOCUMENTEVENT_DELETEDC + /// The return value is not used and should not be read. + /// + /// + /// DOCUMENTEVENT_ENDDOCPOST + /// The return value is not used and should not be read. + /// + /// + /// DOCUMENTEVENT_ENDDOCPRE or DOCUMENTEVENT_ENDDOC + /// The return value is not used and should not be read. + /// + /// + /// DOCUMENTEVENT_ENDPAGE + /// The return value is not used and should not be read. + /// + /// + /// DOCUMENTEVENT_ESCAPE + /// The return value is not used and should not be read. + /// + /// + /// DOCUMENTEVENT_QUERYFILTER + /// See Remarks. + /// + /// + /// DOCUMENTEVENT_RESETDCPOST + /// The return value is not used and should not be read. + /// + /// + /// DOCUMENTEVENT_RESETDCPRE + /// DOCUMENTEVENT_FAILURE - GDI does not reset the device context, and provides a return value of 0 for ResetDC. + /// + /// + /// DOCUMENTEVENT_STARTDOCPOST + /// DOCUMENTEVENT_FAILURE - GDI calls AbortDoc to stop the document, and then provides a return value of SP_ERROR for StartDoc. + /// + /// + /// DOCUMENTEVENT_STARTDOCPRE or DOCUMENTEVENT_STARTDOC + /// DOCUMENTEVENT_FAILURE - GDI does not start the document, and provides a return value of SP_ERROR for StartDoc. + /// + /// + /// DOCUMENTEVENT_STARTPAGE + /// DOCUMENTEVENT_FAILURE - GDI does not start the page, and provides a return value of SP_ERROR for StartPage. + /// + /// + /// + /// + /// + /// For an iEsc value of DOCUMENTEVENT_QUERYFILTER, the spooler can interpret a DOCUMENTEVENT_SUCCESS value returned by + /// DocumentEvent in two ways, depending on whether the driver modified certain members of the DOCEVENT_FILTER structure + /// (which is documented in the Windows Driver Development Kit ). (The pvOut parameter points to this structure.) When the spooler + /// allocates memory for a structure of this type, it initializes two members of this structure, cElementsReturned and + /// cElementsNeeded, to known values. After DocumentEvent returns, the spooler determines whether the values of these + /// members have changed, and uses that information to interpret the DocumentEvent return value. The following table + /// summarizes this situation. + /// + /// + /// + /// Return Value + /// Status of cElementsReturned and cElementsNeeded + /// Meaning + /// + /// + /// DOCUMENTEVENT_SUCCESS + /// Driver made no change to either member. + /// + /// The spooler interprets this return value as equivalent to DOCUMENTEVENT_UNSUPPORTED. The spooler is unable to retrieve the event + /// filter from the driver, so it persists in calling DocumentEvent for all events. + /// + /// + /// + /// DOCUMENTEVENT_SUCCESS + /// Driver wrote to one or both members. + /// + /// The spooler accepts this return value without interpretation. If the driver wrote to only one of cElementsNeeded and + /// cElementsReturned, the spooler considers the unchanged member to have a value of zero. The spooler filters out all events listed + /// in the aDocEventCall member of DOCEVENT_FILTER (which is documented in the Windows Driver Development Kit ). + /// + /// + /// + /// DOCUMENTEVENT_UNSUPPORTED + /// Not applicable + /// + /// The driver does not support DOCUMENTEVENT_QUERYFILTER. The spooler is unable to retrieve the event filter from the driver, so it + /// persists in calling DocumentEvent for all events. + /// + /// + /// + /// DOCUMENTEVENT_FAILURE + /// Not applicable + /// + /// The driver supports DOCUMENTEVENT_QUERYFILTER, but encountered an internal error. The spooler is unable to retrieve the event + /// filter from the driver, so it persists in calling DocumentEvent for all events. + /// + /// + /// + /// If the escape code supplied in the iEsc parameter is DOCUMENTEVENT_CREATEDCPRE, the following rules apply: + /// + /// + /// + /// If the job is being sent directly to the printer without spooling, pvIn->pszDevice points to the printer name. (For more + /// information, see the documentation for the DOCEVENT_CREATEDCPRE structure in the Windows Driver Development Kit.) + /// + /// + /// + /// If the job is being spooled, pvIn->pszDevice points to the printer port name. + /// + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/documentevent HRESULT DocumentEvent( _In_ HANDLE hPrinter, _In_ HDC hdc, + // INT iEsc, ULONG cbIn, _In_ PVOID pvIn, ULONG cbOut, _Out_ PVOID pvOut ); + [DllImport(Lib.Winspool, SetLastError = false, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "1250116e-55c7-470f-97f6-36f27a31a841")] + public static extern HRESULT DocumentEvent(HPRINTER hPrinter, HDC hdc, DOCUMENTEVENT iEsc, uint cbIn, IntPtr pvIn, uint cbOut, IntPtr pvOut); + + /// + /// The DocumentProperties function retrieves or modifies printer initialization information or displays a + /// printer-configuration property sheet for the specified printer. + /// + /// A handle to the parent window of the printer-configuration property sheet. + /// + /// A handle to a printer object. Use the OpenPrinter or AddPrinter function to retrieve a printer handle. + /// + /// + /// A pointer to a null-terminated string that specifies the name of the device for which the printer-configuration property sheet + /// is displayed. + /// + /// + /// A pointer to a DEVMODE structure that receives the printer configuration data specified by the user. + /// + /// + /// A pointer to a DEVMODE structure that the operating system uses to initialize the property sheet controls. + /// + /// This parameter is only used if the DM_IN_BUFFER flag is set in the fMode parameter. If DM_IN_BUFFER is not set, + /// the operating system uses the printer's default DEVMODE. + /// + /// + /// + /// + /// The operations the function performs. If this parameter is zero, the DocumentProperties function returns the number of + /// bytes required by the printer driver's DEVMODE data structure. Otherwise, use one or more of the following constants to + /// construct a value for this parameter; note, however, that in order to change the print settings, an application must specify at + /// least one input value and one output value. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// DM_IN_BUFFER + /// + /// Input value. Before prompting, copying, or updating, the function merges the printer driver's current print settings with the + /// settings in the DEVMODE structure specified by the pDevModeInput parameter. The function updates the structure only for those + /// members specified by the DEVMODE structure's dmFields member. This value is also defined as DM_MODIFY. In cases of conflict + /// during the merge, the settings in the DEVMODE structure specified by pDevModeInput override the printer driver's current print settings. + /// + /// + /// + /// DM_IN_PROMPT + /// + /// Input value. The function presents the printer driver's Print Setup property sheet and then changes the settings in the + /// printer's DEVMODE data structure to those values specified by the user. This value is also defined as DM_PROMPT. + /// + /// + /// + /// DM_OUT_BUFFER + /// + /// Output value. The function writes the printer driver's current print settings, including private data, to the DEVMODE data + /// structure specified by the pDevModeOutput parameter. The caller must allocate a buffer sufficiently large to contain the + /// information. If the bit DM_OUT_BUFFER sets is clear, the pDevModeOutput parameter can be NULL. This value is also defined as DM_COPY. + /// + /// + /// + /// + /// + /// + /// If the fMode parameter is zero, the return value is the size of the buffer required to contain the printer driver initialization + /// data. Note that this buffer can be larger than a DEVMODE structure if the printer driver appends private data to the structure. + /// + /// + /// If the function displays the property sheet, the return value is either IDOK or IDCANCEL, depending on which + /// button the user selects. + /// + /// If the function does not display the property sheet and is successful, the return value is IDOK. + /// If the function fails, the return value is less than zero. + /// + /// + /// The string pointed to by the pDeviceName parameter can be obtained by calling the GetPrinter function. + /// + /// The DEVMODE structure actually used by a printer driver contains the device-independent part (as defined above) followed + /// by a driver-specific part that varies in size and content with each driver and driver version. Because of this driver + /// dependence, it is very important for applications to query the driver for the correct size of the DEVMODE structure + /// before allocating a buffer for it. + /// + /// To make changes to print settings that are local to an application, an application should follow these steps: + /// + /// + /// + /// Get the number of bytes required for the full DEVMODE structure by calling DocumentProperties and specifying zero + /// in the fMode parameter. + /// + /// + /// + /// Allocate memory for the full DEVMODE structure. + /// + /// + /// + /// Get the current printer settings by calling DocumentProperties. Pass a pointer to the DEVMODE structure allocated + /// in Step 2 as the pDevModeOutput parameter and specify the DM_OUT_BUFFER value. + /// + /// + /// + /// + /// Modify the appropriate members of the returned DEVMODE structure and indicate which members were changed by setting the + /// corresponding bits in the dmFields member of the DEVMODE. + /// + /// + /// + /// + /// Call DocumentProperties and pass the modified DEVMODE structure back as both the pDevModeInput and pDevModeOutput + /// parameters and specify both the DM_IN_BUFFER and DM_OUT_BUFFER values (which are combined using the OR + /// operator).The DEVMODE structure returned by the third call to DocumentProperties can be used as an argument in a + /// call to the CreateDC function. + /// + /// + /// + /// + /// To create a handle to a printer-device context using the current printer settings, you only need to call + /// DocumentProperties twice, as described above. The first call gets the size of the full DEVMODE and the second call + /// initializes the DEVMODE with the current printer settings. Pass the initialized DEVMODE to CreateDC to + /// obtain the handle to the printer device context. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/documentproperties LONG DocumentProperties( _In_ HWND hWnd, _In_ HANDLE + // hPrinter, _In_ LPTSTR pDeviceName, _Out_ PDEVMODE pDevModeOutput, _In_ PDEVMODE pDevModeInput, _In_ DWORD fMode ); + [DllImport(Lib.Winspool, SetLastError = false, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "e89a2f6f-2bac-4369-b526-f8e15028698b")] + public static extern int DocumentProperties(HWND hWnd, HPRINTER hPrinter, string pDeviceName, IntPtr pDevModeOutput, in DEVMODE pDevModeInput, DM fMode); + + /// + /// The DocumentProperties function retrieves or modifies printer initialization information or displays a + /// printer-configuration property sheet for the specified printer. + /// + /// A handle to the parent window of the printer-configuration property sheet. + /// + /// A handle to a printer object. Use the OpenPrinter or AddPrinter function to retrieve a printer handle. + /// + /// + /// A pointer to a null-terminated string that specifies the name of the device for which the printer-configuration property sheet + /// is displayed. + /// + /// + /// A pointer to a DEVMODE structure that receives the printer configuration data specified by the user. + /// + /// + /// A pointer to a DEVMODE structure that the operating system uses to initialize the property sheet controls. + /// + /// This parameter is only used if the DM_IN_BUFFER flag is set in the fMode parameter. If DM_IN_BUFFER is not set, + /// the operating system uses the printer's default DEVMODE. + /// + /// + /// + /// + /// The operations the function performs. If this parameter is zero, the DocumentProperties function returns the number of + /// bytes required by the printer driver's DEVMODE data structure. Otherwise, use one or more of the following constants to + /// construct a value for this parameter; note, however, that in order to change the print settings, an application must specify at + /// least one input value and one output value. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// DM_IN_BUFFER + /// + /// Input value. Before prompting, copying, or updating, the function merges the printer driver's current print settings with the + /// settings in the DEVMODE structure specified by the pDevModeInput parameter. The function updates the structure only for those + /// members specified by the DEVMODE structure's dmFields member. This value is also defined as DM_MODIFY. In cases of conflict + /// during the merge, the settings in the DEVMODE structure specified by pDevModeInput override the printer driver's current print settings. + /// + /// + /// + /// DM_IN_PROMPT + /// + /// Input value. The function presents the printer driver's Print Setup property sheet and then changes the settings in the + /// printer's DEVMODE data structure to those values specified by the user. This value is also defined as DM_PROMPT. + /// + /// + /// + /// DM_OUT_BUFFER + /// + /// Output value. The function writes the printer driver's current print settings, including private data, to the DEVMODE data + /// structure specified by the pDevModeOutput parameter. The caller must allocate a buffer sufficiently large to contain the + /// information. If the bit DM_OUT_BUFFER sets is clear, the pDevModeOutput parameter can be NULL. This value is also defined as DM_COPY. + /// + /// + /// + /// + /// + /// + /// If the fMode parameter is zero, the return value is the size of the buffer required to contain the printer driver initialization + /// data. Note that this buffer can be larger than a DEVMODE structure if the printer driver appends private data to the structure. + /// + /// + /// If the function displays the property sheet, the return value is either IDOK or IDCANCEL, depending on which + /// button the user selects. + /// + /// If the function does not display the property sheet and is successful, the return value is IDOK. + /// If the function fails, the return value is less than zero. + /// + /// + /// The string pointed to by the pDeviceName parameter can be obtained by calling the GetPrinter function. + /// + /// The DEVMODE structure actually used by a printer driver contains the device-independent part (as defined above) followed + /// by a driver-specific part that varies in size and content with each driver and driver version. Because of this driver + /// dependence, it is very important for applications to query the driver for the correct size of the DEVMODE structure + /// before allocating a buffer for it. + /// + /// To make changes to print settings that are local to an application, an application should follow these steps: + /// + /// + /// + /// Get the number of bytes required for the full DEVMODE structure by calling DocumentProperties and specifying zero + /// in the fMode parameter. + /// + /// + /// + /// Allocate memory for the full DEVMODE structure. + /// + /// + /// + /// Get the current printer settings by calling DocumentProperties. Pass a pointer to the DEVMODE structure allocated + /// in Step 2 as the pDevModeOutput parameter and specify the DM_OUT_BUFFER value. + /// + /// + /// + /// + /// Modify the appropriate members of the returned DEVMODE structure and indicate which members were changed by setting the + /// corresponding bits in the dmFields member of the DEVMODE. + /// + /// + /// + /// + /// Call DocumentProperties and pass the modified DEVMODE structure back as both the pDevModeInput and pDevModeOutput + /// parameters and specify both the DM_IN_BUFFER and DM_OUT_BUFFER values (which are combined using the OR + /// operator).The DEVMODE structure returned by the third call to DocumentProperties can be used as an argument in a + /// call to the CreateDC function. + /// + /// + /// + /// + /// To create a handle to a printer-device context using the current printer settings, you only need to call + /// DocumentProperties twice, as described above. The first call gets the size of the full DEVMODE and the second call + /// initializes the DEVMODE with the current printer settings. Pass the initialized DEVMODE to CreateDC to + /// obtain the handle to the printer device context. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/documentproperties LONG DocumentProperties( _In_ HWND hWnd, _In_ HANDLE + // hPrinter, _In_ LPTSTR pDeviceName, _Out_ PDEVMODE pDevModeOutput, _In_ PDEVMODE pDevModeInput, _In_ DWORD fMode ); + [DllImport(Lib.Winspool, SetLastError = false, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "e89a2f6f-2bac-4369-b526-f8e15028698b")] + public static extern int DocumentProperties(HWND hWnd, HPRINTER hPrinter, string pDeviceName, IntPtr pDevModeOutput, [Optional] IntPtr pDevModeInput, DM fMode); + + /// The EndDocPrinter function ends a print job for the specified printer. + /// + /// Handle to a printer for which the print job should be ended. Use the OpenPrinter or AddPrinter function to + /// retrieve a printer handle. + /// + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + /// + /// + /// The EndDocPrinter function returns an error if the print job was not started by calling the StartDocPrinter function. + /// + /// The sequence for a print job is as follows: + /// + /// + /// To begin a print job, call StartDocPrinter. + /// + /// + /// To begin each page, call StartPagePrinter. + /// + /// + /// To write data to a page, call WritePrinter. + /// + /// + /// To end each page, call EndPagePrinter. + /// + /// + /// Repeat 2, 3, and 4 for as many pages as necessary. + /// + /// + /// To end the print job, call EndDocPrinter. + /// + /// + /// + /// When a page in a spooled file exceeds approximately 350 MB, it may fail to print and not send an error message. For example, + /// this can occur when printing large EMF files. The page size limit depends on many factors including the amount of virtual memory + /// available, the amount of memory allocated by calling processes, and the amount of fragmentation in the process heap. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/enddocprinter BOOL EndDocPrinter( _In_ HANDLE hPrinter ); + [DllImport(Lib.Winspool, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winspool.h", MSDNShortId = "13c713e8-cc24-4191-8b1e-967b9e20e541")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool EndDocPrinter(HPRINTER hPrinter); + + /// + /// The EndPagePrinter function notifies the print spooler that the application is at the end of a page in a print job. + /// + /// + /// Handle to the printer for which the page will be concluded. Use the OpenPrinter or AddPrinter function to retrieve + /// a printer handle. + /// + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + /// + /// The sequence for a print job is as follows: + /// + /// + /// To begin a print job, call StartDocPrinter. + /// + /// + /// To begin each page, call StartPagePrinter. + /// + /// + /// To write data to a page, call WritePrinter. + /// + /// + /// To end each page, call EndPagePrinter. + /// + /// + /// Repeat 2, 3, and 4 for as many pages as necessary. + /// + /// + /// To end the print job, call EndDocPrinter. + /// + /// + /// + /// When a page in a spooled file exceeds approximately 350 MB, it can fail to print and not send an error message. For example, + /// this can occur when printing large EMF files. The page size limit depends on many factors including the amount of virtual memory + /// available, the amount of memory allocated by calling processes, and the amount of fragmentation in the process heap. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/endpageprinter BOOL EndPagePrinter( _In_ HANDLE hPrinter ); + [DllImport(Lib.Winspool, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winspool.h", MSDNShortId = "aceb88b9-375b-4cd2-996a-c369f590154e")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool EndPagePrinter(HPRINTER hPrinter); + + /// The EnumForms function enumerates the forms supported by the specified printer. + /// + /// Handle to the printer for which the forms should be enumerated. Use the OpenPrinter or AddPrinter function to + /// retrieve a printer handle. + /// + /// Specifies the version of the structure to which pForm points. This value must be 1 or 2. + /// + /// Pointer to one or more FORM_INFO_1 structures or to one or more FORM_INFO_2 structures. All the structures will + /// have the same level. + /// + /// Specifies the size, in bytes, of the buffer to which pForm points. + /// + /// Pointer to a variable that receives the number of bytes copied to the array to which pForm points (if the operation succeeds) or + /// the number of bytes required (if it fails because cbBuf is too small). + /// + /// + /// Pointer to a variable that receives the number of structures copied into the array to which pForm points. + /// + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + /// + /// + /// If the caller is remote, and the Level is 2, the StringType value of the returned FORM_INFO_2 structures will + /// always be STRING_LANGPAIR. + /// + /// + /// In Windows Vista, the form data returned by EnumForms is retrieved from a local cache when hPrinter refers to a remote + /// print server or a printer hosted by a print server and there is at least one open connection to a printer on the remote print + /// server. In all other configurations, the form data is queried from the remote print server. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/enumforms BOOL EnumForms( _In_ HANDLE hPrinter, _In_ DWORD Level, _Out_ + // LPBYTE pForm, _In_ DWORD cbBuf, _Out_ LPDWORD pcbNeeded, _Out_ LPDWORD pcReturned ); + [DllImport(Lib.Winspool, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "b13b515a-c764-4a80-ab85-95fb4abb2a6b")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool EnumForms(HPRINTER hPrinter, uint Level, IntPtr pForm, uint cbBuf, out uint pcbNeeded, out uint pcReturned); + + /// The EnumForms function enumerates the forms supported by the specified printer. + /// The type of form information to enumerate. This must be either FORM_INFO_1 or FORM_INFO_2. + /// + /// Handle to the printer for which the forms should be enumerated. Use the OpenPrinter or AddPrinter function to + /// retrieve a printer handle. + /// + /// A sequence of FORM_INFO_1 or FORM_INFO_2 structures. All the structures will be of . + [PInvokeData("winspool.h", MSDNShortId = "b13b515a-c764-4a80-ab85-95fb4abb2a6b")] + public static IEnumerable EnumForms(HPRINTER hPrinter) where T : struct + { + if (!TryGetLevel("FORM_INFO_", out var lvl)) + throw new ArgumentException($"{nameof(EnumForms)} cannot process a structure of type {typeof(T).Name}."); + if (!EnumForms(hPrinter, lvl, default, 0, out var bytes, out var count)) + Win32Error.ThrowLastErrorUnless(Win32Error.ERROR_INSUFFICIENT_BUFFER); + if (bytes == 0) + return new T[0]; + using var mem = new SafeCoTaskMemHandle(bytes); + if (!EnumForms(hPrinter, lvl, mem, mem.Size, out bytes, out count)) + Win32Error.ThrowLastError(); + return mem.ToArray((int)count); + } + + /// The EnumJobs function retrieves information about a specified set of print jobs for a specified printer. + /// + /// A handle to the printer object whose print jobs the function enumerates. Use the OpenPrinter or AddPrinter + /// function to retrieve a printer handle. + /// + /// + /// The zero-based position within the print queue of the first print job to enumerate. For example, a value of 0 specifies that + /// enumeration should begin at the first print job in the print queue; a value of 9 specifies that enumeration should begin at the + /// tenth print job in the print queue. + /// + /// The total number of print jobs to enumerate. + /// + /// The type of information returned in the pJob buffer. + /// + /// + /// Value + /// Meaning + /// + /// + /// 1 + /// pJob receives an array of JOB_INFO_1 structures + /// + /// + /// 2 + /// pJob receives an array of JOB_INFO_2 structures + /// + /// + /// 3 + /// pJob receives an array of JOB_INFO_3 structures + /// + /// + /// + /// + /// + /// A pointer to a buffer that receives an array of JOB_INFO_1, JOB_INFO_2, or JOB_INFO_3 structures. The + /// buffer must be large enough to receive the array of structures and any strings or other data to which the structure members point. + /// + /// + /// To determine the required buffer size, call EnumJobs with cbBuf set to zero. EnumJobs fails, GetLastError + /// returns ERROR_INSUFFICIENT_BUFFER, and the pcbNeeded parameter returns the size, in bytes, of the buffer required to hold the + /// array of structures and their data. + /// + /// + /// The size, in bytes, of the pJob buffer. + /// + /// A pointer to a variable that receives the number of bytes copied if the function succeeds. If the function fails, the variable + /// receives the number of bytes required. + /// + /// + /// A pointer to a variable that receives the number of JOB_INFO_1, JOB_INFO_2, or JOB_INFO_3 structures + /// returned in the pJob buffer. + /// + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + /// + /// + /// The JOB_INFO_1 structure contains general print-job information; the JOB_INFO_2 structure has much more detailed + /// information. The JOB_INFO_3 structure contains information about how jobs are linked. + /// + /// + /// To determine the number of print jobs in the printer queue, call the GetPrinter function with the Level parameter set to 2. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/enumjobs BOOL EnumJobs( _In_ HANDLE hPrinter, _In_ DWORD FirstJob, _In_ + // DWORD NoJobs, _In_ DWORD Level, _Out_ LPBYTE pJob, _In_ DWORD cbBuf, _Out_ LPDWORD pcbNeeded, _Out_ LPDWORD pcReturned ); + [DllImport(Lib.Winspool, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "1cf429ea-b40e-4063-b6de-c43b7b87f3d3")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool EnumJobs(HPRINTER hPrinter, uint FirstJob, uint NoJobs, uint Level, IntPtr pJob, uint cbBuf, out uint pcbNeeded, out uint pcReturned); + + /// The EnumJobs function retrieves information about a specified set of print jobs for a specified printer. + /// + /// The type of form information to enumerate. This must be either JOB_INFO_1, JOB_INFO_2, or JOB_INFO_3. + /// + /// + /// A handle to the printer object whose print jobs the function enumerates. Use the OpenPrinter or AddPrinter + /// function to retrieve a printer handle. + /// + /// + /// The zero-based position within the print queue of the first print job to enumerate. For example, a value of 0 specifies that + /// enumeration should begin at the first print job in the print queue; a value of 9 specifies that enumeration should begin at the + /// tenth print job in the print queue. + /// + /// The total number of print jobs to enumerate. + /// + /// A sequence of JOB_INFO_1, JOB_INFO_2, or JOB_INFO_3 structures. All the structures will be of . + /// + [PInvokeData("winspool.h", MSDNShortId = "1cf429ea-b40e-4063-b6de-c43b7b87f3d3")] + public static IEnumerable EnumJobs(HPRINTER hPrinter, uint FirstJob = 0, uint NoJobs = uint.MaxValue) where T : struct + { + if (!TryGetLevel("JOB_INFO_", out var lvl)) + throw new ArgumentException($"{nameof(EnumJobs)} cannot process a structure of type {typeof(T).Name}."); + if (!EnumJobs(hPrinter, FirstJob, NoJobs, lvl, default, 0, out var bytes, out var count)) + Win32Error.ThrowLastErrorUnless(Win32Error.ERROR_INSUFFICIENT_BUFFER); + if (bytes == 0) + return new T[0]; + using var mem = new SafeCoTaskMemHandle(bytes); + if (!EnumJobs(hPrinter, FirstJob, NoJobs, lvl, mem, mem.Size, out bytes, out count)) + Win32Error.ThrowLastError(); + return mem.ToArray((int)count); + } + + /// + /// The EnumPrinterData function enumerates configuration data for a specified printer. + /// To retrieve the configuration data in a single call, use the EnumPrinterDataEx function. + /// + /// + /// A handle to the printer whose configuration data is to be obtained. Use the OpenPrinter or AddPrinter function to + /// retrieve a printer handle. + /// + /// + /// An index value that specifies the configuration data value to retrieve. + /// + /// Set this parameter to zero for the first call to EnumPrinterData for a specified printer handle. Then increment the + /// parameter by one for subsequent calls involving the same printer, until the function returns ERROR_NO_MORE_ITEMS. See the + /// following Remarks section for further information. + /// + /// + /// If you use the technique mentioned in the descriptions of the cbValueName and cbData parameters to obtain adequate buffer size + /// values, setting both those parameters to zero in a first call to EnumPrinterData for a specified printer handle, the + /// value of dwIndex does not matter for that call. Set dwIndex to zero in the next call to EnumPrinterData to start the + /// actual enumeration process. + /// + /// + /// Configuration data values are not ordered. New values will have an arbitrary index. This means that the EnumPrinterData + /// function may return values in any order. + /// + /// + /// + /// A pointer to a buffer that receives the name of the configuration data value, including a terminating null character. + /// + /// + /// The size, in bytes, of the buffer pointed to by pValueName. + /// + /// If you want to have the operating system supply an adequate buffer size, set both this parameter and the cbData parameter to + /// zero for the first call to EnumPrinterData for a specified printer handle. When the function returns, the variable + /// pointed to by pcbValueName will contain a buffer size that is large enough to successfully enumerate all of the printer's + /// configuration data value names. + /// + /// + /// A pointer to a variable that receives the number of bytes stored into the buffer pointed to by pValueName. + /// + /// A pointer to a variable that receives a code indicating the type of data stored in the specified value. For a list of the + /// possible type codes, see Registry Value Types. The pType parameter can be NULL if the type code is not required. + /// + /// + /// A pointer to a buffer that receives the configuration data value. + /// This parameter can be NULL if the configuration data value is not required. + /// + /// + /// The size, in bytes, of the buffer pointed to by pData. + /// + /// If you want to have the operating system supply an adequate buffer size, set both this parameter and the cbValueName parameter + /// to zero for the first call to EnumPrinterData for a specified printer handle. When the function returns, the variable + /// pointed to by pcbData will contain a buffer size that is large enough to successfully enumerate all of the printer's + /// configuration data value names. + /// + /// + /// + /// A pointer to a variable that receives the number of bytes stored into the buffer pointed to by pData. + /// This parameter can be NULL if pData is NULL. + /// + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. + /// If the function fails, the return value is a system error code. + /// + /// The function returns ERROR_NO_MORE_ITEMS when there are no more configuration data values to retrieve for a specified printer handle. + /// + /// + /// + /// + /// EnumPrinterData retrieves printer configuration data set by the SetPrinterData function. A printer's configuration + /// data consists of a set of named and typed values. The EnumPrinterData function obtains one of these values, and its name + /// and a type code, each time you call it. Call the EnumPrinterData function several times in succession to obtain all of a + /// printer's configuration data values. + /// + /// + /// Printer configuration data is stored in the registry. While enumerating printer configuration data, you should avoid calling + /// registry functions that might change that data. + /// + /// + /// If you want to have the operating system supply an adequate buffer size, first call EnumPrinterData with both the + /// cbValueName and cbData parameters set to zero, as noted earlier in the Parameters section. The value of dwIndex does not matter + /// for this call. When the function returns, *pcbValueName and *pcbData will contain buffer sizes that are large enough to + /// enumerate all of the printer's configuration data value names and values. On the next call, allocate value name and data + /// buffers, set cbValueName and cbData to the sizes in bytes of the allocated buffers, and set dwIndex to zero. Thereafter, + /// continue to call the EnumPrinterData function, incrementing dwIndex by one each time, until the function returns ERROR_NO_MORE_ITEMS. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/enumprinterdata DWORD EnumPrinterData( _In_ HANDLE hPrinter, _In_ DWORD + // dwIndex, _Out_ LPTSTR pValueName, _In_ DWORD cbValueName, _Out_ LPDWORD pcbValueName, _Out_ LPDWORD pType, _Out_ LPBYTE pData, + // _In_ DWORD cbData, _Out_ LPDWORD pcbData ); + [DllImport(Lib.Winspool, SetLastError = false, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "0a4c8436-46fe-4e21-8d55-c5031a3d1b38")] + public static extern Win32Error EnumPrinterData(HPRINTER hPrinter, uint dwIndex, StringBuilder pValueName, uint cbValueName, out uint pcbValueName, out REG_VALUE_TYPE pType, IntPtr pData, uint cbData, out uint pcbData); + + /// + /// The EnumPrinterData function enumerates configuration data for a specified printer. + /// To retrieve the configuration data in a single call, use the EnumPrinterDataEx function. + /// + /// + /// A handle to the printer whose configuration data is to be obtained. Use the OpenPrinter or AddPrinter function to + /// retrieve a printer handle. + /// + /// + /// A sequence of tuples, each with the following information. + /// + /// + /// valueName ( ) + /// The name of the configuration data value. + /// + /// + /// valueType ( ) + /// The type of data stored in the specified value. + /// + /// + /// value ( ) + /// The configuration data value. + /// + /// + /// + [PInvokeData("winspool.h", MSDNShortId = "0a4c8436-46fe-4e21-8d55-c5031a3d1b38")] + public static IEnumerable<(string valueName, REG_VALUE_TYPE valueType, object value)> EnumPrinterData(HPRINTER hPrinter) + { + var idx = 0U; + EnumPrinterData(hPrinter, idx, null, 0, out var valueNameSz, out var valueType, default, 0, out var dataSz).ThrowIfFailed(); + if (valueNameSz == 0) yield break; + var name = new StringBuilder(1024); + using var mem = new SafeCoTaskMemHandle(dataSz); + while (true) + { + name.EnsureCapacity((int)valueNameSz); + if (mem.Size < dataSz) mem.Size = dataSz; + var ret = EnumPrinterData(hPrinter, idx, name, (uint)name.Capacity, out valueNameSz, out valueType, mem, mem.Size, out dataSz); + if (ret == Win32Error.ERROR_NO_MORE_ITEMS) break; + if (ret == Win32Error.ERROR_MORE_DATA) continue; + ret.ThrowIfFailed(); + if (valueNameSz == 0) continue; + ++idx; + yield return (name.ToString(), valueType, valueType.GetValue(mem, mem.Size)); + } + } + + /// + /// The EnumPrinterDataEx function enumerates all value names and data for a specified printer and key. + /// + /// Printer data is stored in the registry. While enumerating printer data, do not call registry functions that might change the data. + /// + /// + /// + /// A handle to the printer for which the function retrieves configuration data. Use the OpenPrinter or AddPrinter + /// function to retrieve a printer handle. + /// + /// + /// + /// A pointer to a null-terminated string that specifies the key containing the values to enumerate. Use the backslash ( \ ) + /// character as a delimiter to specify a path with one or more subkeys. EnumPrinterDataEx enumerates all values of the key, + /// but does not enumerate values of subkeys of the specified key. Use the EnumPrinterKey function to enumerate subkeys. + /// + /// If pKeyName is NULL or an empty string, EnumPrinterDataEx returns ERROR_INVALID_PARAMETER. + /// + /// + /// A pointer to a buffer that receives an array of PRINTER_ENUM_VALUES structures. Each structure contains the value name, + /// type, data, and sizes of a value under the key. + /// + /// + /// The size, in bytes, of the buffer pointed to by pcbEnumValues. If you set cbEnumValues to zero, the pcbEnumValues parameter + /// returns the required buffer size. + /// + /// + /// A pointer to a variable that receives the size, in bytes, of the retrieved configuration data. If the buffer size specified by + /// cbEnumValues is too small, the function returns ERROR_MORE_DATA and pcbEnumValues indicates the required buffer size. + /// + /// + /// A pointer to a variable that receives the number of PRINTER_ENUM_VALUES structures returned in pEnumValues. + /// + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. + /// If the function fails, the return value is a system error code. + /// + /// + /// EnumPrinterDataEx retrieves printer configuration data set by the SetPrinterDataEx and SetPrinterData functions. + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/enumprinterdataex DWORD EnumPrinterDataEx( _In_ HANDLE hPrinter, _In_ + // LPCTSTR pKeyName, _Out_ LPBYTE pEnumValues, _In_ DWORD cbEnumValues, _Out_ LPDWORD pcbEnumValues, _Out_ LPDWORD pnEnumValues ); + [DllImport(Lib.Winspool, SetLastError = false, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "bc5ecc46-24a4-4b54-9431-0eaf6446e2d6")] + public static extern Win32Error EnumPrinterDataEx(HPRINTER hPrinter, string pKeyName, IntPtr pEnumValues, uint cbEnumValues, out uint pcbEnumValues, out uint pnEnumValues); + + /// + /// The EnumPrinterDataEx function enumerates all value names and data for a specified printer and key. + /// + /// Printer data is stored in the registry. While enumerating printer data, do not call registry functions that might change the data. + /// + /// + /// + /// A handle to the printer for which the function retrieves configuration data. Use the OpenPrinter or AddPrinter + /// function to retrieve a printer handle. + /// + /// + /// + /// A pointer to a null-terminated string that specifies the key containing the values to enumerate. Use the backslash ( \ ) + /// character as a delimiter to specify a path with one or more subkeys. EnumPrinterDataEx enumerates all values of the key, + /// but does not enumerate values of subkeys of the specified key. Use the EnumPrinterKey function to enumerate subkeys. + /// + /// If pKeyName is NULL or an empty string, EnumPrinterDataEx returns ERROR_INVALID_PARAMETER. + /// + /// + /// A sequence of tuples, each with the following information. + /// + /// + /// valueName ( ) + /// The name of the configuration data value. + /// + /// + /// valueType ( ) + /// The type of data stored in the specified value. + /// + /// + /// value ( ) + /// The configuration data value. + /// + /// + /// + [PInvokeData("winspool.h", MSDNShortId = "bc5ecc46-24a4-4b54-9431-0eaf6446e2d6")] + public static IEnumerable<(string valueName, REG_VALUE_TYPE valueType, object value)> EnumPrinterDataEx(HPRINTER hPrinter, string pKeyName = "PrinterDriverData") + { + EnumPrinterDataEx(hPrinter, pKeyName, default, 0, out var sz, out var cnt).ThrowUnless(Win32Error.ERROR_MORE_DATA); + using var mem = new SafeCoTaskMemHandle(sz); + EnumPrinterDataEx(hPrinter, pKeyName, mem, mem.Size, out sz, out cnt).ThrowIfFailed(); + return mem.ToEnumerable((int)cnt).Select(v => (v.pValueName, v.dwType, v.dwType.GetValue(v.pData, v.cbData))).ToArray(); + } + + /// + /// The EnumPrinterKey function enumerates the subkeys of a specified key for a specified printer. + /// + /// Printer data is stored in the registry. While enumerating printer data, do not call registry functions that might change the data. + /// + /// + /// + /// A handle to the printer for which the function enumerates subkeys. Use the OpenPrinter or AddPrinter function to + /// retrieve a printer handle. + /// + /// + /// + /// A pointer to a null-terminated string that specifies the key containing the subkeys to enumerate. Use the backslash '\' + /// character as a delimiter to specify a path with one or more subkeys. EnumPrinterKey enumerates all subkeys of the key, + /// but does not enumerate the subkeys of those subkeys. + /// + /// + /// If pKeyName is an empty string (""), EnumPrinterKey enumerates the top-level key for the printer. If pKeyName is + /// NULL, EnumPrinterKey returns ERROR_INVALID_PARAMETER. + /// + /// + /// + /// A pointer to a buffer that receives an array of null-terminated subkey names. The array is terminated by two null characters. + /// + /// + /// The size, in bytes, of the buffer pointed to by pSubkey. If you set cbSubkey to zero, the pcbSubkey parameter returns the + /// required buffer size. + /// + /// + /// A pointer to a variable that receives the number of bytes retrieved in the pSubkey buffer. If the buffer size specified by + /// cbSubkey is too small, the function returns ERROR_MORE_DATA and pcbSubkey indicates the required buffer size. + /// + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. + /// If the function fails, the return value is a system error code. If pKeyName does not exist, the return value is ERROR_FILE_NOT_FOUND. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/enumprinterkey DWORD EnumPrinterKey( _In_ HANDLE hPrinter, _In_ LPCTSTR + // pKeyName, _Out_ LPTSTR pSubkey, _In_ DWORD cbSubkey, _Out_ LPDWORD pcbSubkey ); + [DllImport(Lib.Winspool, SetLastError = false, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "721b1d23-a594-4439-b8f9-9b11be5fe874")] + public static extern Win32Error EnumPrinterKey(HPRINTER hPrinter, string pKeyName, IntPtr pSubkey, uint cbSubkey, out uint pcbSubkey); + + /// + /// The EnumPrinterKey function enumerates the subkeys of a specified key for a specified printer. + /// + /// Printer data is stored in the registry. While enumerating printer data, do not call registry functions that might change the data. + /// + /// + /// + /// A handle to the printer for which the function enumerates subkeys. Use the OpenPrinter or AddPrinter function to + /// retrieve a printer handle. + /// + /// + /// + /// A pointer to a null-terminated string that specifies the key containing the subkeys to enumerate. Use the backslash '\' + /// character as a delimiter to specify a path with one or more subkeys. EnumPrinterKey enumerates all subkeys of the key, + /// but does not enumerate the subkeys of those subkeys. + /// + /// + /// If pKeyName is an empty string (""), EnumPrinterKey enumerates the top-level key for the printer. If pKeyName is + /// NULL, EnumPrinterKey returns ERROR_INVALID_PARAMETER. + /// + /// + /// An array of subkey names. + [PInvokeData("winspool.h", MSDNShortId = "721b1d23-a594-4439-b8f9-9b11be5fe874")] + public static IEnumerable EnumPrinterKey(HPRINTER hPrinter, string pKeyName) + { + EnumPrinterKey(hPrinter, pKeyName, default, 0, out var bytes).ThrowUnless(Win32Error.ERROR_MORE_DATA); + if (bytes == 0) + return new string[0]; + using var mem = new SafeCoTaskMemHandle(bytes); + EnumPrinterKey(hPrinter, pKeyName, mem, mem.Size, out bytes).ThrowIfFailed(); + return mem.ToStringEnum().ToArray(); + } + + /// The EnumPrinters function enumerates available printers, print servers, domains, or print providers. + /// + /// The types of print objects that the function should enumerate. This value can be one or more of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// PRINTER_ENUM_LOCAL + /// + /// If the PRINTER_ENUM_NAME flag is not also passed, the function ignores the Name parameter, and enumerates the locally installed + /// printers. If PRINTER_ENUM_NAME is also passed, the function enumerates the local printers on Name. + /// + /// + /// + /// PRINTER_ENUM_NAME + /// + /// The function enumerates the printer identified by Name. This can be a server, a domain, or a print provider. If Name is NULL, + /// the function enumerates available print providers. + /// + /// + /// + /// PRINTER_ENUM_SHARED + /// + /// The function enumerates printers that have the shared attribute. Cannot be used in isolation; use an OR operation to combine + /// with another PRINTER_ENUM type. + /// + /// + /// + /// PRINTER_ENUM_CONNECTIONS + /// The function enumerates the list of printers to which the user has made previous connections. + /// + /// + /// PRINTER_ENUM_NETWORK + /// The function enumerates network printers in the computer's domain. This value is valid only if Level is 1. + /// + /// + /// PRINTER_ENUM_REMOTE + /// + /// The function enumerates network printers and print servers in the computer's domain. This value is valid only if Level is 1. + /// + /// + /// + /// PRINTER_ENUM_CATEGORY_3D + /// The function enumerates only 3D printers. + /// + /// + /// PRINTER_ENUM_CATEGORY_ALL + /// The function enumerates all print devices, including 3D printers. + /// + /// + /// If Level is 4, you can only use the PRINTER_ENUM_CONNECTIONS and PRINTER_ENUM_LOCAL constants. + /// + /// + /// + /// If Level is 1, Flags contains PRINTER_ENUM_NAME, and Name is non- NULL, then Name is a pointer to a null-terminated + /// string that specifies the name of the object to enumerate. This string can be the name of a server, a domain, or a print provider. + /// + /// + /// If Level is 1, Flags contains PRINTER_ENUM_NAME, and Name is NULL, then the function enumerates the available print providers. + /// + /// + /// If Level is 1, Flags contains PRINTER_ENUM_REMOTE, and Name is NULL, then the function enumerates the printers in the + /// user's domain. + /// + /// + /// If Level is 2 or 5,Name is a pointer to a null-terminated string that specifies the name of a server whose printers are to be + /// enumerated. If this string is NULL, then the function enumerates the printers installed on the local computer. + /// + /// If Level is 4, Name should be NULL. The function always queries on the local computer. + /// + /// When Name is NULL, setting Flags to PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS enumerates printers that are installed + /// on the local machine. These printers include those that are physically attached to the local machine as well as remote printers + /// to which it has a network connection. + /// + /// + /// When Name is not NULL, setting Flags to PRINTER_ENUM_LOCAL | PRINTER_ENUM_NAME enumerates the local printers that are + /// installed on the server Name. + /// + /// + /// + /// + /// The type of data structures pointed to by pPrinterEnum. Valid values are 1, 2, 4, and 5, which correspond to the + /// PRINTER_INFO_1, PRINTER_INFO_2 , PRINTER_INFO_4, and PRINTER_INFO_5 data structures. + /// + /// This value can be 1, 2, 4, or 5. + /// + /// + /// + /// A pointer to a buffer that receives an array of PRINTER_INFO_1, PRINTER_INFO_2, PRINTER_INFO_4, or + /// PRINTER_INFO_5 structures. Each structure contains data that describes an available print object. + /// + /// + /// If Level is 1, the array contains PRINTER_INFO_1 structures. If Level is 2, the array contains PRINTER_INFO_2 + /// structures. If Level is 4, the array contains PRINTER_INFO_4 structures. If Level is 5, the array contains + /// PRINTER_INFO_5 structures. + /// + /// + /// The buffer must be large enough to receive the array of data structures and any strings or other data to which the structure + /// members point. If the buffer is too small, the pcbNeeded parameter returns the required buffer size. + /// + /// + /// The size, in bytes, of the buffer pointed to by pPrinterEnum. + /// + /// A pointer to a value that receives the number of bytes copied if the function succeeds or the number of bytes required if cbBuf + /// is too small. + /// + /// + /// A pointer to a value that receives the number of PRINTER_INFO_1, PRINTER_INFO_2 , PRINTER_INFO_4, or + /// PRINTER_INFO_5 structures that the function returns in the array to which pPrinterEnum points. + /// + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + /// + /// Do not call this method in DllMain. + /// + /// If EnumPrinters returns a PRINTER_INFO_1 structure in which PRINTER_ENUM_CONTAINER is specified, this indicates + /// that there is a hierarchy of printer objects. An application can enumerate the hierarchy by calling EnumPrinters again, + /// setting Name to the value of the PRINTER_INFO_1 structure's pName member. + /// + /// + /// The EnumPrinters function does not retrieve security information. If PRINTER_INFO_2 structures are returned in the + /// array pointed to by pPrinterEnum, their pSecurityDescriptor members will be set to NULL. + /// + /// To get information about the default printer, call GetDefaultPrinter. + /// + /// The PRINTER_INFO_4 structure provides an easy and extremely fast way to retrieve the names of the printers installed on a + /// local machine, as well as the remote connections that a user has established. When EnumPrinters is called with a + /// PRINTER_INFO_4 data structure, that function queries the registry for the specified information, then returns + /// immediately. This differs from the behavior of EnumPrinters when called with other levels of PRINTER_INFO_* data + /// structures. In particular, when EnumPrinters is called with a level 2 ( PRINTER_INFO_2) data structure, it + /// performs an OpenPrinter call on each remote connection. If a remote connection is down, or the remote server no longer + /// exists, or the remote printer no longer exists, the function must wait for RPC to time out and consequently fail the + /// OpenPrinter call. This can take a while. Passing a PRINTER_INFO_4 structure lets an application retrieve a bare + /// minimum of required information; if more detailed information is desired, a subsequent EnumPrinters level 2 call can be made. + /// + /// + /// Windows Vista: The printer data returned by EnumPrinters is retrieved from a local cache when the value of Level + /// is 4. + /// + /// The following table shows the EnumPrinters output for various Flags values when the Level parameter is set to 1. + /// + /// In the Name parameter column of the table, you should substitute an appropriate name for Print Provider, Domain, and Machine. + /// For example, for "Print Provider," you could use the name of the network print provider or the name of the local print provider. + /// To retrieve print provider names, call EnumPrinters with Name set to NULL. + /// + /// + /// + /// Flags parameter + /// Name parameter + /// Result + /// + /// + /// PRINTER_ENUM_LOCAL (and not PRINTER_ENUM_NAME) + /// The Name parameter is ignored. + /// All local printers. + /// + /// + /// PRINTER_ENUM_NAME + /// "Print Provider" + /// All domain names + /// + /// + /// PRINTER_ENUM_NAME + /// "Print Provider!Domain" + /// All printers and print servers in the computer's domain + /// + /// + /// PRINTER_ENUM_NAME + /// "Print Provider!!\\Machine" + /// All printers shared at \\Machine + /// + /// + /// PRINTER_ENUM_NAME + /// An empty string, "" + /// All local printers. + /// + /// + /// PRINTER_ENUM_NAME + /// NULL + /// All print providers in the computer's domain + /// + /// + /// PRINTER_ENUM_CONNECTIONS + /// The Name parameter is ignored. + /// All connected remote printers + /// + /// + /// PRINTER_ENUM_NETWORK + /// The Name parameter is ignored. + /// All printers in the computer's domain + /// + /// + /// PRINTER_ENUM_REMOTE + /// An empty string, "" + /// All printers and print servers in the computer's domain + /// + /// + /// PRINTER_ENUM_REMOTE + /// "Print Provider" + /// Same as PRINTER_ENUM_NAME + /// + /// + /// PRINTER_ENUM_REMOTE + /// "Print Provider!Domain" + /// All printers and print servers in computer's domain, regardless of Domain specified. + /// + /// + /// PRINTER_ENUM_CATEGORY_3D + /// The Name parameter is ignored. + /// Only 3D printers are enumerated. + /// + /// + /// PRINTER_ENUM_CATEGORY_ALL + /// The Name parameter is ignored. + /// 3D printers are enumerated, along with all other printers. + /// + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/enumprinters BOOL EnumPrinters( _In_ DWORD Flags, _In_ LPTSTR Name, _In_ + // DWORD Level, _Out_ LPBYTE pPrinterEnum, _In_ DWORD cbBuf, _Out_ LPDWORD pcbNeeded, _Out_ LPDWORD pcReturned ); + [DllImport(Lib.Winspool, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "0d0cc726-c515-4146-9273-cdf1db3c76b7")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool EnumPrinters(PRINTER_ENUM Flags, string Name, uint Level, IntPtr pPrinterEnum, uint cbBuf, out uint pcbNeeded, out uint pcReturned); + + /// The EnumPrinters function enumerates available printers, print servers, domains, or print providers. + /// + /// The type of form information to enumerate. This must be either , , + /// , or . + /// + /// + /// The types of print objects that the function should enumerate. This value can be one or more of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// PRINTER_ENUM_LOCAL + /// + /// If the PRINTER_ENUM_NAME flag is not also passed, the function ignores the Name parameter, and enumerates the locally installed + /// printers. If PRINTER_ENUM_NAME is also passed, the function enumerates the local printers on Name. + /// + /// + /// + /// PRINTER_ENUM_NAME + /// + /// The function enumerates the printer identified by Name. This can be a server, a domain, or a print provider. If Name is NULL, + /// the function enumerates available print providers. + /// + /// + /// + /// PRINTER_ENUM_SHARED + /// + /// The function enumerates printers that have the shared attribute. Cannot be used in isolation; use an OR operation to combine + /// with another PRINTER_ENUM type. + /// + /// + /// + /// PRINTER_ENUM_CONNECTIONS + /// The function enumerates the list of printers to which the user has made previous connections. + /// + /// + /// PRINTER_ENUM_NETWORK + /// The function enumerates network printers in the computer's domain. This value is valid only if Level is 1. + /// + /// + /// PRINTER_ENUM_REMOTE + /// + /// The function enumerates network printers and print servers in the computer's domain. This value is valid only if Level is 1. + /// + /// + /// + /// PRINTER_ENUM_CATEGORY_3D + /// The function enumerates only 3D printers. + /// + /// + /// PRINTER_ENUM_CATEGORY_ALL + /// The function enumerates all print devices, including 3D printers. + /// + /// + /// If Level is 4, you can only use the PRINTER_ENUM_CONNECTIONS and PRINTER_ENUM_LOCAL constants. + /// + /// + /// + /// If Level is 1, Flags contains PRINTER_ENUM_NAME, and Name is non- NULL, then Name is a pointer to a null-terminated + /// string that specifies the name of the object to enumerate. This string can be the name of a server, a domain, or a print provider. + /// + /// + /// If Level is 1, Flags contains PRINTER_ENUM_NAME, and Name is NULL, then the function enumerates the available print providers. + /// + /// + /// If Level is 1, Flags contains PRINTER_ENUM_REMOTE, and Name is NULL, then the function enumerates the printers in the + /// user's domain. + /// + /// + /// If Level is 2 or 5,Name is a pointer to a null-terminated string that specifies the name of a server whose printers are to be + /// enumerated. If this string is NULL, then the function enumerates the printers installed on the local computer. + /// + /// If Level is 4, Name should be NULL. The function always queries on the local computer. + /// + /// When Name is NULL, setting Flags to PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS enumerates printers that are installed + /// on the local machine. These printers include those that are physically attached to the local machine as well as remote printers + /// to which it has a network connection. + /// + /// + /// When Name is not NULL, setting Flags to PRINTER_ENUM_LOCAL | PRINTER_ENUM_NAME enumerates the local printers that are + /// installed on the server Name. + /// + /// + /// + /// + /// A sequence of the structures of . Each structure contains data that describes an available print object. + /// + /// + [PInvokeData("winspool.h", MSDNShortId = "0d0cc726-c515-4146-9273-cdf1db3c76b7")] + public static IEnumerable EnumPrinters(PRINTER_ENUM Flags = PRINTER_ENUM.PRINTER_ENUM_LOCAL, string Name = null) where T : struct + { + if (!TryGetLevel("PRINTER_INFO_", out var lvl)) + throw new ArgumentException($"{nameof(EnumPrinters)} cannot process a structure of type {typeof(T).Name}."); + if (!EnumPrinters(Flags, Name, lvl, default, 0, out var bytes, out var count)) + Win32Error.ThrowLastErrorUnless(Win32Error.ERROR_INSUFFICIENT_BUFFER); + if (bytes == 0) + return new T[0]; + using var mem = new SafeCoTaskMemHandle(bytes); + if (!EnumPrinters(Flags, Name, lvl, mem, mem.Size, out bytes, out count)) + Win32Error.ThrowLastError(); + return mem.ToArray((int)count); + } + + /// + /// The FindClosePrinterChangeNotification function closes a change notification object created by calling the + /// FindFirstPrinterChangeNotification function. The printer or print server associated with the change notification object + /// will no longer be monitored by that object. + /// + /// + /// A handle to the change notification object to be closed. This is a handle created by calling the + /// FindFirstPrinterChangeNotification function. + /// + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + /// + /// After calling the FindClosePrinterChangeNotification function, you cannot use the hChange handle in subsequent calls to + /// either FindFirstPrinterChangeNotification or FindNextPrinterChangeNotification. + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/findcloseprinterchangenotification BOOL + // FindClosePrinterChangeNotification( _In_ HANDLE hChange ); + [DllImport(Lib.Winspool, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winspool.h", MSDNShortId = "2b4758f8-af0a-494b-8f1b-8ea6ee73c79b")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool FindClosePrinterChangeNotification(HPRINTERCHANGENOTIFICATION hChange); + + /// + /// + /// The FindFirstPrinterChangeNotification function creates a change notification object and returns a handle to the object. + /// You can then use this handle in a call to one of the wait functions to monitor changes to the printer or print server. + /// + /// + /// The FindFirstPrinterChangeNotification call specifies the type of changes to be monitored. You can specify a set of + /// conditions to monitor for changes, a set of printer information fields to monitor, or both. + /// + /// + /// A wait operation on the change notification handle succeeds when one of the specified changes occurs in the specified printer or + /// print server. You then call the FindNextPrinterChangeNotification function to retrieve information about the change, and + /// to reset the change notification object for use in the next wait operation. + /// + /// + /// + /// A handle to the printer or print server that you want to monitor. Use the OpenPrinter or AddPrinter function to + /// retrieve a printer handle. + /// + /// + /// + /// The conditions that will cause the change notification object to enter a signaled state. A change notification occurs when one + /// or more of the specified conditions are met. The fdwFilter parameter can be zero if pPrinterNotifyOptions is non- NULL. + /// + /// This parameter can be one or more of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// PRINTER_CHANGE_FORM + /// + /// Notify of any changes to a form. You can set this general flag or one or more of the following specific flags: + /// PRINTER_CHANGE_ADD_FORM PRINTER_CHANGE_SET_FORM PRINTER_CHANGE_DELETE_FORM + /// + /// + /// + /// PRINTER_CHANGE_JOB + /// + /// Notify of any changes to a job. You can set this general flag or one or more of the following specific flags: + /// PRINTER_CHANGE_ADD_JOB PRINTER_CHANGE_SET_JOB PRINTER_CHANGE_DELETE_JOB PRINTER_CHANGE_WRITE_JOB + /// + /// + /// + /// PRINTER_CHANGE_PORT + /// + /// Notify of any changes to a port. You can set this general flag or one or more of the following specific flags: + /// PRINTER_CHANGE_ADD_PORT PRINTER_CHANGE_CONFIGURE_PORT PRINTER_CHANGE_DELETE_PORT + /// + /// + /// + /// PRINTER_CHANGE_PRINT_PROCESSOR + /// + /// Notify of any changes to a print processor. You can set this general flag or one or more of the following specific flags: + /// PRINTER_CHANGE_ADD_PRINT_PROCESSOR PRINTER_CHANGE_DELETE_PRINT_PROCESSOR + /// + /// + /// + /// PRINTER_CHANGE_PRINTER + /// + /// Notify of any changes to a printer. You can set this general flag or one or more of the following specific flags: + /// PRINTER_CHANGE_ADD_PRINTER PRINTER_CHANGE_SET_PRINTER PRINTER_CHANGE_DELETE_PRINTER PRINTER_CHANGE_FAILED_CONNECTION_PRINTER + /// + /// + /// + /// PRINTER_CHANGE_PRINTER_DRIVER + /// + /// Notify of any changes to a printer driver. You can set this general flag or one or more of the following specific flags: + /// PRINTER_CHANGE_ADD_PRINTER_DRIVER PRINTER_CHANGE_SET_PRINTER_DRIVER PRINTER_CHANGE_DELETE_PRINTER_DRIVER + /// + /// + /// + /// PRINTER_CHANGE_ALL + /// Notify if any of the preceding changes occur. + /// + /// + /// PRINTER_CHANGE_SERVER + /// + /// Windows 7: Notify of any changes to the server. This flag is not included in the changes monitored by setting the + /// PRINTER_CHANGE_ALL value. + /// + /// + /// + /// For descriptions of the more specific flags in the preceding table, see the FindNextPrinterChangeNotification function. + /// + /// + /// The flag that determines the category of printers for which notifications will work. + /// + /// + /// Value + /// Meaning + /// + /// + /// PRINTER_NOTIFY_CATEGORY_ALL 0x001000 + /// FindNextPrinterChangeNotification returns notifications for both 2D and 3D printers. + /// + /// + /// PRINTER_NOTIFY_CATEGORY_3D 0x002000 + /// FindNextPrinterChangeNotification returns notifications only for 3D printers. + /// + /// + /// + /// When this flag is set to zero (0), FindFirstPrinterChangeNotification will only work for 2D printers. This is the default value. + /// + /// + /// + /// + /// A pointer to a PRINTER_NOTIFY_OPTIONS structure. The pTypes member of this structure is an array of one or more + /// PRINTER_NOTIFY_OPTIONS_TYPE structures, each of which specifies a printer information field to monitor. A change + /// notification occurs when one or more of the specified fields changes. When a change occurs, the + /// FindNextPrinterChangeNotification function can retrieve the new printer information. This parameter can be NULL if + /// fdwFilter is nonzero. + /// + /// For a list of fields that can be monitored, see PRINTER_NOTIFY_OPTIONS_TYPE. + /// + /// + /// + /// If the function succeeds, the return value is a handle to a change notification object associated with the specified printer or + /// print server. + /// + /// If the function fails, the return value is INVALID_HANDLE_VALUE. + /// + /// + /// + /// To monitor a printer or print server, call the FindFirstPrinterChangeNotification function, then use the returned change + /// notification object handle in a call to one of the wait functions. A wait operation on a change notification object is satisfied + /// when the change notification object enters the signaled state. The system signals the object when one or more of the changes + /// specified by fdwFilter or pPrinterNotifyOptions occurs in the monitored printer or print server. + /// + /// + /// When you call FindFirstPrinterChangeNotification, either fdwFilter must be nonzero or pPrinterNotifyOptions must be non- + /// NULL. If both are specified, notifications will occur for both. + /// + /// + /// When a wait operation on a printer change notification object is satisfied, call the FindNextPrinterChangeNotification + /// function to determine the cause of the notification. For a condition specified by fdwFilter, + /// FindNextPrinterChangeNotification reports the condition or conditions that changed. For a printer information field + /// specified by pPrinterNotifyOptions, FindNextPrinterChangeNotification reports the field or fields that changed as well as + /// the new information for these fields. FindNextPrinterChangeNotification also resets the change notification object to the + /// nonsignaled state so you can use it in another wait operation to continue monitoring the printer or print server. + /// + /// + /// With one exception, do not call the FindNextPrinterChangeNotification function if the change notification object is not + /// in the signaled state. If the wait function returns the value WAIT_TIMEOUT, the change object is not in the signaled state. Call + /// the FindNextPrinterChangeNotification function only if the wait function succeeds without timing out. The exception is + /// when FindNextPrinterChangeNotification is called with the PRINTER_NOTIFY_OPTIONS_REFRESH bit set in the + /// pPrinterNotifyOptions parameter. + /// + /// + /// When you no longer need the change notification object, close it by calling the FindClosePrinterChangeNotification function. + /// + /// + /// Callers of FindFirstPrinterChangeNotification must ensure that the printer handle passed into + /// FindFirstPrinterChangeNotification remains valid until FindClosePrinterChangeNotification is called. If the + /// printer handle is closed before the printer change notification handle, further notifications will fail to be delivered. + /// + /// FindFirstPrinterChangeNotification will not send change notifications for 3D printers to server handles. + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/findfirstprinterchangenotification HANDLE + // FindFirstPrinterChangeNotification( _In_ HANDLE hPrinter, DWORD fdwFilter, DWORD fdwOptions, _In_opt_ LPVOID + // pPrinterNotifyOptions ); + [DllImport(Lib.Winspool, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winspool.h", MSDNShortId = "4155ef5c-cd96-4960-919b-d9a495bb73a5")] + public static extern SafeHPRINTERCHANGENOTIFICATION FindFirstPrinterChangeNotification(HPRINTER hPrinter, PRINTER_CHANGE fdwFilter, PRINTER_NOTIFY_CATEGORY fdwOptions, in PRINTER_NOTIFY_OPTIONS pPrinterNotifyOptions); + + /// + /// + /// The FindFirstPrinterChangeNotification function creates a change notification object and returns a handle to the object. + /// You can then use this handle in a call to one of the wait functions to monitor changes to the printer or print server. + /// + /// + /// The FindFirstPrinterChangeNotification call specifies the type of changes to be monitored. You can specify a set of + /// conditions to monitor for changes, a set of printer information fields to monitor, or both. + /// + /// + /// A wait operation on the change notification handle succeeds when one of the specified changes occurs in the specified printer or + /// print server. You then call the FindNextPrinterChangeNotification function to retrieve information about the change, and + /// to reset the change notification object for use in the next wait operation. + /// + /// + /// + /// A handle to the printer or print server that you want to monitor. Use the OpenPrinter or AddPrinter function to + /// retrieve a printer handle. + /// + /// + /// + /// The conditions that will cause the change notification object to enter a signaled state. A change notification occurs when one + /// or more of the specified conditions are met. The fdwFilter parameter can be zero if pPrinterNotifyOptions is non- NULL. + /// + /// This parameter can be one or more of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// PRINTER_CHANGE_FORM + /// + /// Notify of any changes to a form. You can set this general flag or one or more of the following specific flags: + /// PRINTER_CHANGE_ADD_FORM PRINTER_CHANGE_SET_FORM PRINTER_CHANGE_DELETE_FORM + /// + /// + /// + /// PRINTER_CHANGE_JOB + /// + /// Notify of any changes to a job. You can set this general flag or one or more of the following specific flags: + /// PRINTER_CHANGE_ADD_JOB PRINTER_CHANGE_SET_JOB PRINTER_CHANGE_DELETE_JOB PRINTER_CHANGE_WRITE_JOB + /// + /// + /// + /// PRINTER_CHANGE_PORT + /// + /// Notify of any changes to a port. You can set this general flag or one or more of the following specific flags: + /// PRINTER_CHANGE_ADD_PORT PRINTER_CHANGE_CONFIGURE_PORT PRINTER_CHANGE_DELETE_PORT + /// + /// + /// + /// PRINTER_CHANGE_PRINT_PROCESSOR + /// + /// Notify of any changes to a print processor. You can set this general flag or one or more of the following specific flags: + /// PRINTER_CHANGE_ADD_PRINT_PROCESSOR PRINTER_CHANGE_DELETE_PRINT_PROCESSOR + /// + /// + /// + /// PRINTER_CHANGE_PRINTER + /// + /// Notify of any changes to a printer. You can set this general flag or one or more of the following specific flags: + /// PRINTER_CHANGE_ADD_PRINTER PRINTER_CHANGE_SET_PRINTER PRINTER_CHANGE_DELETE_PRINTER PRINTER_CHANGE_FAILED_CONNECTION_PRINTER + /// + /// + /// + /// PRINTER_CHANGE_PRINTER_DRIVER + /// + /// Notify of any changes to a printer driver. You can set this general flag or one or more of the following specific flags: + /// PRINTER_CHANGE_ADD_PRINTER_DRIVER PRINTER_CHANGE_SET_PRINTER_DRIVER PRINTER_CHANGE_DELETE_PRINTER_DRIVER + /// + /// + /// + /// PRINTER_CHANGE_ALL + /// Notify if any of the preceding changes occur. + /// + /// + /// PRINTER_CHANGE_SERVER + /// + /// Windows 7: Notify of any changes to the server. This flag is not included in the changes monitored by setting the + /// PRINTER_CHANGE_ALL value. + /// + /// + /// + /// For descriptions of the more specific flags in the preceding table, see the FindNextPrinterChangeNotification function. + /// + /// + /// The flag that determines the category of printers for which notifications will work. + /// + /// + /// Value + /// Meaning + /// + /// + /// PRINTER_NOTIFY_CATEGORY_ALL 0x001000 + /// FindNextPrinterChangeNotification returns notifications for both 2D and 3D printers. + /// + /// + /// PRINTER_NOTIFY_CATEGORY_3D 0x002000 + /// FindNextPrinterChangeNotification returns notifications only for 3D printers. + /// + /// + /// + /// When this flag is set to zero (0), FindFirstPrinterChangeNotification will only work for 2D printers. This is the default value. + /// + /// + /// + /// + /// A pointer to a PRINTER_NOTIFY_OPTIONS structure. The pTypes member of this structure is an array of one or more + /// PRINTER_NOTIFY_OPTIONS_TYPE structures, each of which specifies a printer information field to monitor. A change + /// notification occurs when one or more of the specified fields changes. When a change occurs, the + /// FindNextPrinterChangeNotification function can retrieve the new printer information. This parameter can be NULL if + /// fdwFilter is nonzero. + /// + /// For a list of fields that can be monitored, see PRINTER_NOTIFY_OPTIONS_TYPE. + /// + /// + /// + /// If the function succeeds, the return value is a handle to a change notification object associated with the specified printer or + /// print server. + /// + /// If the function fails, the return value is INVALID_HANDLE_VALUE. + /// + /// + /// + /// To monitor a printer or print server, call the FindFirstPrinterChangeNotification function, then use the returned change + /// notification object handle in a call to one of the wait functions. A wait operation on a change notification object is satisfied + /// when the change notification object enters the signaled state. The system signals the object when one or more of the changes + /// specified by fdwFilter or pPrinterNotifyOptions occurs in the monitored printer or print server. + /// + /// + /// When you call FindFirstPrinterChangeNotification, either fdwFilter must be nonzero or pPrinterNotifyOptions must be non- + /// NULL. If both are specified, notifications will occur for both. + /// + /// + /// When a wait operation on a printer change notification object is satisfied, call the FindNextPrinterChangeNotification + /// function to determine the cause of the notification. For a condition specified by fdwFilter, + /// FindNextPrinterChangeNotification reports the condition or conditions that changed. For a printer information field + /// specified by pPrinterNotifyOptions, FindNextPrinterChangeNotification reports the field or fields that changed as well as + /// the new information for these fields. FindNextPrinterChangeNotification also resets the change notification object to the + /// nonsignaled state so you can use it in another wait operation to continue monitoring the printer or print server. + /// + /// + /// With one exception, do not call the FindNextPrinterChangeNotification function if the change notification object is not + /// in the signaled state. If the wait function returns the value WAIT_TIMEOUT, the change object is not in the signaled state. Call + /// the FindNextPrinterChangeNotification function only if the wait function succeeds without timing out. The exception is + /// when FindNextPrinterChangeNotification is called with the PRINTER_NOTIFY_OPTIONS_REFRESH bit set in the + /// pPrinterNotifyOptions parameter. + /// + /// + /// When you no longer need the change notification object, close it by calling the FindClosePrinterChangeNotification function. + /// + /// + /// Callers of FindFirstPrinterChangeNotification must ensure that the printer handle passed into + /// FindFirstPrinterChangeNotification remains valid until FindClosePrinterChangeNotification is called. If the + /// printer handle is closed before the printer change notification handle, further notifications will fail to be delivered. + /// + /// FindFirstPrinterChangeNotification will not send change notifications for 3D printers to server handles. + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/findfirstprinterchangenotification HANDLE + // FindFirstPrinterChangeNotification( _In_ HANDLE hPrinter, DWORD fdwFilter, DWORD fdwOptions, _In_opt_ LPVOID + // pPrinterNotifyOptions ); + [DllImport(Lib.Winspool, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winspool.h", MSDNShortId = "4155ef5c-cd96-4960-919b-d9a495bb73a5")] + public static extern SafeHPRINTERCHANGENOTIFICATION FindFirstPrinterChangeNotification(HPRINTER hPrinter, PRINTER_CHANGE fdwFilter, PRINTER_NOTIFY_CATEGORY fdwOptions, [In, Optional] IntPtr pPrinterNotifyOptions); + + /// + /// + /// The FindNextPrinterChangeNotification function retrieves information about the most recent change notification for a + /// change notification object associated with a printer or print server. Call this function when a wait operation on the change + /// notification object is satisfied. + /// + /// + /// The function also resets the change notification object to the not-signaled state. You can then use the object in another wait + /// operation to continue monitoring the printer or print server. The operating system will set the object to the signaled state the + /// next time one of a specified set of changes occurs to the printer or print server. The FindFirstPrinterChangeNotification + /// function creates the change notification object and specifies the set of changes to be monitored. + /// + /// + /// + /// A handle to a change notification object associated with a printer or print server. You obtain such a handle by calling the + /// FindFirstPrinterChangeNotification function. The operating system sets this change notification object to the signaled + /// state when it detects one of the changes specified in the object's change notification filter. + /// + /// + /// + /// A pointer to a variable whose bits are set to indicate the changes that occurred to cause the most recent notification. The bit + /// flags that might be set correspond to those specified in the fdwFilter parameter of the + /// FindFirstPrinterChangeNotification call. The system sets one or more of the following bit flags. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// PRINTER_CHANGE_ADD_FORM + /// A form was added to the server. + /// + /// + /// PRINTER_CHANGE_ADD_JOB + /// A print job was sent to the printer. + /// + /// + /// PRINTER_CHANGE_ADD_PORT + /// A port or monitor was added to the server. + /// + /// + /// PRINTER_CHANGE_ADD_PRINT_PROCESSOR + /// A print processor was added to the server. + /// + /// + /// PRINTER_CHANGE_ADD_PRINTER + /// A printer was added to the server. + /// + /// + /// PRINTER_CHANGE_ADD_PRINTER_DRIVER + /// A printer driver was added to the server. + /// + /// + /// PRINTER_CHANGE_CONFIGURE_PORT + /// A port was configured on the server. + /// + /// + /// PRINTER_CHANGE_DELETE_FORM + /// A form was deleted from the server. + /// + /// + /// PRINTER_CHANGE_DELETE_JOB + /// A job was deleted. + /// + /// + /// PRINTER_CHANGE_DELETE_PORT + /// A port or monitor was deleted from the server. + /// + /// + /// PRINTER_CHANGE_DELETE_PRINT_PROCESSOR + /// A print processor was deleted from the server. + /// + /// + /// PRINTER_CHANGE_DELETE_PRINTER + /// A printer was deleted. + /// + /// + /// PRINTER_CHANGE_DELETE_PRINTER_DRIVER + /// A printer driver was deleted from the server. + /// + /// + /// PRINTER_CHANGE_FAILED_CONNECTION_PRINTER + /// A printer connection has failed. + /// + /// + /// PRINTER_CHANGE_SET_FORM + /// A form was set on the server. + /// + /// + /// PRINTER_CHANGE_SET_JOB + /// A job was set. + /// + /// + /// PRINTER_CHANGE_SET_PRINTER + /// A printer was set. + /// + /// + /// PRINTER_CHANGE_SET_PRINTER_DRIVER + /// A printer driver was set. + /// + /// + /// PRINTER_CHANGE_WRITE_JOB + /// Job data was written. + /// + /// + /// PRINTER_CHANGE_TIMEOUT + /// The job timed out. + /// + /// + /// PRINTER_CHANGE_SERVER + /// Windows 7: A change occurred on the server. + /// + /// + /// + /// + /// A pointer to a PRINTER_NOTIFY_OPTIONS structure. Set the Flags member of this structure to + /// PRINTER_NOTIFY_OPTIONS_REFRESH, to cause the function to return the current data for all monitored printer information + /// fields. The function ignores all other members of the structure. This parameter can be NULL. + /// + /// + /// + /// A pointer to a pointer variable that receives a pointer to a system-allocated, read-only buffer. Call the + /// FreePrinterNotifyInfo function to free the buffer when you are finished with it. This parameter can be NULL if no + /// information is required. + /// + /// + /// The buffer contains a PRINTER_NOTIFY_INFO structure, which contains an array of PRINTER_NOTIFY_INFO_DATA + /// structures. Each element of the array contains information about one of the fields specified in the pPrinterNotifyOptions + /// parameter of the FindFirstPrinterChangeNotification call. Typically, the function provides data only for the fields that + /// changed to cause the most recent notification. However, if the structure pointed to by the pPrinterNotifyOptions parameter + /// specifies PRINTER_NOTIFY_OPTIONS_REFRESH, the function provides data for all monitored fields. + /// + /// + /// If the PRINTER_NOTIFY_INFO_DISCARDED bit is set in the Flags member of the PRINTER_NOTIFY_INFO structure, + /// an overflow or error occurred, and notifications may have been lost. In this case, no additional notifications will be sent + /// until you make a second FindNextPrinterChangeNotification call that specifies PRINTER_NOTIFY_OPTIONS_REFRESH. + /// + /// + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + /// + /// + /// Call the FindNextPrinterChangeNotification function after a wait operation on a notification object created by + /// FindFirstPrinterChangeNotification has been satisfied. Calling FindNextPrinterChangeNotification lets you obtain + /// information about the change that satisfied the wait operation, and resets the notification object so it can be signaled when + /// the next change occurs. + /// + /// + /// With one exception, do not call the FindNextPrinterChangeNotification function if the change notification object is not + /// in the signaled state. If a wait function returns the value WAIT_TIMEOUT, the change object is not in the signaled state. + /// Call the FindNextPrinterChangeNotification function only if the wait function succeeds without timing out. The exception + /// is when FindNextPrinterChangeNotification is called with the PRINTER_NOTIFY_OPTIONS_REFRESH bit set in the + /// pPrinterNotifyOptions parameter. Note that even when this flag is set, it is still possible for the + /// PRINTER_NOTIFY_INFO_DISCARDED flag to be set in the ppPrinterNotifyInfo parameter. + /// + /// + /// To continue monitoring the printer or print server for changes, repeat the cycle of calling one of the wait functions , and then + /// calling the FindNextPrinterChangeNotification function to examine the change and reset the notification object. + /// + /// + /// FindNextPrinterChangeNotification may combine multiple changes to the same printer information field into a single + /// notification. When this occurs, the function typically collapses all changes for the field into a single entry in the array of + /// PRINTER_NOTIFY_INFO_DATA structures in ppPrinterNotifyInfo; the single entry reports only the most current information. + /// However, for some job and printer information fields, the function can return multiple array entries for the same field. In this + /// case, the last array entry for the field reports the current data, and the earlier entries contain the data for the intermediate stages. + /// + /// + /// When you no longer need the change notification object, close it by calling the FindClosePrinterChangeNotification function. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/findnextprinterchangenotification BOOL + // FindNextPrinterChangeNotification( _In_ HANDLE hChange, _Out_opt_ PDWORD pdwChange, _In_opt_ LPVOID pPrinterNotifyOptions, + // _Out_opt_ LPVOID *ppPrinterNotifyInfo ); + [DllImport(Lib.Winspool, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winspool.h", MSDNShortId = "ea7774ae-361f-41e4-bbc6-3f100028b22a")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool FindNextPrinterChangeNotification(HPRINTERCHANGENOTIFICATION hChange, out PRINTER_CHANGE pdwChange, in PRINTER_NOTIFY_OPTIONS pPrinterNotifyOptions, out SafePRINTER_NOTIFY_INFO ppPrinterNotifyInfo); + + /// The FlushPrinter function sends a buffer to the printer in order to clear it from a transient state. + /// + /// A handle to the printer object. This should be the same handle that was used, in a prior WritePrinter call, by the + /// printer driver. + /// + /// A pointer to an array of bytes that contains the data to be written to the printer. + /// The size, in bytes, of the array pointed to by pBuf. + /// A pointer to a value that receives the number of bytes of data that were written to the printer. + /// The time, in milliseconds, for which the I/O line to the printer port should be kept idle. + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. + /// + /// + /// + /// FlushPrinter should be called only if WritePrinter failed, leaving the printer in a transient state. For example, + /// the printer could get into a transient state when the job gets aborted and the printer driver has partially sent some raw data + /// to the printer. + /// + /// + /// FlushPrinter also can specify an idle period during which the print spooler does not schedule any jobs to the + /// corresponding printer port. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/flushprinter BOOL FlushPrinter( _In_ HANDLE hPrinter, _In_ LPVOID pBuf, + // _In_ DWORD cbBuf, _Out_ LPDWORD pcWritten, _In_ DWORD cSleep ); + [DllImport(Lib.Winspool, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winspool.h", MSDNShortId = "08e54175-da68-4ebd-91ec-8f4525f49d30")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool FlushPrinter(HPRINTER hPrinter, IntPtr pBuf, uint cbBuf, out uint pcWritten, uint cSleep); + + /// The FlushPrinter function sends a buffer to the printer in order to clear it from a transient state. + /// + /// A handle to the printer object. This should be the same handle that was used, in a prior WritePrinter call, by the + /// printer driver. + /// + /// A pointer to an array of bytes that contains the data to be written to the printer. + /// The size, in bytes, of the array pointed to by pBuf. + /// A pointer to a value that receives the number of bytes of data that were written to the printer. + /// The time, in milliseconds, for which the I/O line to the printer port should be kept idle. + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. + /// + /// + /// + /// FlushPrinter should be called only if WritePrinter failed, leaving the printer in a transient state. For example, + /// the printer could get into a transient state when the job gets aborted and the printer driver has partially sent some raw data + /// to the printer. + /// + /// + /// FlushPrinter also can specify an idle period during which the print spooler does not schedule any jobs to the + /// corresponding printer port. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/flushprinter BOOL FlushPrinter( _In_ HANDLE hPrinter, _In_ LPVOID pBuf, + // _In_ DWORD cbBuf, _Out_ LPDWORD pcWritten, _In_ DWORD cSleep ); + [DllImport(Lib.Winspool, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winspool.h", MSDNShortId = "08e54175-da68-4ebd-91ec-8f4525f49d30")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool FlushPrinter(HPRINTER hPrinter, byte[] pBuf, int cbBuf, out uint pcWritten, uint cSleep); + + /// + /// The FreePrinterNotifyInfo function frees a system-allocated buffer created by the + /// FindNextPrinterChangeNotification function. + /// + /// + /// Pointer to a PRINTER_NOTIFY_INFO buffer returned from a call to the FindNextPrinterChangeNotification function. + /// FreePrinterNotifyInfo deallocates this buffer. + /// + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/freeprinternotifyinfo BOOL FreePrinterNotifyInfo( _In_ + // PPRINTER_NOTIFY_INFO pPrinterNotifyInfo ); + [DllImport(Lib.Winspool, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winspool.h", MSDNShortId = "e50d4718-3682-486b-9d07-ddddd0b284dc")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool FreePrinterNotifyInfo(IntPtr pPrinterNotifyInfo); + + /// + /// The GetDefaultPrinter function retrieves the printer name of the default printer for the current user on the local computer. + /// + /// + /// A pointer to a buffer that receives a null-terminated character string containing the default printer name. If this parameter is + /// NULL, the function fails and the variable pointed to by pcchBuffer returns the required buffer size, in characters. + /// + /// + /// On input, specifies the size, in characters, of the pszBuffer buffer. On output, receives the size, in characters, of the + /// printer name string, including the terminating null character. + /// + /// + /// + /// If the function succeeds, the return value is a nonzero value and the variable pointed to by pcchBuffer contains the number of + /// characters copied to the pszBuffer buffer, including the terminating null character. + /// + /// If the function fails, the return value is zero. + /// + /// + /// Value + /// Meaning + /// + /// + /// ERROR_INSUFFICIENT_BUFFER + /// The pszBuffer buffer is too small. The variable pointed to by pcchBuffer contains the required buffer size, in characters. + /// + /// + /// ERROR_FILE_NOT_FOUND + /// There is no default printer. + /// + /// + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/getdefaultprinter BOOL GetDefaultPrinter( _In_ LPTSTR pszBuffer, _Inout_ + // LPDWORD pcchBuffer ); + [DllImport(Lib.Winspool, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "8ec06743-43ce-4fac-83c4-f09eac7ee333")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool GetDefaultPrinter(StringBuilder pszBuffer, ref uint pcchBuffer); + + /// The GetForm function retrieves information about a specified form. + /// + /// A handle to the printer. Use the OpenPrinter or AddPrinter function to retrieve a printer handle. + /// + /// + /// A pointer to a null-terminated string that specifies the name of the form. To get the names of the forms supported by the + /// printer, call the EnumForms function. + /// + /// The version of the structure to which pForm points. This value must be 1 or 2. + /// A pointer to an array of bytes that receives the initialized FORM_INFO_1 or FORM_INFO_2 structure. + /// The size, in bytes, of the pForm array. + /// + /// A pointer to a value that specifies the number of bytes copied if the function succeeds or the number of bytes required if cbBuf + /// is too small. + /// + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + /// + /// If the caller is remote, and the Level is 2, the StringType value of the returned FORM_INFO_2 will always be STRING_LANGPAIR. + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/getform BOOL GetForm( _In_ HANDLE hPrinter, _In_ LPTSTR pFormName, _In_ + // DWORD Level, _Out_ LPBYTE pForm, _In_ DWORD cbBuf, _Out_ LPDWORD pcbNeeded ); + [DllImport(Lib.Winspool, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "10b25748-6d7c-46ab-bd2c-9b6126a1d7d1")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool GetForm(HPRINTER hPrinter, string pFormName, uint Level, IntPtr pForm, uint cbBuf, out uint pcbNeeded); + + /// The GetForm function retrieves information about a specified form. + /// The type of the structure to get. This must be either FORM_INFO_1 or FORM_INFO_2. + /// + /// A handle to the printer. Use the OpenPrinter or AddPrinter function to retrieve a printer handle. + /// + /// + /// A pointer to a null-terminated string that specifies the name of the form. To get the names of the forms supported by the + /// printer, call the EnumForms function. + /// + /// The initialized FORM_INFO_1 or FORM_INFO_2 structure. + /// + /// + /// If the caller is remote, and the Level is 2, the StringType value of the returned FORM_INFO_2 will always be STRING_LANGPAIR. + /// + [PInvokeData("winspool.h", MSDNShortId = "10b25748-6d7c-46ab-bd2c-9b6126a1d7d1")] + public static T GetForm(HPRINTER hPrinter, string pFormName) where T : struct + { + if (!TryGetLevel("FORM_INFO_", out var lvl)) + throw new ArgumentException($"{nameof(GetForm)} cannot process a structure of type {typeof(T).Name}."); + if (!GetForm(hPrinter, pFormName, lvl, default, 0, out var sz)) + Win32Error.ThrowLastErrorUnless(Win32Error.ERROR_INSUFFICIENT_BUFFER); + using var mem = new SafeCoTaskMemHandle(sz); + if (!GetForm(hPrinter, pFormName, lvl, mem, mem.Size, out sz)) + Win32Error.ThrowLastError(); + return mem.ToStructure(); + } + + /// The GetJob function retrieves information about a specified print job. + /// + /// A handle to the printer for which the print-job data is retrieved. Use the OpenPrinter or AddPrinter function to + /// retrieve a printer handle. + /// + /// + /// Identifies the print job for which to retrieve data. Use the AddJob function or StartDoc function to get a print + /// job identifier. + /// + /// + /// The type of information returned in the pJob buffer. If Level is 1, pJob receives a JOB_INFO_1 structure. If Level is 2, + /// pJob receives a JOB_INFO_2 structure. + /// + /// + /// + /// A pointer to a buffer that receives a JOB_INFO_1 or a JOB_INFO_2 structure containing information about the job. + /// The buffer must be large enough to store the strings pointed to by the structure members. + /// + /// + /// To determine the required buffer size, call GetJob with cbBuf set to zero. GetJob fails, GetLastError + /// returns ERROR_INSUFFICIENT_BUFFER, and the pcbNeeded parameter returns the size, in bytes, of the buffer required to hold the + /// array of structures and their data. + /// + /// + /// The size, in bytes, of the array. + /// + /// A pointer to a value that specifies the number of bytes copied if the function succeeds or the number of bytes required if cbBuf + /// is too small. + /// + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/getjob BOOL GetJob( _In_ HANDLE hPrinter, _In_ DWORD JobId, _In_ DWORD + // Level, _Out_ LPBYTE pJob, _In_ DWORD cbBuf, _Out_ LPDWORD pcbNeeded ); + [DllImport(Lib.Winspool, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "57e59f84-d2a0-4722-b0fc-6673f7bb5c57")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool GetJob(HPRINTER hPrinter, uint JobId, uint Level, IntPtr pJob, uint cbBuf, out uint pcbNeeded); + + /// The GetJob function retrieves information about a specified print job. + /// The type of the structure to get. This must be either JOB_INFO_1 or a JOB_INFO_2. + /// + /// A handle to the printer for which the print-job data is retrieved. Use the OpenPrinter or AddPrinter function to + /// retrieve a printer handle. + /// + /// + /// Identifies the print job for which to retrieve data. Use the AddJob function or StartDoc function to get a print + /// job identifier. + /// + /// A JOB_INFO_1 or a JOB_INFO_2 structure containing information about the job as specified by . + /// + [PInvokeData("winspool.h", MSDNShortId = "57e59f84-d2a0-4722-b0fc-6673f7bb5c57")] + public static T GetJob(HPRINTER hPrinter, uint JobId) where T : struct + { + if (!TryGetLevel("JOB_INFO_", out var lvl)) + throw new ArgumentException($"{nameof(GetJob)} cannot process a structure of type {typeof(T).Name}."); + if (!GetJob(hPrinter, JobId, lvl, default, 0, out var sz)) + Win32Error.ThrowLastErrorUnless(Win32Error.ERROR_INSUFFICIENT_BUFFER); + using var mem = new SafeCoTaskMemHandle(sz); + if (!GetJob(hPrinter, JobId, lvl, mem, mem.Size, out sz)) + Win32Error.ThrowLastError(); + return mem.ToStructure(); + } + + /// The GetPrinter function retrieves information about a specified printer. + /// + /// A handle to the printer for which the function retrieves information. Use the OpenPrinter or AddPrinter function + /// to retrieve a printer handle. + /// + /// + /// The level or type of structure that the function stores into the buffer pointed to by pPrinter. + /// This value can be 1, 2, 3, 4, 5, 6, 7, 8 or 9. + /// + /// + /// + /// A pointer to a buffer that receives a structure containing information about the specified printer. The buffer must be large + /// enough to receive the structure and any strings or other data to which the structure members point. If the buffer is too small, + /// the pcbNeeded parameter returns the required buffer size. + /// + /// The type of structure is determined by the value of Level. + /// + /// + /// Level + /// Structure + /// + /// + /// 1 + /// A PRINTER_INFO_1 structure containing general printer information. + /// + /// + /// 2 + /// A PRINTER_INFO_2 structure containing detailed information about the printer. + /// + /// + /// 3 + /// A PRINTER_INFO_3 structure containing the printer's security information. + /// + /// + /// 4 + /// + /// A PRINTER_INFO_4 structure containing minimal printer information, including the name of the printer, the name of the server, + /// and whether the printer is remote or local. + /// + /// + /// + /// 5 + /// A PRINTER_INFO_5 structure containing printer information such as printer attributes and time-out settings. + /// + /// + /// 6 + /// A PRINTER_INFO_6 structure specifying the status value of a printer. + /// + /// + /// 7 + /// A PRINTER_INFO_7 structure that indicates whether the printer is published in the directory service. + /// + /// + /// 8 + /// A PRINTER_INFO_8 structure specifying the global default printer settings. + /// + /// + /// 9 + /// A PRINTER_INFO_9 structure specifying the per-user default printer settings. + /// + /// + /// + /// The size, in bytes, of the buffer pointed to by pPrinter. + /// + /// A pointer to a variable that the function sets to the size, in bytes, of the printer information. If cbBuf is smaller than this + /// value, GetPrinter fails, and the value represents the required buffer size. If cbBuf is equal to or greater than this + /// value, GetPrinter succeeds, and the value represents the number of bytes stored in the buffer. + /// + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + /// + /// + /// The pDevMode member in the PRINTER_INFO_2, PRINTER_INFO_8, and PRINTER_INFO_9 structures can be + /// NULL. When this happens, the printer is unusable until the driver is reinstalled successfully. + /// + /// + /// For the PRINTER_INFO_2 and PRINTER_INFO_3 structures that contain a pointer to a security descriptor, the function + /// retrieves only those components of the security descriptor that the caller has permission to read. To retrieve particular + /// security descriptor components, you must specify the necessary access rights when you call the OpenPrinter function to + /// retrieve a handle to the printer. The following table shows the access rights required to read the various security descriptor components. + /// + /// + /// + /// Access Right + /// Security Descriptor Component + /// + /// + /// READ_CONTROL + /// Owner Primary group Discretionary access-control list (DACL) + /// + /// + /// ACCESS_SYSTEM_SECURITY + /// System access-control list (SACL) + /// + /// + /// + /// If you specify level 7, the dwAction member of PRINTER_INFO_7 returns one of the following values to indicate + /// whether the printer is published in the directory service. + /// + /// + /// + /// dwAction value + /// Meaning + /// + /// + /// DSPRINT_PUBLISH + /// + /// The printer is published. The pszObjectGUID member contains the GUID of the directory services print queue object associated + /// with the printer. + /// + /// + /// + /// DSPRINT_UNPUBLISH + /// The printer is not published. + /// + /// + /// DSPRINT_PENDING + /// + /// Indicates that the system is attempting to complete a publish or unpublish operation. If a SetPrinter call fails to publish or + /// unpublish a printer, the system makes further attempts to complete the operation in the background. + /// + /// + /// + /// + /// Starting with Windows Vista, the printer data returned by GetPrinter is retrieved from a local cache when hPrinter refers + /// to a printer hosted by a print server and there is at least one open connection to the print server. In all other + /// configurations, the printer data is queried from the print server. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/getprinter BOOL GetPrinter( _In_ HANDLE hPrinter, _In_ DWORD Level, + // _Out_ LPBYTE pPrinter, _In_ DWORD cbBuf, _Out_ LPDWORD pcbNeeded ); + [DllImport(Lib.Winspool, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "f162edbb-83ee-40c3-8710-9c867301d652")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool GetPrinter(HPRINTER hPrinter, uint Level, IntPtr pPrinter, uint cbBuf, out uint pcbNeeded); + + /// The GetPrinter function retrieves information about a specified printer. + /// + /// The type of the structure to get. This must be either PRINTER_INFO_1, PRINTER_INFO_2, PRINTER_INFO_3, + /// PRINTER_INFO_4, PRINTER_INFO_5, PRINTER_INFO_6, PRINTER_INFO_7, PRINTER_INFO_8, or JOB_INFO_9. + /// + /// + /// A handle to the printer for which the function retrieves information. Use the OpenPrinter or AddPrinter function + /// to retrieve a printer handle. + /// + /// + /// A PRINTER_INFO_1, PRINTER_INFO_2, PRINTER_INFO_3, PRINTER_INFO_4, PRINTER_INFO_5, + /// PRINTER_INFO_6, PRINTER_INFO_7, PRINTER_INFO_8, or JOB_INFO_9 structure containing information about + /// the printer as specified by . + /// + /// + /// + /// The pDevMode member in the PRINTER_INFO_2, PRINTER_INFO_8, and PRINTER_INFO_9 structures can be + /// NULL. When this happens, the printer is unusable until the driver is reinstalled successfully. + /// + /// + /// For the PRINTER_INFO_2 and PRINTER_INFO_3 structures that contain a pointer to a security descriptor, the function + /// retrieves only those components of the security descriptor that the caller has permission to read. To retrieve particular + /// security descriptor components, you must specify the necessary access rights when you call the OpenPrinter function to + /// retrieve a handle to the printer. The following table shows the access rights required to read the various security descriptor components. + /// + /// + /// + /// Access Right + /// Security Descriptor Component + /// + /// + /// READ_CONTROL + /// Owner Primary group Discretionary access-control list (DACL) + /// + /// + /// ACCESS_SYSTEM_SECURITY + /// System access-control list (SACL) + /// + /// + /// + /// If you specify level 7, the dwAction member of PRINTER_INFO_7 returns one of the following values to indicate + /// whether the printer is published in the directory service. + /// + /// + /// + /// dwAction value + /// Meaning + /// + /// + /// DSPRINT_PUBLISH + /// + /// The printer is published. The pszObjectGUID member contains the GUID of the directory services print queue object associated + /// with the printer. + /// + /// + /// + /// DSPRINT_UNPUBLISH + /// The printer is not published. + /// + /// + /// DSPRINT_PENDING + /// + /// Indicates that the system is attempting to complete a publish or unpublish operation. If a SetPrinter call fails to publish or + /// unpublish a printer, the system makes further attempts to complete the operation in the background. + /// + /// + /// + /// + /// Starting with Windows Vista, the printer data returned by GetPrinter is retrieved from a local cache when hPrinter refers + /// to a printer hosted by a print server and there is at least one open connection to the print server. In all other + /// configurations, the printer data is queried from the print server. + /// + /// + public static T GetPrinter(HPRINTER hPrinter) where T : struct + { + if (!TryGetLevel("PRINTER_INFO_", out var lvl)) + throw new ArgumentException($"{nameof(GetPrinter)} cannot process a structure of type {typeof(T).Name}."); + if (!GetPrinter(hPrinter, lvl, default, 0, out var sz)) + Win32Error.ThrowLastErrorUnless(Win32Error.ERROR_INSUFFICIENT_BUFFER); + using var mem = new SafeCoTaskMemHandle(sz); + if (!GetPrinter(hPrinter, lvl, mem, mem.Size, out sz)) + Win32Error.ThrowLastError(); + return mem.ToStructure(); + } + + /// + /// The GetPrinterData function retrieves configuration data for the specified printer or print server. + /// + /// In Windows 2000 and later versions of Windows, calling GetPrinterData is equivalent to calling GetPrinterDataEx + /// with the pKeyName parameter set to "PrinterDriverData". + /// + /// + /// + /// A handle to the printer or print server for which the function retrieves configuration data. Use the OpenPrinter, + /// OpenPrinter2, or AddPrinter function to retrieve a printer handle. + /// + /// + /// A pointer to a null-terminated string that identifies the data to retrieve. + /// For printers, this string is the name of a registry value under the printer's "PrinterDriverData" key in the registry. + /// For print servers, this string is one of the predefined strings listed in the following Remarks section. + /// + /// + /// A pointer to a variable that receives a value that indicates the type of data retrieved in pData. The function returns the type + /// specified in the SetPrinterData or SetPrinterDataEx call that stored the data. Set this parameter to NULL + /// if you don't need the data type. + /// + /// A pointer to a buffer that receives the configuration data. + /// The size, in bytes, of the buffer that pData points to. + /// + /// A pointer to a variable that receives the size, in bytes, of the configuration data. If the buffer size specified by nSize is + /// too small, the function returns ERROR_MORE_DATA, and pcbNeeded indicates the required buffer size. + /// + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. If the function fails, the return value is an error value. + /// + /// + /// + /// GetPrinterData retrieves printer configuration data that was set by the SetPrinterDataEx or SetPrinterData function. + /// + /// + /// GetPrinterData might trigger a Windows call to GetPrinterDataFromPort, which might write to the registry. If it + /// does, side effects can occur, such as triggering an update or upgrade printer event ID 20 in the client, if the printer is + /// shared in a network. + /// + /// If hPrinter is a handle to a print server, pValueName can specify one of the following predefined values. + /// + /// + /// Value + /// Comments + /// + /// + /// SPLREG_ALLOW_USER_MANAGEFORMS + /// Windows XP with Service Pack 2 (SP2) and later Windows Server 2003 with Service Pack 1 (SP1) and later + /// + /// + /// SPLREG_ARCHITECTURE + /// + /// + /// + /// SPLREG_BEEP_ENABLED + /// + /// + /// + /// SPLREG_DEFAULT_SPOOL_DIRECTORY + /// + /// + /// + /// SPLREG_DNS_MACHINE_NAME + /// + /// + /// + /// SPLREG_DS_PRESENT + /// On successful return, pData contains 0x0001 if the machine is on a DS domain, 0 otherwise. + /// + /// + /// SPLREG_DS_PRESENT_FOR_USER + /// On successful return, pData contains 0x0001 if the user is logged onto a DS domain, 0 otherwise. + /// + /// + /// SPLREG_EVENT_LOG + /// + /// + /// + /// SPLREG_MAJOR_VERSION + /// + /// + /// + /// SPLREG_MINOR_VERSION + /// + /// + /// + /// SPLREG_NET_POPUP + /// Not supported in Windows Server 2003 and later + /// + /// + /// SPLREG_NET_POPUP_TO_COMPUTER + /// + /// On successful return, pData contains 1 if job notifications should be sent to the client computer, or 0 if job notifications are + /// to be sent to the user. Not supported in Windows Server 2003 and later + /// + /// + /// + /// SPLREG_OS_VERSION + /// Windows XP and later + /// + /// + /// SPLREG_OS_VERSIONEX + /// + /// + /// + /// SPLREG_PORT_THREAD_PRIORITY_DEFAULT + /// + /// + /// + /// SPLREG_PORT_THREAD_PRIORITY + /// + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_GROUPS + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_TIME_BEFORE_RECYCLE + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_MAX_OBJECTS_BEFORE_RECYCLE + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_IDLE_TIMEOUT + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_EXECUTION_POLICY + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_OVERRIDE_POLICY + /// Windows 7 and later + /// + /// + /// SPLREG_REMOTE_FAX + /// On successful return, pData contains 0x0001 if the FAX service supports remote clients, 0 otherwise. + /// + /// + /// SPLREG_RETRY_POPUP + /// + /// On successful return, pData contains 1 if server is set to retry pop-up windows for all jobs, or 0 if server does not retry + /// pop-up windows for all jobs. Not supported in Windows Server 2003 and later + /// + /// + /// + /// SPLREG_SCHEDULER_THREAD_PRIORITY + /// + /// + /// + /// SPLREG_SCHEDULER_THREAD_PRIORITY_DEFAULT + /// + /// + /// + /// SPLREG_WEBSHAREMGMT + /// Windows Server 2003 and later + /// + /// + /// The following values of pValueName indicate the pool printing behavior when an error occurs. + /// + /// + /// Value + /// Comments + /// + /// + /// SPLREG_RESTART_JOB_ON_POOL_ERROR + /// + /// The value of pData indicates the time, in seconds, when a job is restarted on another port after an error occurs. This setting + /// is used with SPLREG_RESTART_JOB_ON_POOL_ENABLED. + /// + /// + /// + /// SPLREG_RESTART_JOB_ON_POOL_ENABLED + /// A nonzero value in pData indicates that SPLREG_RESTART_JOB_ON_POOL_ERROR is enabled. + /// + /// + /// + /// The time specified in SPLREG_RESTART_JOB_ON_POOL_ERROR is a minimum time. The actual time can be longer, depending on the + /// following port monitor settings, which are registry values under this registry key: + /// + /// HKLM\SYSTEM\CurrentControlSet\Control\Print\Monitors\<MonitorName>\Ports + /// Call the RegQueryValueEx function to query these values. + /// + /// + /// Port monitor setting + /// Data type + /// Meaning + /// + /// + /// StatusUpdateEnabled + /// REG_DWORD + /// If a nonzero value, enables the port monitor to update the spooler with the port status. + /// + /// + /// StatusUpdateInterval + /// REG_DWORD + /// Specifies the interval, in minutes, when the port monitor updates the spooler with the port status. + /// + /// + /// + /// In Windows 7 and later versions of Windows, print jobs that are sent to a print server are rendered on the client by default. + /// The following values configure client-side rendering of a print jobs and can be read if you set the following values in pValueName. + /// + /// + /// + /// Setting + /// Data type + /// Description + /// + /// + /// EMFDespoolingSetting + /// REG_DWORD + /// + /// A value of 0, or if this value is not present in the registry, enables the default client-side rendering of print jobs. A value + /// of 1 disables client-side rendering of print jobs. + /// + /// + /// + /// ForceClientSideRendering + /// REG_DWORD + /// + /// A value of 0, or if this value is not present in the registry, will cause the print jobs to be rendered on the client. If a + /// print job cannot be rendered on the client, it will be rendered on the server. If a print job cannot be rendered on the server, + /// it will fail. A value of 1 will render print jobs on the client. If a print job cannot be rendered on the client, it will fail. + /// + /// + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/getprinterdata DWORD GetPrinterData( _In_ HANDLE hPrinter, _In_ LPTSTR + // pValueName, _Out_ LPDWORD pType, _Out_ LPBYTE pData, _In_ DWORD nSize, _Out_ LPDWORD pcbNeeded ); + [DllImport(Lib.Winspool, SetLastError = false, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "b5a44b27-a4aa-4e58-9a64-05be87d12ab5")] + public static extern Win32Error GetPrinterData(HPRINTER hPrinter, string pValueName, out REG_VALUE_TYPE pType, IntPtr pData, uint nSize, out uint pcbNeeded); + + /// + /// The GetPrinterData function retrieves configuration data for the specified printer or print server. + /// + /// In Windows 2000 and later versions of Windows, calling GetPrinterData is equivalent to calling GetPrinterDataEx + /// with the pKeyName parameter set to "PrinterDriverData". + /// + /// + /// + /// A handle to the printer or print server for which the function retrieves configuration data. Use the OpenPrinter, + /// OpenPrinter2, or AddPrinter function to retrieve a printer handle. + /// + /// + /// A pointer to a null-terminated string that identifies the data to retrieve. + /// For printers, this string is the name of a registry value under the printer's "PrinterDriverData" key in the registry. + /// For print servers, this string is one of the predefined strings listed in the following Remarks section. + /// + /// THe requested configuration data. + /// + /// + /// GetPrinterData retrieves printer configuration data that was set by the SetPrinterDataEx or SetPrinterData function. + /// + /// + /// GetPrinterData might trigger a Windows call to GetPrinterDataFromPort, which might write to the registry. If it + /// does, side effects can occur, such as triggering an update or upgrade printer event ID 20 in the client, if the printer is + /// shared in a network. + /// + /// If hPrinter is a handle to a print server, pValueName can specify one of the following predefined values. + /// + /// + /// Value + /// Comments + /// + /// + /// SPLREG_ALLOW_USER_MANAGEFORMS + /// Windows XP with Service Pack 2 (SP2) and later Windows Server 2003 with Service Pack 1 (SP1) and later + /// + /// + /// SPLREG_ARCHITECTURE + /// + /// + /// + /// SPLREG_BEEP_ENABLED + /// + /// + /// + /// SPLREG_DEFAULT_SPOOL_DIRECTORY + /// + /// + /// + /// SPLREG_DNS_MACHINE_NAME + /// + /// + /// + /// SPLREG_DS_PRESENT + /// On successful return, pData contains 0x0001 if the machine is on a DS domain, 0 otherwise. + /// + /// + /// SPLREG_DS_PRESENT_FOR_USER + /// On successful return, pData contains 0x0001 if the user is logged onto a DS domain, 0 otherwise. + /// + /// + /// SPLREG_EVENT_LOG + /// + /// + /// + /// SPLREG_MAJOR_VERSION + /// + /// + /// + /// SPLREG_MINOR_VERSION + /// + /// + /// + /// SPLREG_NET_POPUP + /// Not supported in Windows Server 2003 and later + /// + /// + /// SPLREG_NET_POPUP_TO_COMPUTER + /// + /// On successful return, pData contains 1 if job notifications should be sent to the client computer, or 0 if job notifications are + /// to be sent to the user. Not supported in Windows Server 2003 and later + /// + /// + /// + /// SPLREG_OS_VERSION + /// Windows XP and later + /// + /// + /// SPLREG_OS_VERSIONEX + /// + /// + /// + /// SPLREG_PORT_THREAD_PRIORITY_DEFAULT + /// + /// + /// + /// SPLREG_PORT_THREAD_PRIORITY + /// + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_GROUPS + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_TIME_BEFORE_RECYCLE + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_MAX_OBJECTS_BEFORE_RECYCLE + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_IDLE_TIMEOUT + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_EXECUTION_POLICY + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_OVERRIDE_POLICY + /// Windows 7 and later + /// + /// + /// SPLREG_REMOTE_FAX + /// On successful return, pData contains 0x0001 if the FAX service supports remote clients, 0 otherwise. + /// + /// + /// SPLREG_RETRY_POPUP + /// + /// On successful return, pData contains 1 if server is set to retry pop-up windows for all jobs, or 0 if server does not retry + /// pop-up windows for all jobs. Not supported in Windows Server 2003 and later + /// + /// + /// + /// SPLREG_SCHEDULER_THREAD_PRIORITY + /// + /// + /// + /// SPLREG_SCHEDULER_THREAD_PRIORITY_DEFAULT + /// + /// + /// + /// SPLREG_WEBSHAREMGMT + /// Windows Server 2003 and later + /// + /// + /// The following values of pValueName indicate the pool printing behavior when an error occurs. + /// + /// + /// Value + /// Comments + /// + /// + /// SPLREG_RESTART_JOB_ON_POOL_ERROR + /// + /// The value of pData indicates the time, in seconds, when a job is restarted on another port after an error occurs. This setting + /// is used with SPLREG_RESTART_JOB_ON_POOL_ENABLED. + /// + /// + /// + /// SPLREG_RESTART_JOB_ON_POOL_ENABLED + /// A nonzero value in pData indicates that SPLREG_RESTART_JOB_ON_POOL_ERROR is enabled. + /// + /// + /// + /// The time specified in SPLREG_RESTART_JOB_ON_POOL_ERROR is a minimum time. The actual time can be longer, depending on the + /// following port monitor settings, which are registry values under this registry key: + /// + /// HKLM\SYSTEM\CurrentControlSet\Control\Print\Monitors\<MonitorName>\Ports + /// Call the RegQueryValueEx function to query these values. + /// + /// + /// Port monitor setting + /// Data type + /// Meaning + /// + /// + /// StatusUpdateEnabled + /// REG_DWORD + /// If a nonzero value, enables the port monitor to update the spooler with the port status. + /// + /// + /// StatusUpdateInterval + /// REG_DWORD + /// Specifies the interval, in minutes, when the port monitor updates the spooler with the port status. + /// + /// + /// + /// In Windows 7 and later versions of Windows, print jobs that are sent to a print server are rendered on the client by default. + /// The following values configure client-side rendering of a print jobs and can be read if you set the following values in pValueName. + /// + /// + /// + /// Setting + /// Data type + /// Description + /// + /// + /// EMFDespoolingSetting + /// REG_DWORD + /// + /// A value of 0, or if this value is not present in the registry, enables the default client-side rendering of print jobs. A value + /// of 1 disables client-side rendering of print jobs. + /// + /// + /// + /// ForceClientSideRendering + /// REG_DWORD + /// + /// A value of 0, or if this value is not present in the registry, will cause the print jobs to be rendered on the client. If a + /// print job cannot be rendered on the client, it will be rendered on the server. If a print job cannot be rendered on the server, + /// it will fail. A value of 1 will render print jobs on the client. If a print job cannot be rendered on the client, it will fail. + /// + /// + /// + /// + [PInvokeData("winspool.h", MSDNShortId = "b5a44b27-a4aa-4e58-9a64-05be87d12ab5")] + public static object GetPrinterData(HPRINTER hPrinter, string pValueName) + { + GetPrinterData(hPrinter, pValueName, out var type, default, 0, out var sz).ThrowUnless(Win32Error.ERROR_MORE_DATA); + using var mem = new SafeCoTaskMemHandle(sz); + GetPrinterData(hPrinter, pValueName, out type, mem, mem.Size, out sz).ThrowIfFailed(); + return type.GetValue(mem, mem.Size); + } + + /// + /// The GetPrinterDataEx function retrieves configuration data for the specified printer or print server. + /// GetPrinterDataEx can retrieve values that the SetPrinterData function stored. In addition, GetPrinterDataEx + /// can retrieve values that the SetPrinterDataEx function stored under a specified key. + /// + /// + /// A handle to the printer or print server for which the function retrieves configuration data. Use the OpenPrinter, + /// OpenPrinter2, or AddPrinter function to retrieve a printer handle. + /// + /// + /// + /// A pointer to a null-terminated string that specifies the key containing the value to be retrieved. Use the backslash ( \ ) + /// character as a delimiter to specify a path that has one or more subkeys. + /// + /// If hPrinter is a handle to a printer and pKeyName is NULL or an empty string, GetPrinterDataEx returns ERROR_INVALID_PARAMETER. + /// If hPrinter is a handle to a print server, pKeyName is ignored. + /// + /// + /// A pointer to a null-terminated string that identifies the data to retrieve. + /// For printers, this string specifies the name of a value under the pKeyName key. + /// For print servers, this string is one of the predefined strings listed in the following Remarks section. + /// + /// + /// A pointer to a variable that receives the type of data stored in the value. The function returns the type specified in the + /// SetPrinterDataEx call when the data was stored. This parameter can be NULL if you don't need the information. + /// GetPrinterDataEx passes pType on as the lpdwType parameter of a RegQueryValueEx function call. + /// + /// A pointer to a buffer that receives the configuration data. + /// The size, in bytes, of the buffer pointed to by pData. + /// + /// A pointer to a variable that receives the size, in bytes, of the configuration data. If the buffer size specified by nSize is + /// too small, the function returns ERROR_MORE_DATA, and pcbNeeded indicates the required buffer size. + /// + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. + /// If the function fails, the return value is an error value. + /// + /// + /// + /// GetPrinterDataEx retrieves printer-configuration data that was set by the SetPrinterDataEx and + /// SetPrinterData functions. + /// + /// + /// Calling GetPrinterDataEx with the pKeyName parameter set to "PrinterDriverData" is equivalent to calling the + /// GetPrinterData function. + /// + /// If hPrinter is a handle to a print server, pValueName can specify one of the following predefined values. + /// + /// + /// Value + /// Comments + /// + /// + /// SPLREG_ALLOW_USER_MANAGEFORMS + /// Windows XP with Service Pack 2 (SP2) and later Windows Server 2003 with Service Pack 1 (SP1) and later + /// + /// + /// SPLREG_ARCHITECTURE + /// + /// + /// + /// SPLREG_BEEP_ENABLED + /// + /// + /// + /// SPLREG_DEFAULT_SPOOL_DIRECTORY + /// + /// + /// + /// SPLREG_DNS_MACHINE_NAME + /// + /// + /// + /// SPLREG_DS_PRESENT + /// On successful return, pData contains 0x0001 if the machine is on a DS domain, 0 otherwise. + /// + /// + /// SPLREG_DS_PRESENT_FOR_USER + /// On successful return, pData contains 0x0001 if the user is logged onto a DS domain, 0 otherwise. + /// + /// + /// SPLREG_EVENT_LOG + /// + /// + /// + /// SPLREG_MAJOR_VERSION + /// + /// + /// + /// SPLREG_MINOR_VERSION + /// + /// + /// + /// SPLREG_NET_POPUP + /// Not supported in Windows Server 2003 and later + /// + /// + /// SPLREG_NET_POPUP_TO_COMPUTER + /// + /// On successful return, pData contains 1 if job notifications should be sent to the client computer, or 0 if job notifications are + /// to be sent to the user. Not supported in Windows Server 2003 and later + /// + /// + /// + /// SPLREG_OS_VERSION + /// Windows XP and later + /// + /// + /// SPLREG_OS_VERSIONEX + /// + /// + /// + /// SPLREG_PORT_THREAD_PRIORITY_DEFAULT + /// + /// + /// + /// SPLREG_PORT_THREAD_PRIORITY + /// + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_GROUPS + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_TIME_BEFORE_RECYCLE + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_MAX_OBJECTS_BEFORE_RECYCLE + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_IDLE_TIMEOUT + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_EXECUTION_POLICY + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_OVERRIDE_POLICY + /// Windows 7 and later + /// + /// + /// SPLREG_REMOTE_FAX + /// On successful return, pData contains 0x0001 if the FAX service supports remote clients, 0 otherwise. + /// + /// + /// SPLREG_RETRY_POPUP + /// + /// On successful return, pData contains 1 if server is set to retry pop-up windows for all jobs, or 0 if server does not retry + /// pop-up windows for all jobs. Not supported in Windows Server 2003 and later + /// + /// + /// + /// SPLREG_SCHEDULER_THREAD_PRIORITY + /// + /// + /// + /// SPLREG_SCHEDULER_THREAD_PRIORITY_DEFAULT + /// + /// + /// + /// SPLREG_WEBSHAREMGMT + /// Windows Server 2003 and later + /// + /// + /// The following values of pValueName indicate the pool printing behavior when an error occurs. + /// + /// + /// Value + /// Comments + /// + /// + /// SPLREG_RESTART_JOB_ON_POOL_ERROR + /// + /// The value of pData indicates the time, in seconds, when a job is restarted on another port after an error occurs. This setting + /// is used with SPLREG_RESTART_JOB_ON_POOL_ENABLED. + /// + /// + /// + /// SPLREG_RESTART_JOB_ON_POOL_ENABLED + /// A nonzero value in pData indicates that SPLREG_RESTART_JOB_ON_POOL_ERROR is enabled. + /// + /// + /// + /// The time specified in SPLREG_RESTART_JOB_ON_POOL_ERROR is a minimum time. The actual time can be longer, depending on the + /// following port monitor settings, which are registry values under this registry key: + /// + /// HKLM\SYSTEM\CurrentControlSet\Control\Print\Monitors\<MonitorName>\Ports + /// Call the RegQueryValueEx function to query these values. + /// + /// + /// Port monitor setting + /// Data type + /// Meaning + /// + /// + /// StatusUpdateEnabled + /// REG_DWORD + /// If a nonzero value, enables the port monitor to update the spooler with the port status. + /// + /// + /// StatusUpdateInterval + /// REG_DWORD + /// Specifies the interval, in minutes, when the port monitor updates the spooler with the port status. + /// + /// + /// + /// If pKeyName is one of the predefined Directory Service (DS) keys (see SetPrinter) and pValueName contains a comma (','), + /// then the portion of pValueName before the comma is the value name and the portion of pValueName to the right of the comma is the + /// DS Property OID. A subkey called OID is created and a new value that consists of the value name and OID is entered under the OID + /// key. SetPrinterDataEx also adds the value name and data under the DS key. + /// + /// + /// In Windows 7 and later versions of Windows, print jobs that are sent to a print server are rendered on the client by default. + /// The configuration of client-side rendering for a printer can be read by setting pKeyName to "PrinterDriverData" and pValueName + /// to the setting value in the following table. + /// + /// + /// + /// Setting + /// Data type + /// Description + /// + /// + /// EMFDespoolingSetting + /// REG_DWORD + /// + /// A value of 0, or if this value is not present in the registry, enables the default client-side rendering of print jobs. A value + /// of 1 disables client-side rendering of print jobs. + /// + /// + /// + /// ForceClientSideRendering + /// REG_DWORD + /// + /// A value of 0, or if this value is not present in the registry, will cause the print jobs to be rendered on the client. If a + /// print job cannot be rendered on the client, it will be rendered on the server. If a print job cannot be rendered on the server, + /// it will fail. A value of 1 will render print jobs on the client. If a print job cannot be rendered on the client, it will fail. + /// + /// + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/getprinterdataex DWORD GetPrinterDataEx( _In_ HANDLE hPrinter, _In_ + // LPCTSTR pKeyName, _In_ LPCTSTR pValueName, _Out_ LPDWORD pType, _Out_ LPBYTE pData, _In_ DWORD nSize, _Out_ LPDWORD pcbNeeded ); + [DllImport(Lib.Winspool, SetLastError = false, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "5d9183a7-97cc-46de-848e-e37ce51396eb")] + public static extern Win32Error GetPrinterDataEx(HPRINTER hPrinter, string pKeyName, string pValueName, out REG_VALUE_TYPE pType, IntPtr pData, uint nSize, out uint pcbNeeded); + + /// + /// The GetPrinterDataEx function retrieves configuration data for the specified printer or print server. + /// GetPrinterDataEx can retrieve values that the SetPrinterData function stored. In addition, GetPrinterDataEx + /// can retrieve values that the SetPrinterDataEx function stored under a specified key. + /// + /// + /// A handle to the printer or print server for which the function retrieves configuration data. Use the OpenPrinter, + /// OpenPrinter2, or AddPrinter function to retrieve a printer handle. + /// + /// + /// + /// A pointer to a null-terminated string that specifies the key containing the value to be retrieved. Use the backslash ( \ ) + /// character as a delimiter to specify a path that has one or more subkeys. + /// + /// If hPrinter is a handle to a printer and pKeyName is NULL or an empty string, GetPrinterDataEx returns ERROR_INVALID_PARAMETER. + /// If hPrinter is a handle to a print server, pKeyName is ignored. + /// + /// + /// A pointer to a null-terminated string that identifies the data to retrieve. + /// For printers, this string specifies the name of a value under the pKeyName key. + /// For print servers, this string is one of the predefined strings listed in the following Remarks section. + /// + /// The requested valued. + /// + /// + /// GetPrinterDataEx retrieves printer-configuration data that was set by the SetPrinterDataEx and + /// SetPrinterData functions. + /// + /// + /// Calling GetPrinterDataEx with the pKeyName parameter set to "PrinterDriverData" is equivalent to calling the + /// GetPrinterData function. + /// + /// If hPrinter is a handle to a print server, pValueName can specify one of the following predefined values. + /// + /// + /// Value + /// Comments + /// + /// + /// SPLREG_ALLOW_USER_MANAGEFORMS + /// Windows XP with Service Pack 2 (SP2) and later Windows Server 2003 with Service Pack 1 (SP1) and later + /// + /// + /// SPLREG_ARCHITECTURE + /// + /// + /// + /// SPLREG_BEEP_ENABLED + /// + /// + /// + /// SPLREG_DEFAULT_SPOOL_DIRECTORY + /// + /// + /// + /// SPLREG_DNS_MACHINE_NAME + /// + /// + /// + /// SPLREG_DS_PRESENT + /// On successful return, pData contains 0x0001 if the machine is on a DS domain, 0 otherwise. + /// + /// + /// SPLREG_DS_PRESENT_FOR_USER + /// On successful return, pData contains 0x0001 if the user is logged onto a DS domain, 0 otherwise. + /// + /// + /// SPLREG_EVENT_LOG + /// + /// + /// + /// SPLREG_MAJOR_VERSION + /// + /// + /// + /// SPLREG_MINOR_VERSION + /// + /// + /// + /// SPLREG_NET_POPUP + /// Not supported in Windows Server 2003 and later + /// + /// + /// SPLREG_NET_POPUP_TO_COMPUTER + /// + /// On successful return, pData contains 1 if job notifications should be sent to the client computer, or 0 if job notifications are + /// to be sent to the user. Not supported in Windows Server 2003 and later + /// + /// + /// + /// SPLREG_OS_VERSION + /// Windows XP and later + /// + /// + /// SPLREG_OS_VERSIONEX + /// + /// + /// + /// SPLREG_PORT_THREAD_PRIORITY_DEFAULT + /// + /// + /// + /// SPLREG_PORT_THREAD_PRIORITY + /// + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_GROUPS + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_TIME_BEFORE_RECYCLE + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_MAX_OBJECTS_BEFORE_RECYCLE + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_IDLE_TIMEOUT + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_EXECUTION_POLICY + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_OVERRIDE_POLICY + /// Windows 7 and later + /// + /// + /// SPLREG_REMOTE_FAX + /// On successful return, pData contains 0x0001 if the FAX service supports remote clients, 0 otherwise. + /// + /// + /// SPLREG_RETRY_POPUP + /// + /// On successful return, pData contains 1 if server is set to retry pop-up windows for all jobs, or 0 if server does not retry + /// pop-up windows for all jobs. Not supported in Windows Server 2003 and later + /// + /// + /// + /// SPLREG_SCHEDULER_THREAD_PRIORITY + /// + /// + /// + /// SPLREG_SCHEDULER_THREAD_PRIORITY_DEFAULT + /// + /// + /// + /// SPLREG_WEBSHAREMGMT + /// Windows Server 2003 and later + /// + /// + /// The following values of pValueName indicate the pool printing behavior when an error occurs. + /// + /// + /// Value + /// Comments + /// + /// + /// SPLREG_RESTART_JOB_ON_POOL_ERROR + /// + /// The value of pData indicates the time, in seconds, when a job is restarted on another port after an error occurs. This setting + /// is used with SPLREG_RESTART_JOB_ON_POOL_ENABLED. + /// + /// + /// + /// SPLREG_RESTART_JOB_ON_POOL_ENABLED + /// A nonzero value in pData indicates that SPLREG_RESTART_JOB_ON_POOL_ERROR is enabled. + /// + /// + /// + /// The time specified in SPLREG_RESTART_JOB_ON_POOL_ERROR is a minimum time. The actual time can be longer, depending on the + /// following port monitor settings, which are registry values under this registry key: + /// + /// HKLM\SYSTEM\CurrentControlSet\Control\Print\Monitors\<MonitorName>\Ports + /// Call the RegQueryValueEx function to query these values. + /// + /// + /// Port monitor setting + /// Data type + /// Meaning + /// + /// + /// StatusUpdateEnabled + /// REG_DWORD + /// If a nonzero value, enables the port monitor to update the spooler with the port status. + /// + /// + /// StatusUpdateInterval + /// REG_DWORD + /// Specifies the interval, in minutes, when the port monitor updates the spooler with the port status. + /// + /// + /// + /// If pKeyName is one of the predefined Directory Service (DS) keys (see SetPrinter) and pValueName contains a comma (','), + /// then the portion of pValueName before the comma is the value name and the portion of pValueName to the right of the comma is the + /// DS Property OID. A subkey called OID is created and a new value that consists of the value name and OID is entered under the OID + /// key. SetPrinterDataEx also adds the value name and data under the DS key. + /// + /// + /// In Windows 7 and later versions of Windows, print jobs that are sent to a print server are rendered on the client by default. + /// The configuration of client-side rendering for a printer can be read by setting pKeyName to "PrinterDriverData" and pValueName + /// to the setting value in the following table. + /// + /// + /// + /// Setting + /// Data type + /// Description + /// + /// + /// EMFDespoolingSetting + /// REG_DWORD + /// + /// A value of 0, or if this value is not present in the registry, enables the default client-side rendering of print jobs. A value + /// of 1 disables client-side rendering of print jobs. + /// + /// + /// + /// ForceClientSideRendering + /// REG_DWORD + /// + /// A value of 0, or if this value is not present in the registry, will cause the print jobs to be rendered on the client. If a + /// print job cannot be rendered on the client, it will be rendered on the server. If a print job cannot be rendered on the server, + /// it will fail. A value of 1 will render print jobs on the client. If a print job cannot be rendered on the client, it will fail. + /// + /// + /// + /// + [PInvokeData("winspool.h", MSDNShortId = "5d9183a7-97cc-46de-848e-e37ce51396eb")] + public static object GetPrinterDataEx(HPRINTER hPrinter, string pKeyName, string pValueName) + { + GetPrinterDataEx(hPrinter, pKeyName, pValueName, out var type, default, 0, out var sz).ThrowUnless(Win32Error.ERROR_MORE_DATA); + using var mem = new SafeCoTaskMemHandle(sz); + GetPrinterDataEx(hPrinter, pKeyName, pValueName, out type, mem, mem.Size, out sz).ThrowIfFailed(); + return type.GetValue(mem, mem.Size); + } + + /// The GetPrintExecutionData retrieves the current print context. + /// A pointer to a variable that receives the address of the PRINT_EXECUTION_DATA structure. + /// + /// Returns TRUE if the function succeeds; otherwise FALSE. If the return value is FALSE, call + /// GetLastError to get the error status. + /// + /// + /// + /// Printer drivers should call GetProcAddress on the winspool.drv module to get the address of the + /// GetPrintExecutionData function because GetPrintExecutionData is not supported on Windows Vista or earlier versions + /// of Windows. + /// + /// GetPrintExecutionData only fails if the value of pData is NULL. + /// + /// The value of the clientAppPID member of PRINT_EXECUTION_DATA is only meaningful if the value of context is + /// PRINT_EXECUTION_CONTEXT_WOW64. If the value of context is not PRINT_EXECUTION_CONTEXT_WOW64, the value of + /// clientAppPID is 0. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/getprintexecutiondata BOOL WINAPI GetPrintExecutionData( _Out_ + // PRINT_EXECUTION_DATA *pData ); + [DllImport(Lib.Winspool, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winspool.h", MSDNShortId = "bb9506aa-a0da-46bc-a86a-84a79587cd50")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool GetPrintExecutionData(out PRINT_EXECUTION_DATA pData); + + /// + /// The GetSpoolFileHandle function retrieves a handle for the spool file associated with the job currently submitted by the application. + /// + /// + /// A handle to the printer to which the job was submitted. This should be the same handle that was used to submit the job. (Use the + /// OpenPrinter or AddPrinter function to retrieve a printer handle.) + /// + /// + /// If the function succeeds, it returns a handle to the spool file. + /// If the function fails, it returns INVALID_HANDLE_VALUE. + /// + /// + /// + /// With the handle to the spool file, your application can write to the spool file with calls to WriteFile followed by CommitSpoolData. + /// + /// + /// Your application must not call ClosePrinter on hPrinter until after it has accessed the spool file for the last time. + /// Then it should call CloseSpoolFileHandle followed by ClosePrinter. Attempts to access the spool file handle after + /// the original hPrinter has been closed will fail even if the file handle itself has not been closed. CloseSpoolFileHandle + /// will itself fail if ClosePrinter is called first. + /// + /// This function will fail if it is called before the print job has finished spooling. + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/getspoolfilehandle HANDLE GetSpoolFileHandle( _In_ HANDLE hPrinter ); + [PInvokeData("winspool.h", MSDNShortId = "df6f28b3-66a6-4fb7-bdde-40cd7d934c5f")] + public static SafeHSPOOLFILE GetSpoolFileHandle(HPRINTER hPrinter) => new SafeHSPOOLFILE(hPrinter, InternalGetSpoolFileHandle(hPrinter), true); + + /// The IsValidDevmode function verifies that the contents of a DEVMODE structure are valid. + /// A pointer to the DEVMODE to validate. + /// The size in bytes of the input byte buffer. + /// + /// + /// TRUE, if the DEVMODE is structurally valid. If minor errors are found the function will fix them and return TRUE. + /// + /// + /// FALSE, if the DEVMODE has one or more significant structural problems. For example, its dmSize member is + /// misaligned or specifies a buffer that is too small. Also, FALSE if pDevmode is NULL. + /// + /// + /// + /// No private printer driver fields of the DEVMODE are checked, only the public fields. + /// + /// Callers should use dmSize+ dmDriverExtra for DevmodeSize only if they can guarantee that the input buffer + /// size is at least that big. Since the DEVMODE is generally untrusted data, the values that are in the input buffer at the + /// dmSize and dmDriverExtra offsets are also untrusted. + /// + /// This function is executable in Least-Privileged User Account (LUA) context. + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/isvaliddevmode BOOL IsValidDevmode( _In_ PDEVMODE pDevmode, size_t + // DevmodeSize ); + [DllImport(Lib.Winspool, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "8b4e32cc-5eeb-4a0d-a1b7-f6edb99ed8d8")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool IsValidDevmode(in DEVMODE pDevmode, SizeT DevmodeSize); + + /// + /// The OpenPrinter function retrieves a handle to the specified printer or print server or other types of handles in the + /// print subsystem. + /// + /// + /// + /// A pointer to a null-terminated string that specifies the name of the printer or print server, the printer object, the + /// XcvMonitor, or the XcvPort. + /// + /// + /// For a printer object use: PrinterName, Job xxxx. For an XcvMonitor, use: ServerName, XcvMonitor MonitorName. For an XcvPort, + /// use: ServerName, XcvPort PortName. + /// + /// If NULL, it indicates the local printer server. + /// + /// + /// A pointer to a variable that receives a handle (not thread safe) to the open printer or print server object. + /// + /// The phPrinter parameter can return an Xcv handle for use with the XcvData function. For more information about XcvData, see the DDK. + /// + /// + /// A pointer to a PRINTER_DEFAULTS structure. This value can be NULL. + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + /// + /// Do not call this method in DllMain. + /// + /// The handle pointed to by phPrinter is not thread safe. If callers need to use it concurrently on multiple threads, they must + /// provide custom synchronization access to the printer handle using the Synchronization Functions. To avoid writing custom code + /// the application can open a printer handle on each thread, as needed. + /// + /// + /// The pDefault parameter enables you to specify the data type and device mode values that are used for printing documents + /// submitted by the StartDocPrinter function. However, you can override these values by using the SetJob function + /// after a document has been started. + /// + /// + /// The DEVMODE settings defined in the PRINTER_DEFAULTS structure of the pDefault parameter are not used when the + /// value of the pDatatype member of the DOC_INFO_1 structure that was passed in the pDocInfo parameter of the + /// StartDocPrinter call is "RAW". When a high-level document (such as an Adobe PDF or Microsoft Word file) or other printer + /// data (such PCL, PS, or HPGL) is sent directly to a printer with pDatatype set to "RAW", the document must fully describe the + /// DEVMODE-style print job settings in the language understood by the hardware. + /// + /// + /// You can call the OpenPrinter function to open a handle to a print server or to determine the access rights that a client + /// has to a print server. To do so, specify the name of the print server in the pPrinterName parameter, set the pDatatype + /// and pDevMode members of the PRINTER_DEFAULTS structure to NULL, and set the DesiredAccess member to + /// specify a server access mask value such as SERVER_ALL_ACCESS. When you finish with the handle, pass it to the + /// ClosePrinter function to close it. + /// + /// + /// Use the DesiredAccess member of the PRINTER_DEFAULTS structure to specify the access rights that you need to the + /// printer. The access rights can be one of the following. (If pDefault is NULL, then the access rights are PRINTER_ACCESS_USE.) + /// + /// + /// + /// Desired Access value + /// Meaning + /// + /// + /// PRINTER_ACCESS_ADMINISTER + /// To perform administrative tasks, such as those provided by SetPrinter. + /// + /// + /// PRINTER_ACCESS_USE + /// To perform basic printing operations. + /// + /// + /// PRINTER_ALL_ACCESS + /// To perform all administrative tasks and basic printing operations except for SYNCHRONIZE (see Standard Access Rights. + /// + /// + /// PRINTER_ACCESS_MANAGE_LIMITED + /// + /// To perform administrative tasks, such as those provided by SetPrinter and SetPrinterData. This value is available starting from + /// Windows 8.1. + /// + /// + /// + /// generic security values, such as WRITE_DAC + /// To allow specific control access rights. See Standard Access Rights. + /// + /// + /// + /// If a user does not have permission to open a specified printer or print server with the desired access, the OpenPrinter + /// call will fail with a return value of zero and GetLastError will return the value ERROR_ACCESS_DENIED. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/openprinter BOOL OpenPrinter( _In_ LPTSTR pPrinterName, _Out_ LPHANDLE + // phPrinter, _In_ LPPRINTER_DEFAULTS pDefault ); + [DllImport(Lib.Winspool, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "96763220-d851-46f0-8be8-403f3356edb9")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool OpenPrinter(string pPrinterName, out SafeHPRINTER phPrinter, in PRINTER_DEFAULTS pDefault); + + /// + /// The OpenPrinter function retrieves a handle to the specified printer or print server or other types of handles in the + /// print subsystem. + /// + /// + /// + /// A pointer to a null-terminated string that specifies the name of the printer or print server, the printer object, the + /// XcvMonitor, or the XcvPort. + /// + /// + /// For a printer object use: PrinterName, Job xxxx. For an XcvMonitor, use: ServerName, XcvMonitor MonitorName. For an XcvPort, + /// use: ServerName, XcvPort PortName. + /// + /// If NULL, it indicates the local printer server. + /// + /// + /// A pointer to a variable that receives a handle (not thread safe) to the open printer or print server object. + /// + /// The phPrinter parameter can return an Xcv handle for use with the XcvData function. For more information about XcvData, see the DDK. + /// + /// + /// A pointer to a PRINTER_DEFAULTS structure. This value can be NULL. + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + /// + /// Do not call this method in DllMain. + /// + /// The handle pointed to by phPrinter is not thread safe. If callers need to use it concurrently on multiple threads, they must + /// provide custom synchronization access to the printer handle using the Synchronization Functions. To avoid writing custom code + /// the application can open a printer handle on each thread, as needed. + /// + /// + /// The pDefault parameter enables you to specify the data type and device mode values that are used for printing documents + /// submitted by the StartDocPrinter function. However, you can override these values by using the SetJob function + /// after a document has been started. + /// + /// + /// The DEVMODE settings defined in the PRINTER_DEFAULTS structure of the pDefault parameter are not used when the + /// value of the pDatatype member of the DOC_INFO_1 structure that was passed in the pDocInfo parameter of the + /// StartDocPrinter call is "RAW". When a high-level document (such as an Adobe PDF or Microsoft Word file) or other printer + /// data (such PCL, PS, or HPGL) is sent directly to a printer with pDatatype set to "RAW", the document must fully describe the + /// DEVMODE-style print job settings in the language understood by the hardware. + /// + /// + /// You can call the OpenPrinter function to open a handle to a print server or to determine the access rights that a client + /// has to a print server. To do so, specify the name of the print server in the pPrinterName parameter, set the pDatatype + /// and pDevMode members of the PRINTER_DEFAULTS structure to NULL, and set the DesiredAccess member to + /// specify a server access mask value such as SERVER_ALL_ACCESS. When you finish with the handle, pass it to the + /// ClosePrinter function to close it. + /// + /// + /// Use the DesiredAccess member of the PRINTER_DEFAULTS structure to specify the access rights that you need to the + /// printer. The access rights can be one of the following. (If pDefault is NULL, then the access rights are PRINTER_ACCESS_USE.) + /// + /// + /// + /// Desired Access value + /// Meaning + /// + /// + /// PRINTER_ACCESS_ADMINISTER + /// To perform administrative tasks, such as those provided by SetPrinter. + /// + /// + /// PRINTER_ACCESS_USE + /// To perform basic printing operations. + /// + /// + /// PRINTER_ALL_ACCESS + /// To perform all administrative tasks and basic printing operations except for SYNCHRONIZE (see Standard Access Rights. + /// + /// + /// PRINTER_ACCESS_MANAGE_LIMITED + /// + /// To perform administrative tasks, such as those provided by SetPrinter and SetPrinterData. This value is available starting from + /// Windows 8.1. + /// + /// + /// + /// generic security values, such as WRITE_DAC + /// To allow specific control access rights. See Standard Access Rights. + /// + /// + /// + /// If a user does not have permission to open a specified printer or print server with the desired access, the OpenPrinter + /// call will fail with a return value of zero and GetLastError will return the value ERROR_ACCESS_DENIED. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/openprinter BOOL OpenPrinter( _In_ LPTSTR pPrinterName, _Out_ LPHANDLE + // phPrinter, _In_ LPPRINTER_DEFAULTS pDefault ); + [DllImport(Lib.Winspool, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "96763220-d851-46f0-8be8-403f3356edb9")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool OpenPrinter(string pPrinterName, out SafeHPRINTER phPrinter, IntPtr pDefault = default); + + /// + /// Retrieves a handle to the specified printer, print server, or other types of handles in the print subsystem, while setting some + /// of the printer options. + /// + /// + /// + /// A pointer to a constant null-terminated string that specifies the name of the printer or print server, the printer object, the + /// XcvMonitor, or the XcvPort. + /// + /// + /// For a printer object, use: PrinterName,Job xxxx. For an XcvMonitor, use: ServerName,XcvMonitor MonitorName. For an XcvPort, use: + /// ServerName,XcvPort PortName. + /// + /// Windows Vista: If NULL, it indicates the local print server. + /// + /// A pointer to a variable that receives a handle to the open printer or print server object. + /// A pointer to a PRINTER_DEFAULTS structure. This value can be NULL. + /// A pointer to a PRINTER_OPTIONS structure. This value can be NULL. + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. For extended error information, call GetLastError. + /// + /// + /// Do not call this method in DllMain. + /// The ANSI version of this function is not implemented and returns ERROR_NOT_SUPPORTED. + /// + /// The pDefault parameter enables you to specify the data type and device mode values that are used for printing documents + /// submitted by the StartDocPrinter function. However, you can override these values by using the SetJob function + /// after a document has been started. + /// + /// + /// You can call the OpenPrinter2 function to open a handle to a print server or to determine client access rights to a print + /// server. To do this, specify the name of the print server in the pPrinterName parameter, set the pDatatype and + /// pDevMode members of the PRINTER_DEFAULTS structure to NULL, and set the DesiredAccess member to + /// specify a server access mask value such as SERVER_ALL_ACCESS. When you are finished with the handle, pass it to the + /// ClosePrinter function to close it. + /// + /// + /// Use the DesiredAccess member of the PRINTER_DEFAULTS structure to specify the necessary access rights. The access + /// rights can be one of the following. + /// + /// + /// + /// Desired Access value + /// Meaning + /// + /// + /// PRINTER_ACCESS_ADMINISTER + /// To perform administrative tasks, such as those provided by SetPrinter. + /// + /// + /// PRINTER_ACCESS_USE + /// To perform basic printing operations. + /// + /// + /// PRINTER_ALL_ACCESS + /// To perform all administrative tasks and basic printing operations except SYNCHRONIZE. See Standard Access Rights. + /// + /// + /// PRINTER_ACCESS_MANAGE_LIMITED + /// + /// To perform administrative tasks, such as those provided by SetPrinter and SetPrinterData. This value is available starting from + /// Windows 8.1. + /// + /// + /// + /// generic security values, such as WRITE_DAC + /// To allow specific control access rights. See Standard Access Rights. + /// + /// + /// + /// If a user does not have permission to open a specified printer or print server with the desired access, the OpenPrinter2 + /// call will fail, and GetLastError will return the value ERROR_ACCESS_DENIED. + /// + /// + /// When pPrinterName is a local printer, then OpenPrinter2 ignores all values of the dwFlags that the + /// PRINTER_OPTIONS structure pointed to using pOptions, except PRINTER_OPTION_CLIENT_CHANGE. If the latter is passed, then + /// OpenPrinter2 will return ERROR_ACCESS_DENIED. Accordingly, when opening a local printer, OpenPrinter2 provides no + /// advantage over OpenPrinter. + /// + /// + /// Windows Vista: The printer data returned by OpenPrinter2 is retrieved from a local cache unless the + /// PRINTER_OPTION_NO_CACHE flag is set in the dwFlags field of the PRINTER_OPTIONS structure referenced by pOptions. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/openprinter2 BOOL OpenPrinter2( _In_ LPCTSTR pPrinterName, _Out_ + // LPHANDLE phPrinter, _In_ LPPRINTER_DEFAULTS pDefault, _In_ PPRINTER_OPTIONS pOptions ); + [DllImport(Lib.Winspool, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "e2370ae4-4475-4ccc-a6f9-3d33d1370054")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool OpenPrinter2(string pPrinterName, out SafeHPRINTER phPrinter, in PRINTER_DEFAULTS pDefault, in PRINTER_OPTIONS pOptions); + + /// + /// Retrieves a handle to the specified printer, print server, or other types of handles in the print subsystem, while setting some + /// of the printer options. + /// + /// + /// + /// A pointer to a constant null-terminated string that specifies the name of the printer or print server, the printer object, the + /// XcvMonitor, or the XcvPort. + /// + /// + /// For a printer object, use: PrinterName,Job xxxx. For an XcvMonitor, use: ServerName,XcvMonitor MonitorName. For an XcvPort, use: + /// ServerName,XcvPort PortName. + /// + /// Windows Vista: If NULL, it indicates the local print server. + /// + /// A pointer to a variable that receives a handle to the open printer or print server object. + /// A pointer to a PRINTER_DEFAULTS structure. This value can be NULL. + /// A pointer to a PRINTER_OPTIONS structure. This value can be NULL. + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. For extended error information, call GetLastError. + /// + /// + /// Do not call this method in DllMain. + /// The ANSI version of this function is not implemented and returns ERROR_NOT_SUPPORTED. + /// + /// The pDefault parameter enables you to specify the data type and device mode values that are used for printing documents + /// submitted by the StartDocPrinter function. However, you can override these values by using the SetJob function + /// after a document has been started. + /// + /// + /// You can call the OpenPrinter2 function to open a handle to a print server or to determine client access rights to a print + /// server. To do this, specify the name of the print server in the pPrinterName parameter, set the pDatatype and + /// pDevMode members of the PRINTER_DEFAULTS structure to NULL, and set the DesiredAccess member to + /// specify a server access mask value such as SERVER_ALL_ACCESS. When you are finished with the handle, pass it to the + /// ClosePrinter function to close it. + /// + /// + /// Use the DesiredAccess member of the PRINTER_DEFAULTS structure to specify the necessary access rights. The access + /// rights can be one of the following. + /// + /// + /// + /// Desired Access value + /// Meaning + /// + /// + /// PRINTER_ACCESS_ADMINISTER + /// To perform administrative tasks, such as those provided by SetPrinter. + /// + /// + /// PRINTER_ACCESS_USE + /// To perform basic printing operations. + /// + /// + /// PRINTER_ALL_ACCESS + /// To perform all administrative tasks and basic printing operations except SYNCHRONIZE. See Standard Access Rights. + /// + /// + /// PRINTER_ACCESS_MANAGE_LIMITED + /// + /// To perform administrative tasks, such as those provided by SetPrinter and SetPrinterData. This value is available starting from + /// Windows 8.1. + /// + /// + /// + /// generic security values, such as WRITE_DAC + /// To allow specific control access rights. See Standard Access Rights. + /// + /// + /// + /// If a user does not have permission to open a specified printer or print server with the desired access, the OpenPrinter2 + /// call will fail, and GetLastError will return the value ERROR_ACCESS_DENIED. + /// + /// + /// When pPrinterName is a local printer, then OpenPrinter2 ignores all values of the dwFlags that the + /// PRINTER_OPTIONS structure pointed to using pOptions, except PRINTER_OPTION_CLIENT_CHANGE. If the latter is passed, then + /// OpenPrinter2 will return ERROR_ACCESS_DENIED. Accordingly, when opening a local printer, OpenPrinter2 provides no + /// advantage over OpenPrinter. + /// + /// + /// Windows Vista: The printer data returned by OpenPrinter2 is retrieved from a local cache unless the + /// PRINTER_OPTION_NO_CACHE flag is set in the dwFlags field of the PRINTER_OPTIONS structure referenced by pOptions. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/openprinter2 BOOL OpenPrinter2( _In_ LPCTSTR pPrinterName, _Out_ + // LPHANDLE phPrinter, _In_ LPPRINTER_DEFAULTS pDefault, _In_ PPRINTER_OPTIONS pOptions ); + [DllImport(Lib.Winspool, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "e2370ae4-4475-4ccc-a6f9-3d33d1370054")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool OpenPrinter2(string pPrinterName, out SafeHPRINTER phPrinter, [Optional] IntPtr pDefault, [Optional] IntPtr pOptions); + + /// The PrinterProperties function displays a printer-properties property sheet for the specified printer. + /// A handle to the parent window of the property sheet. + /// + /// A handle to a printer object. Use the OpenPrinter or AddPrinter function to retrieve a printer handle. + /// + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/printerproperties BOOL PrinterProperties( _In_ HWND hWnd, _In_ HANDLE + // hPrinter ); + [DllImport(Lib.Winspool, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winspool.h", MSDNShortId = "1d4c961b-178b-47af-b983-5b7327919f93")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool PrinterProperties(HWND hWnd, HPRINTER hPrinter); + + /// The ReadPrinter function retrieves data from the specified printer. + /// + /// A handle to the printer object for which to retrieve data. Use the OpenPrinter function to retrieve a printer object + /// handle. Use the format: Printername, Job xxxx. + /// + /// A pointer to a buffer that receives the printer data. + /// The size, in bytes, of the buffer to which pBuf points. + /// + /// A pointer to a variable that receives the number of bytes of data copied into the array to which pBuf points. + /// + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + /// ReadPrinter returns an error if the device or the printer is not bidirectional. + // https://docs.microsoft.com/en-us/windows/win32/printdocs/readprinter BOOL ReadPrinter( _In_ HANDLE hPrinter, _Out_ LPVOID pBuf, + // _In_ DWORD cbBuf, _Out_ LPDWORD pNoBytesRead ); + [DllImport(Lib.Winspool, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winspool.h", MSDNShortId = "d7c3f186-c53e-424b-89bf-6742babb998f")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool ReadPrinter(HPRINTER hPrinter, IntPtr pBuf, uint cbBuf, out uint pNoBytesRead); + + /// + /// Reports to the Print Spooler service whether an XPS print job is in the spooling or the rendering phase and what part of the + /// processing is currently underway. + /// + /// + /// A printer handle for which the function is to retrieve information. Use the OpenPrinter or AddPrinter function to + /// retrieve a printer handle. + /// + /// + /// Identifies the print job for which to retrieve data. Use the AddJob function or StartDoc function to get a print + /// job identifier. + /// + /// Specifies whether the job is in the spooling phase or the rendering phase. + /// + /// Specifies what part of the processing is currently underway. This value refers to events in either the spooling or rendering + /// phase depending on the value of jobOperation. + /// + /// + /// If the operation succeeds, the return value is S_OK, otherwise the HRESULT will contain an error code. + /// For more information about COM error codes, see Error Handling. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/reportjobprocessingprogress HRESULT ReportJobProcessingProgress( _In_ + // HANDLE printerHandle, _In_ ULONG jobId, EPrintXPSJobOperation jobOperation, EPrintXPSJobProgress jobProgress ); + [DllImport(Lib.Winspool, SetLastError = false, ExactSpelling = true)] + [PInvokeData("winspool.h", MSDNShortId = "66f7483d-be98-410d-b0c7-430743397de2")] + public static extern HRESULT ReportJobProcessingProgress(HPRINTER printerHandle, uint jobId, EPrintXPSJobOperation jobOperation, EPrintXPSJobProgress jobProgress); + + /// + /// The ResetPrinter function specifies the data type and device mode values to be used for printing documents submitted by + /// the StartDocPrinter function. These values can be overridden by using the SetJob function after document printing + /// has started. + /// + /// + /// Handle to the printer. Use the OpenPrinter or AddPrinter function to retrieve a printer handle. + /// + /// + /// Pointer to a PRINTER_DEFAULTS structure. + /// + /// The ResetPrinter function ignores the DesiredAccess member of the PRINTER_DEFAULTS structure. Set that + /// member to zero. + /// + /// + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/resetprinter BOOL ResetPrinter( _In_ HANDLE hPrinter, _In_ + // LPPRINTER_DEFAULTS pDefault ); + [DllImport(Lib.Winspool, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "9efc6629-dbb7-4320-90b9-07c66f0add47")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool ResetPrinter(HPRINTER hPrinter, in PRINTER_DEFAULTS pDefault); + + /// The ScheduleJob function requests that the print spooler schedule a specified print job for printing. + /// + /// + /// A handle to the printer for the print job. This must be a local printer that is configured as a spooled printer. If hPrinter is + /// a handle to a remote printer connection, or if the printer is configured for direct printing, the ScheduleJob function + /// fails. Use the OpenPrinter or AddPrinter function to retrieve a printer handle. + /// + /// hPrinter must be the same printer handle specified in the call to AddJob that obtained the dwJobID print job identifier. + /// + /// The print job to be scheduled. You obtain this print job identifier by calling the AddJob function. + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + /// + /// + /// You must successfully call the AddJob function before calling the ScheduleJob function. AddJob obtains the + /// print job identifier that you pass to ScheduleJob as dwJobID. Both calls must use the same value for hPrinter. + /// + /// + /// The ScheduleJob function checks for a valid spool file. If there is an invalid spool file, or if it is empty, + /// ScheduleJob deletes both the spool file and the corresponding print job entry in the print spooler. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/schedulejob BOOL ScheduleJob( _In_ HANDLE hPrinter, _In_ DWORD dwJobID ); + [DllImport(Lib.Winspool, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winspool.h", MSDNShortId = "a103a29c-be4d-491e-9b04-84571fe969a5")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool ScheduleJob(HPRINTER hPrinter, uint dwJobID); + + /// + /// The SetDefaultPrinter function sets the printer name of the default printer for the current user on the local computer. + /// + /// + /// + /// A pointer to a null-terminated string containing the default printer name. For a remote printer connection, the name format is + /// **\\ server\**printername. For a local printer, the name format is printername. + /// + /// + /// If this parameter is NULL or an empty string, that is, "", SetDefaultPrinter will select a default printer from + /// one of the installed printers. If a default printer already exists, calling SetDefaultPrinter with a NULL or an + /// empty string in this parameter might change the default printer. + /// + /// + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + /// + /// When using this method, you must specify a valid printer, driver, and port. If they are invalid, the APIs do not fail but the + /// result is not defined. This could cause other programs to set the printer back to the previous valid printer. You can use + /// EnumPrinters to retrieve the printer name, driver name, and port name of all available printers. + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/setdefaultprinter BOOL SetDefaultPrinter( _In_ LPCTSTR pszPrinter ); + [DllImport(Lib.Winspool, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "55eec548-577f-422b-80e3-8b23aa4d2159")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool SetDefaultPrinter(string pszPrinter); + + /// The SetForm function sets the form information for the specified printer. + /// + /// A handle to the printer for which the form information is set. Use the OpenPrinter or AddPrinter function to + /// retrieve a printer handle. + /// + /// + /// A pointer to a null-terminated string that specifies the form name for which the form information is set. + /// + /// The version of the structure to which pForm points. This value must be 1 or 2. + /// A pointer to a FORM_INFO_1 or FORM_INFO_2 structure. + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + /// + /// + /// SetForm can be called multiple times for an existing FORM_INFO_2, each call adding additional pairs of + /// pDisplayName and wLangId values. All languages versions of the form will get the Size and + /// ImageableArea values of the FORM_INFO_2 in the most recent call to SetForm. + /// + /// If the caller is remote and the Level is 2, the StringType value of the FORM_INFO_2 cannot be STRING_MUIDLL. + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/setform BOOL SetForm( _In_ HANDLE hPrinter, _In_ LPTSTR pFormName, _In_ + // DWORD Level, _In_ LPTSTR pForm ); + [DllImport(Lib.Winspool, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "05d5d495-952c-4a1d-8694-1004d0c2bcf6")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool SetForm(HPRINTER hPrinter, string pFormName, uint Level, IntPtr pForm); + + /// The SetForm function sets the form information for the specified printer. + /// The type of the value being set. + /// + /// A handle to the printer for which the form information is set. Use the OpenPrinter or AddPrinter function to + /// retrieve a printer handle. + /// + /// A pointer to a string that specifies the form name for which the form information is set. + /// A FORM_INFO_1 or FORM_INFO_2 structure. + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + /// + /// + /// + /// SetForm can be called multiple times for an existing FORM_INFO_2, each call adding additional pairs of + /// pDisplayName and wLangId values. All languages versions of the form will get the Size and + /// ImageableArea values of the FORM_INFO_2 in the most recent call to SetForm. + /// + /// If the caller is remote and the Level is 2, the StringType value of the FORM_INFO_2 cannot be STRING_MUIDLL. + /// + [PInvokeData("winspool.h", MSDNShortId = "05d5d495-952c-4a1d-8694-1004d0c2bcf6")] + public static bool SetForm(HPRINTER hPrinter, string pFormName, in T pForm) where T : struct + { + if (!TryGetLevel("FORM_INFO_", out var lvl)) + throw new ArgumentException($"{nameof(SetForm)} cannot process a structure of type {typeof(T).Name}."); + using var mem = SafeCoTaskMemHandle.CreateFromStructure(pForm); + return SetForm(hPrinter, pFormName, lvl, mem); + } + + /// + /// + /// The SetJob function pauses, resumes, cancels, or restarts a print job on a specified printer. You can also use the + /// SetJob function to set print job parameters, such as the print job priority and the document name. + /// + /// + /// You can use the SetJob function to give a command to a print job, or to set print job parameters, or to do both in the + /// same call. The value of the Command parameter does not affect how the function uses the Level and pJob parameters. Also, you can + /// use SetJob with JOB_INFO_3 to link together a set of print jobs. See Remarks for more information. + /// + /// + /// + /// A handle to the printer object of interest. Use the OpenPrinter, OpenPrinter2, or AddPrinter function to + /// retrieve a printer handle. + /// + /// + /// + /// Identifier that specifies the print job. You obtain a print job identifier by calling the AddJob function or the + /// StartDoc function. + /// + /// + /// If the Level parameter is set to 3, the JobId parameter must match the JobId member of the JOB_INFO_3 structure + /// pointed to by pJob + /// + /// + /// + /// The type of job information structure pointed to by the pJob parameter. + /// + /// All versions of Windows: You can set the Level parameter to 0, 1, or 2. When you set Level to 0, pJob should be + /// NULL. Use these values when you are not setting any print job parameters. + /// + /// You can also set the Level parameter to 3. + /// Starting with Windows Vista: You can also set the Level parameter to 4. + /// + /// + /// A pointer to a structure that sets the print job parameters. + /// All versions of Windows: pJob can point to a JOB_INFO_1 or JOB_INFO_2 structure. + /// + /// pJob can also point to a JOB_INFO_3 structure. You must have JOB_ACCESS_ADMINISTER access permission for the jobs + /// specified by the JobId and NextJobId members of the JOB_INFO_3 structure. + /// + /// Starting with Windows Vista: pJob can also point to a JOB_INFO_4 structure. + /// If the Level parameter is 0, pJob should be NULL. + /// + /// + /// The print job operation to perform. This parameter can be one of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// JOB_CONTROL_CANCEL + /// Do not use. To delete a print job, use JOB_CONTROL_DELETE. + /// + /// + /// JOB_CONTROL_PAUSE + /// Pause the print job. + /// + /// + /// JOB_CONTROL_RESTART + /// Restart the print job. A job can only be restarted if it was printing. + /// + /// + /// JOB_CONTROL_RESUME + /// Resume a paused print job. + /// + /// + /// JOB_CONTROL_DELETE + /// Delete the print job. + /// + /// + /// JOB_CONTROL_SENT_TO_PRINTER + /// Used by port monitors to end the print job. + /// + /// + /// JOB_CONTROL_LAST_PAGE_EJECTED + /// Used by language monitors to end the print job. + /// + /// + /// JOB_CONTROL_RETAIN + /// Windows Vista and later: Keep the job in the queue after it prints. + /// + /// + /// JOB_CONTROL_RELEASE + /// Windows Vista and later: Release the print job. + /// + /// + /// + /// You can use the same call to the SetJob function to set print job parameters and to give a command to a print job. Thus, + /// Command does not need to be 0 if you are setting print job parameters, although it can be. + /// + /// + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + /// + /// + /// You can use the SetJob function to set various print job parameters by supplying a pointer to a JOB_INFO_1, + /// JOB_INFO_2, JOB_INFO_3, or JOB_INFO_4 structure that contains the necessary data. + /// + /// + /// To remove or delete all of the print jobs for a particular printer, call the SetPrinter function with its Command + /// parameter set to PRINTER_CONTROL_PURGE. + /// + /// + /// The following members of a JOB_INFO_1, JOB_INFO_2, or JOB_INFO_4 structure are ignored on a call to + /// SetJob: JobId, pPrinterName, pMachineName, pUserName, pDrivername, Size, + /// Submitted, Time, and TotalPages. + /// + /// + /// You must have PRINTER_ACCESS_ADMINISTER access permission for a printer in order to change a print job's position in the + /// print queue. + /// + /// + /// If you do not want to set a print job's position in the print queue, you should set the Position member of the + /// JOB_INFO_1, JOB_INFO_2, or JOB_INFO_4 structure to JOB_POSITION_UNSPECIFIED. + /// + /// + /// Use the SetJob function with the JOB_INFO_3 structure to link together a set of print jobs (also known as a + /// chain). This is useful in situations where a single document consists of several parts that you want to render separately. To + /// print jobs A, B, C, and D in order, call SetJob with JOB_INFO_4 to link A to B, B to C, and C to D. + /// + /// If you link print jobs, note the following: + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/setjob BOOL SetJob( _In_ HANDLE hPrinter, _In_ DWORD JobId, _In_ DWORD + // Level, _In_ LPBYTE pJob, _In_ DWORD Command ); + [DllImport(Lib.Winspool, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "21947c69-c517-4962-8eb7-b45ed4211d9a")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool SetJob(HPRINTER hPrinter, uint JobId, uint Level, IntPtr pJob, JOB_CONTROL Command = 0); + + /// + /// + /// The SetJob function pauses, resumes, cancels, or restarts a print job on a specified printer. You can also use the + /// SetJob function to set print job parameters, such as the print job priority and the document name. + /// + /// + /// You can use the SetJob function to give a command to a print job. + /// + /// + /// A handle to the printer object of interest. Use the OpenPrinter, OpenPrinter2, or AddPrinter function to + /// retrieve a printer handle. + /// Identifier that specifies the print job. You obtain a print job identifier by calling the AddJob function or the + /// StartDoc function. + /// The print job operation to perform. This parameter can be one of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// JOB_CONTROL_CANCEL + /// Do not use. To delete a print job, use JOB_CONTROL_DELETE. + /// + /// + /// JOB_CONTROL_PAUSE + /// Pause the print job. + /// + /// + /// JOB_CONTROL_RESTART + /// Restart the print job. A job can only be restarted if it was printing. + /// + /// + /// JOB_CONTROL_RESUME + /// Resume a paused print job. + /// + /// + /// JOB_CONTROL_DELETE + /// Delete the print job. + /// + /// + /// JOB_CONTROL_SENT_TO_PRINTER + /// Used by port monitors to end the print job. + /// + /// + /// JOB_CONTROL_LAST_PAGE_EJECTED + /// Used by language monitors to end the print job. + /// + /// + /// JOB_CONTROL_RETAIN + /// Windows Vista and later: Keep the job in the queue after it prints. + /// + /// + /// JOB_CONTROL_RELEASE + /// Windows Vista and later: Release the print job. + /// + /// + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + /// + /// To remove or delete all of the print jobs for a particular printer, call the SetPrinter function with its Command + /// parameter set to PRINTER_CONTROL_PURGE. + /// + [PInvokeData("winspool.h", MSDNShortId = "21947c69-c517-4962-8eb7-b45ed4211d9a")] + public static bool SetJob(HPRINTER hPrinter, uint JobId, JOB_CONTROL Command) => + SetJob(hPrinter, JobId, 0, default, Command); + + /// + /// + /// The SetJob function pauses, resumes, cancels, or restarts a print job on a specified printer. You can also use the + /// SetJob function to set print job parameters, such as the print job priority and the document name. + /// + /// + /// You can use the SetJob function to give a command to a print job, or to set print job parameters, or to do both in the + /// same call. The value of the Command parameter does not affect how the function uses the Level and pJob parameters. Also, you can + /// use SetJob with JOB_INFO_3 to link together a set of print jobs. See Remarks for more information. + /// + /// + /// The type of the value being set. + /// + /// A handle to the printer object of interest. Use the OpenPrinter, OpenPrinter2, or AddPrinter function to + /// retrieve a printer handle. + /// + /// + /// + /// Identifier that specifies the print job. You obtain a print job identifier by calling the AddJob function or the + /// StartDoc function. + /// + /// + /// If the Level parameter is set to 3, the JobId parameter must match the JobId member of the JOB_INFO_3 structure + /// pointed to by pJob + /// + /// + /// + /// A pointer to a structure that sets the print job parameters. + /// All versions of Windows: pJob can point to a JOB_INFO_1 or JOB_INFO_2 structure. + /// + /// pJob can also point to a JOB_INFO_3 structure. You must have JOB_ACCESS_ADMINISTER access permission for the jobs + /// specified by the JobId and NextJobId members of the JOB_INFO_3 structure. + /// + /// Starting with Windows Vista: pJob can also point to a JOB_INFO_4 structure. + /// If the Level parameter is 0, pJob should be NULL. + /// + /// + /// The print job operation to perform. This parameter can be one of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// JOB_CONTROL_CANCEL + /// Do not use. To delete a print job, use JOB_CONTROL_DELETE. + /// + /// + /// JOB_CONTROL_PAUSE + /// Pause the print job. + /// + /// + /// JOB_CONTROL_RESTART + /// Restart the print job. A job can only be restarted if it was printing. + /// + /// + /// JOB_CONTROL_RESUME + /// Resume a paused print job. + /// + /// + /// JOB_CONTROL_DELETE + /// Delete the print job. + /// + /// + /// JOB_CONTROL_SENT_TO_PRINTER + /// Used by port monitors to end the print job. + /// + /// + /// JOB_CONTROL_LAST_PAGE_EJECTED + /// Used by language monitors to end the print job. + /// + /// + /// JOB_CONTROL_RETAIN + /// Windows Vista and later: Keep the job in the queue after it prints. + /// + /// + /// JOB_CONTROL_RELEASE + /// Windows Vista and later: Release the print job. + /// + /// + /// + /// You can use the same call to the SetJob function to set print job parameters and to give a command to a print job. Thus, + /// Command does not need to be 0 if you are setting print job parameters, although it can be. + /// + /// + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + /// + /// + /// + /// You can use the SetJob function to set various print job parameters by supplying a pointer to a JOB_INFO_1, + /// JOB_INFO_2, JOB_INFO_3, or JOB_INFO_4 structure that contains the necessary data. + /// + /// + /// To remove or delete all of the print jobs for a particular printer, call the SetPrinter function with its Command + /// parameter set to PRINTER_CONTROL_PURGE. + /// + /// + /// The following members of a JOB_INFO_1, JOB_INFO_2, or JOB_INFO_4 structure are ignored on a call to + /// SetJob: JobId, pPrinterName, pMachineName, pUserName, pDrivername, Size, + /// Submitted, Time, and TotalPages. + /// + /// + /// You must have PRINTER_ACCESS_ADMINISTER access permission for a printer in order to change a print job's position in the + /// print queue. + /// + /// + /// If you do not want to set a print job's position in the print queue, you should set the Position member of the + /// JOB_INFO_1, JOB_INFO_2, or JOB_INFO_4 structure to JOB_POSITION_UNSPECIFIED. + /// + /// + /// Use the SetJob function with the JOB_INFO_3 structure to link together a set of print jobs (also known as a + /// chain). This is useful in situations where a single document consists of several parts that you want to render separately. To + /// print jobs A, B, C, and D in order, call SetJob with JOB_INFO_4 to link A to B, B to C, and C to D. + /// + /// If you link print jobs, note the following: + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + [PInvokeData("winspool.h", MSDNShortId = "21947c69-c517-4962-8eb7-b45ed4211d9a")] + public static bool SetJob(HPRINTER hPrinter, uint JobId, in T pJob, JOB_CONTROL Command = 0) where T : struct + { + if (!TryGetLevel("JOB_INFO_", out var lvl)) + throw new ArgumentException($"{nameof(SetJob)} cannot process a structure of type {typeof(T).Name}."); + using var mem = SafeCoTaskMemHandle.CreateFromStructure(pJob); + return SetJob(hPrinter, JobId, lvl, mem, Command); + } + + /// The SetPort function sets the status associated with a printer port. + /// + /// Pointer to a zero-terminated string that specifies the name of the printer server to which the port is connected. Set this + /// parameter to NULL if the port is on the local machine. + /// + /// Pointer to a zero-terminated string that specifies the name of the printer port. + /// + /// Specifies the type of structure pointed to by the pPortInfo parameter. + /// This value must be 3, which corresponds to a PORT_INFO_3 data structure. + /// + /// Pointer to a PORT_INFO_3 structure that contains the port status information to set. + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + /// + /// + /// The caller of the SetPort function must be executing as an Administrator. Additionally, if the caller is a Port Monitor + /// or Language Monitor, it must call RevertToSelf to cease impersonation before it calls SetPort. + /// + /// All programs that call SetPort must have SERVER_ACCESS_ADMINISTER access to the server to which the port is connected. + /// + /// When you set a printer port status value with the severity value PORT_STATUS_TYPE_ERROR, the print spooler stops sending jobs to + /// the port. The print spooler resumes sending jobs to the port when the port status is cleared by another call to SetPort. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/setport BOOL SetPort( _In_ LPTSTR pName, _In_ LPTSTR pPortName, _In_ + // DWORD dwLevel, _In_ LPBYTE pPortInfo ); + [DllImport(Lib.Winspool, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "1b80ad93-aaa1-41ed-a668-a944fa62c3eb")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool SetPort([Optional] string pName, string pPortName, uint dwLevel, IntPtr pPortInfo); + + /// The SetPort function sets the status associated with a printer port. + /// + /// A string that specifies the name of the printer server to which the port is connected. Set this parameter to + /// if the port is on the local machine. + /// + /// A string that specifies the name of the printer port. + /// The new port status value. + /// The severity of the port status value. + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + /// + /// + /// The caller of the SetPort function must be executing as an Administrator. Additionally, if the caller is a Port Monitor + /// or Language Monitor, it must call RevertToSelf to cease impersonation before it calls SetPort. + /// + /// All programs that call SetPort must have SERVER_ACCESS_ADMINISTER access to the server to which the port is connected. + /// + /// When you set a printer port status value with the severity value PORT_STATUS_TYPE_ERROR, the print spooler stops sending jobs to + /// the port. The print spooler resumes sending jobs to the port when the port status is cleared by another call to SetPort. + /// + /// + [PInvokeData("winspool.h", MSDNShortId = "1b80ad93-aaa1-41ed-a668-a944fa62c3eb")] + public static bool SetPort([Optional] string pName, string pPortName, PORT_STATUS status, PORT_STATUS_TYPE severity) + { + using var mem = SafeCoTaskMemHandle.CreateFromStructure(new PORT_INFO_3 { dwStatus = status, dwSeverity = severity }); + return SetPort(pName, pPortName, 3, mem); + } + + /// The SetPort function sets the status associated with a printer port. + /// + /// A string that specifies the name of the printer server to which the port is connected. Set this parameter to + /// if the port is on the local machine. + /// + /// A string that specifies the name of the printer port. + /// + /// A new printer port status value string to set. Use this member if there is no suitable status value among those listed for . + /// + /// The severity of the port status value. + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + /// + /// + /// The caller of the SetPort function must be executing as an Administrator. Additionally, if the caller is a Port Monitor + /// or Language Monitor, it must call RevertToSelf to cease impersonation before it calls SetPort. + /// + /// All programs that call SetPort must have SERVER_ACCESS_ADMINISTER access to the server to which the port is connected. + /// + /// When you set a printer port status value with the severity value PORT_STATUS_TYPE_ERROR, the print spooler stops sending jobs to + /// the port. The print spooler resumes sending jobs to the port when the port status is cleared by another call to SetPort. + /// + /// + [PInvokeData("winspool.h", MSDNShortId = "1b80ad93-aaa1-41ed-a668-a944fa62c3eb")] + public static bool SetPort([Optional] string pName, string pPortName, string status, PORT_STATUS_TYPE severity) + { + using var mem = SafeCoTaskMemHandle.CreateFromStructure(new PORT_INFO_3 { pszStatus = status, dwSeverity = severity }); + return SetPort(pName, pPortName, 3, mem); + } + + /// + /// The SetPrinter function sets the data for a specified printer or sets the state of the specified printer by pausing + /// printing, resuming printing, or clearing all print jobs. + /// + /// + /// A handle to the printer. Use the OpenPrinter, OpenPrinter2, or AddPrinter function to retrieve a printer handle. + /// + /// + /// + /// The type of data that the function stores into the buffer pointed to by pPrinter. If the Command parameter is not equal to zero, + /// the Level parameter must be zero. + /// + /// This value can be 0, 2, 3, 4, 5, 6, 7, 8, or 9. + /// + /// + /// + /// A pointer to a buffer containing data to set for the printer, or containing information for the command specified by the Command + /// parameter. The type of data in the buffer is determined by the value of Level. + /// + /// + /// + /// Level + /// Structure + /// + /// + /// 0 + /// + /// If the Command parameter is PRINTER_CONTROL_SET_STATUS, pPrinter must contain a DWORD value that specifies the new printer + /// status to set. For a list of the possible status values, see the Status member of the PRINTER_INFO_2 structure. Note that + /// PRINTER_STATUS_PAUSED and PRINTER_STATUS_PENDING_DELETION are not valid status values to set. If Level is 0, but the Command + /// parameter is not PRINTER_CONTROL_SET_STATUS, pPrinter must be NULL. + /// + /// + /// + /// 2 + /// A PRINTER_INFO_2 structure containing detailed information about the printer. + /// + /// + /// 3 + /// A PRINTER_INFO_3 structure containing the printer's security information. + /// + /// + /// 4 + /// + /// A PRINTER_INFO_4 structure containing minimal printer information, including the name of the printer, the name of the server, + /// and whether the printer is remote or local. + /// + /// + /// + /// 5 + /// A PRINTER_INFO_5 structure containing printer information such as printer attributes and time-out settings. + /// + /// + /// 6 + /// A PRINTER_INFO_6 structure specifying the status value of a printer. + /// + /// + /// 7 + /// + /// A PRINTER_INFO_7 structure. The dwAction member of this structure indicates whether SetPrinter should publish, unpublish, + /// re-publish, or update the printer's data in the directory service. + /// + /// + /// + /// 8 + /// A PRINTER_INFO_8 structure specifying the global default printer settings. + /// + /// + /// 9 + /// A PRINTER_INFO_9 structure specifying the per-user default printer settings. + /// + /// + /// + /// + /// The action to perform. + /// + /// If the Level parameter is nonzero, set the value of this parameter to zero. In this case, the printer retains its current state + /// and the function reconfigures the printer data as specified by the Level and pPrinter parameters. + /// + /// If the Level parameter is zero, set the value of this parameter to one of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// PRINTER_CONTROL_PAUSE + /// Pause the printer. + /// + /// + /// PRINTER_CONTROL_PURGE + /// Delete all print jobs in the printer. + /// + /// + /// PRINTER_CONTROL_RESUME + /// Resume a paused printer. + /// + /// + /// PRINTER_CONTROL_SET_STATUS + /// Set the printer status. Set the pPrinter parameter to a pointer to a DWORD value that specifies the new printer status. + /// + /// + /// + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + /// If Level is 7 and the publish action failed, SetPrinter returns ERROR_IO_PENDING and attempts to complete the + /// action in the background. If Level is 7 and the update action failed, SetPrinter returns ERROR_FILE_NOT_FOUND. + /// + /// + /// + /// You cannot use SetPrinter to change the default printer. + /// + /// To modify the current printer settings, call the GetPrinter function to retrieve the current settings into a + /// PRINTER_INFO_2 structure, modify the members of that structure as necessary, and then call SetPrinter. + /// + /// + /// The SetPrinter function ignores the pServerName, AveragePPM, Status, and cJobs members of a + /// PRINTER_INFO_2 structure. + /// + /// + /// Pausing a printer suspends scheduling of all print jobs for that printer, except for the one print job that may be currently + /// printing. Print jobs can be submitted to a paused printer, but no jobs will be scheduled to print on that printer until printing + /// is resumed. If a printer is cleared, all print jobs for that printer are deleted, except for the current print job. + /// + /// + /// If you use SetPrinter to modify the default DEVMODE structure for a printer (globally setting the printer + /// defaults), you must first call the DocumentProperties function to validate the DEVMODE structure. + /// + /// + /// For the PRINTER_INFO_2 and PRINTER_INFO_3 structures that contain a pointer to a security descriptor, the function + /// can set only those components of the security descriptor that the caller has permission to modify. To set particular security + /// descriptor components, you must specify the necessary access rights when you call the OpenPrinter or OpenPrinter2 + /// function to retrieve a handle to the printer. The following table shows the access rights required to modify the various + /// security descriptor components. + /// + /// + /// + /// Access permission + /// Security descriptor component + /// + /// + /// WRITE_OWNER + /// Owner Primary group + /// + /// + /// WRITE_DAC + /// Discretionary access-control list (DACL) + /// + /// + /// ACCESS_SYSTEM_SECURITY + /// System access-control list (SACL) + /// + /// + /// + /// If the security descriptor contains a component that the caller does not have the access right to modify, SetPrinter + /// fails. Those components of a security descriptor that you don't want to modify should be NULL or not be present, as + /// appropriate. If you do not want to modify the security descriptor, and are calling SetPrinter with a + /// PRINTER_INFO_2 structure, set the pSecurityDescriptor member of that structure to NULL. + /// + /// + /// The Internet Connection Firewall (ICF) blocks printer ports by default, but an exception for File and Print Sharing can be + /// enabled. If SetPrinter is called by a machine admin, it enables the exception. If it is called by a non-admin and the + /// exception has not already been enabled, the call fails. + /// + /// + /// You can use level 7 with the PRINTER_INFO_7 structure to publish, unpublish, or update directory service data for the + /// printer. The directory service data for a printer includes all the data stored under the SPLDS_* keys by calls to the + /// SetPrinterDataEx function for the printer. Before calling SetPrinter, set the pszObjectGUID member of + /// PRINTER_INFO_7 to NULL and set the dwAction member to one of the following values. + /// + /// + /// + /// Value + /// Description + /// + /// + /// DSPRINT_PUBLISH + /// Publishes the directory service data. + /// + /// + /// DSPRINT_REPUBLISH + /// + /// The directory service data for the printer is unpublished and then published again, refreshing all properties in the published + /// printer. Re-publishing also changes the GUID of the published printer. Use this value if you suspect the printer's published + /// data has been corrupted. + /// + /// + /// + /// DSPRINT_UNPUBLISH + /// Unpublishes the directory service data. + /// + /// + /// DSPRINT_UPDATE + /// + /// Updates the directory service data. This is the same as DSPRINT_PUBLISH, except that SetPrinter fails with ERROR_FILE_NOT_FOUND + /// if the printer is not already published. Use DSPRINT_UPDATE to update published properties but not force publishing. Printer + /// drivers should always use DSPRINT_UPDATE rather than DSPRINT_PUBLISH. + /// + /// + /// + /// DSPRINT_PENDING is not a valid dwAction value for SetPrinter. + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/setprinter BOOL SetPrinter( _In_ HANDLE hPrinter, _In_ DWORD Level, _In_ + // LPBYTE pPrinter, _In_ DWORD Command ); + [DllImport(Lib.Winspool, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "ade367c5-20d6-4da9-bb52-ce6768cf7537")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool SetPrinter(HPRINTER hPrinter, uint Level, IntPtr pPrinter, PRINTER_CONTROL Command = 0); + + /// + /// The SetPrinter function sets the data for a specified printer or sets the state of the specified printer by pausing + /// printing, resuming printing, or clearing all print jobs. + /// + /// + /// A handle to the printer. Use the OpenPrinter, OpenPrinter2, or AddPrinter function to retrieve a printer handle. + /// + /// + /// The action to perform. Set the value of this parameter to one of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// PRINTER_CONTROL_PAUSE + /// Pause the printer. + /// + /// + /// PRINTER_CONTROL_PURGE + /// Delete all print jobs in the printer. + /// + /// + /// PRINTER_CONTROL_RESUME + /// Resume a paused printer. + /// + /// + /// PRINTER_CONTROL_SET_STATUS + /// + /// Set the printer status. Set the pPrinter parameter to a pointer to a DWORD value that specifies the new printer status. + /// + /// + /// + /// + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/setprinter BOOL SetPrinter( _In_ HANDLE hPrinter, _In_ DWORD Level, _In_ + // LPBYTE pPrinter, _In_ DWORD Command ); + [PInvokeData("winspool.h", MSDNShortId = "ade367c5-20d6-4da9-bb52-ce6768cf7537")] + public static bool SetPrinter(HPRINTER hPrinter, PRINTER_CONTROL Command) => SetPrinter(hPrinter, 0, default, Command); + + /// + /// The SetPrinter function sets the data for a specified printer or sets the state of the specified printer by pausing + /// printing, resuming printing, or clearing all print jobs. + /// + /// The type of the structure used in . + /// + /// A handle to the printer. Use the OpenPrinter, OpenPrinter2, or AddPrinter function to retrieve a printer handle. + /// + /// + /// + /// A pointer to a buffer containing data to set for the printer, or containing information for the command specified by the Command + /// parameter. The type of data in the buffer is determined by the value of Level. + /// + /// + /// + /// Level + /// Structure + /// + /// + /// 0 + /// + /// If the Command parameter is PRINTER_CONTROL_SET_STATUS, pPrinter must contain a DWORD value that specifies the new printer + /// status to set. For a list of the possible status values, see the Status member of the PRINTER_INFO_2 structure. Note that + /// PRINTER_STATUS_PAUSED and PRINTER_STATUS_PENDING_DELETION are not valid status values to set. If Level is 0, but the Command + /// parameter is not PRINTER_CONTROL_SET_STATUS, pPrinter must be NULL. + /// + /// + /// + /// 2 + /// A PRINTER_INFO_2 structure containing detailed information about the printer. + /// + /// + /// 3 + /// A PRINTER_INFO_3 structure containing the printer's security information. + /// + /// + /// 4 + /// + /// A PRINTER_INFO_4 structure containing minimal printer information, including the name of the printer, the name of the server, + /// and whether the printer is remote or local. + /// + /// + /// + /// 5 + /// A PRINTER_INFO_5 structure containing printer information such as printer attributes and time-out settings. + /// + /// + /// 6 + /// A PRINTER_INFO_6 structure specifying the status value of a printer. + /// + /// + /// 7 + /// + /// A PRINTER_INFO_7 structure. The dwAction member of this structure indicates whether SetPrinter should publish, unpublish, + /// re-publish, or update the printer's data in the directory service. + /// + /// + /// + /// 8 + /// A PRINTER_INFO_8 structure specifying the global default printer settings. + /// + /// + /// 9 + /// A PRINTER_INFO_9 structure specifying the per-user default printer settings. + /// + /// + /// + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + /// If Level is 7 and the publish action failed, SetPrinter returns ERROR_IO_PENDING and attempts to complete the + /// action in the background. If Level is 7 and the update action failed, SetPrinter returns ERROR_FILE_NOT_FOUND. + /// + /// + /// + /// + /// You cannot use SetPrinter to change the default printer. + /// + /// To modify the current printer settings, call the GetPrinter function to retrieve the current settings into a + /// PRINTER_INFO_2 structure, modify the members of that structure as necessary, and then call SetPrinter. + /// + /// + /// The SetPrinter function ignores the pServerName, AveragePPM, Status, and cJobs members of a + /// PRINTER_INFO_2 structure. + /// + /// + /// Pausing a printer suspends scheduling of all print jobs for that printer, except for the one print job that may be currently + /// printing. Print jobs can be submitted to a paused printer, but no jobs will be scheduled to print on that printer until printing + /// is resumed. If a printer is cleared, all print jobs for that printer are deleted, except for the current print job. + /// + /// + /// If you use SetPrinter to modify the default DEVMODE structure for a printer (globally setting the printer + /// defaults), you must first call the DocumentProperties function to validate the DEVMODE structure. + /// + /// + /// For the PRINTER_INFO_2 and PRINTER_INFO_3 structures that contain a pointer to a security descriptor, the function + /// can set only those components of the security descriptor that the caller has permission to modify. To set particular security + /// descriptor components, you must specify the necessary access rights when you call the OpenPrinter or OpenPrinter2 + /// function to retrieve a handle to the printer. The following table shows the access rights required to modify the various + /// security descriptor components. + /// + /// + /// + /// Access permission + /// Security descriptor component + /// + /// + /// WRITE_OWNER + /// Owner Primary group + /// + /// + /// WRITE_DAC + /// Discretionary access-control list (DACL) + /// + /// + /// ACCESS_SYSTEM_SECURITY + /// System access-control list (SACL) + /// + /// + /// + /// If the security descriptor contains a component that the caller does not have the access right to modify, SetPrinter + /// fails. Those components of a security descriptor that you don't want to modify should be NULL or not be present, as + /// appropriate. If you do not want to modify the security descriptor, and are calling SetPrinter with a + /// PRINTER_INFO_2 structure, set the pSecurityDescriptor member of that structure to NULL. + /// + /// + /// The Internet Connection Firewall (ICF) blocks printer ports by default, but an exception for File and Print Sharing can be + /// enabled. If SetPrinter is called by a machine admin, it enables the exception. If it is called by a non-admin and the + /// exception has not already been enabled, the call fails. + /// + /// + /// You can use level 7 with the PRINTER_INFO_7 structure to publish, unpublish, or update directory service data for the + /// printer. The directory service data for a printer includes all the data stored under the SPLDS_* keys by calls to the + /// SetPrinterDataEx function for the printer. Before calling SetPrinter, set the pszObjectGUID member of + /// PRINTER_INFO_7 to NULL and set the dwAction member to one of the following values. + /// + /// + /// + /// Value + /// Description + /// + /// + /// DSPRINT_PUBLISH + /// Publishes the directory service data. + /// + /// + /// DSPRINT_REPUBLISH + /// + /// The directory service data for the printer is unpublished and then published again, refreshing all properties in the published + /// printer. Re-publishing also changes the GUID of the published printer. Use this value if you suspect the printer's published + /// data has been corrupted. + /// + /// + /// + /// DSPRINT_UNPUBLISH + /// Unpublishes the directory service data. + /// + /// + /// DSPRINT_UPDATE + /// + /// Updates the directory service data. This is the same as DSPRINT_PUBLISH, except that SetPrinter fails with ERROR_FILE_NOT_FOUND + /// if the printer is not already published. Use DSPRINT_UPDATE to update published properties but not force publishing. Printer + /// drivers should always use DSPRINT_UPDATE rather than DSPRINT_PUBLISH. + /// + /// + /// + /// DSPRINT_PENDING is not a valid dwAction value for SetPrinter. + /// + [PInvokeData("winspool.h", MSDNShortId = "ade367c5-20d6-4da9-bb52-ce6768cf7537")] + public static bool SetPrinter(HPRINTER hPrinter, in T pPrinter) where T : struct + { + if (!TryGetLevel("PRINTER_INFO_", out var lvl)) + throw new ArgumentException($"{nameof(SetPrinter)} cannot process a structure of type {typeof(T).Name}."); + using var mem = SafeCoTaskMemHandle.CreateFromStructure(pPrinter); + return SetPrinter(hPrinter, lvl, mem); + } + + /// + /// The SetPrinterData function sets the configuration data for a printer or print server. + /// + /// To specify the registry key under which to store the data, call the SetPrinterDataEx function. Calling + /// SetPrinterData is equivalent to calling the SetPrinterDataEx function with the pKeyName parameter set to "PrinterDriverData". + /// + /// + /// + /// A handle to the printer or print server for which the function sets configuration data. Use the OpenPrinter, + /// OpenPrinter2, or AddPrinter function to retrieve a printer handle. + /// + /// + /// A pointer to a null-terminated string that identifies the data to set. + /// For printers, this string is the name of a registry value under the printer's "PrinterDriverData" key in the registry. + /// For print servers, this string is one of the predefined strings listed in the following Remarks section. + /// + /// + /// A code that indicates the type of data that the pData parameter points to. For a list of the possible type codes, see Registry + /// Value Types. + /// + /// A pointer to an array of bytes that contains the printer configuration data. + /// The size, in bytes, of the array. + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. + /// If the function fails, the return value is an error value. + /// + /// + /// To retrieve existing configuration data for a printer, call the GetPrinterDataEx or GetPrinterData function. + /// If hPrinter is a handle to a print server, pValueName can specify one of the following predefined values. + /// + /// + /// Value + /// Comments + /// + /// + /// SPLREG_ALLOW_USER_MANAGEFORMS + /// Windows XP with Service Pack 2 (SP2) and later Windows Server 2003 with Service Pack 1 (SP1) and later + /// + /// + /// SPLREG_BEEP_ENABLED + /// + /// + /// + /// SPLREG_DEFAULT_SPOOL_DIRECTORY + /// + /// + /// + /// SPLREG_EVENT_LOG + /// + /// + /// + /// SPLREG_NET_POPUP + /// Not supported in Windows Server 2003 and later + /// + /// + /// SPLREG_PORT_THREAD_PRIORITY_DEFAULT + /// + /// + /// + /// SPLREG_PORT_THREAD_PRIORITY + /// + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_GROUPS + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_TIME_BEFORE_RECYCLE + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_MAX_OBJECTS_BEFORE_RECYCLE + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_IDLE_TIMEOUT + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_EXECUTION_POLICY + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_OVERRIDE_POLICY + /// Windows 7 and later + /// + /// + /// SPLREG_RETRY_POPUP + /// + /// On successful return, pData contains 1 if server is set to retry pop-up windows for all jobs, or 0 if server does not retry + /// pop-up windows for all jobs. Not supported in Windows Server 2003 and later + /// + /// + /// + /// SPLREG_SCHEDULER_THREAD_PRIORITY + /// + /// + /// + /// SPLREG_SCHEDULER_THREAD_PRIORITY_DEFAULT + /// + /// + /// + /// SPLREG_WEBSHAREMGMT + /// Windows Server 2003 and later + /// + /// + /// The following values of pValueName determine the pool printing behavior when an error occurs. + /// + /// + /// Value + /// Comments + /// + /// + /// SPLREG_RESTART_JOB_ON_POOL_ERROR + /// + /// The value of pData indicates the time, in seconds, when a job is restarted on another port after an error occurs. This setting + /// is used with SPLREG_RESTART_JOB_ON_POOL_ENABLED. + /// + /// + /// + /// SPLREG_RESTART_JOB_ON_POOL_ENABLED + /// A nonzero value in pData indicates that SPLREG_RESTART_JOB_ON_POOL_ERROR is enabled. + /// + /// + /// + /// The time specified in SPLREG_RESTART_JOB_ON_POOL_ERROR is a minimum time. The actual time can be longer, depending on the + /// following port monitor settings, which are registry values under this registry key: + /// + /// HKLM\SYSTEM\CurrentControlSet\Control\Print\Monitors\<MonitorName>\Ports + /// Call the RegSetValueEx function to set these values. + /// + /// + /// Port monitor setting + /// Data type + /// Meaning + /// + /// + /// StatusUpdateEnabled + /// REG_DWORD + /// If a nonzero value, enables the port monitor to update the spooler with the port status. + /// + /// + /// StatusUpdateInterval + /// REG_DWORD + /// Specifies the interval, in minutes, when the port monitor updates the spooler with the port status. + /// + /// + /// + /// In Windows 7 and later versions of Windows, print jobs that are sent to a print server are rendered on the client by default. + /// Client-side rendering of a print jobs can be configured for each printer by setting the following values in pValueName. + /// + /// + /// + /// Setting + /// Data type + /// Description + /// + /// + /// EMFDespoolingSetting + /// REG_DWORD + /// + /// A value of 0, or if this value is not present in the registry, enables the default client-side rendering of print jobs. A value + /// of 1 disables client-side rendering of print jobs. + /// + /// + /// + /// ForceClientSideRendering + /// REG_DWORD + /// + /// A value of 0, or if this value is not present in the registry, causes the print jobs to be rendered on the client. If a print + /// job cannot be rendered on the client, it will be rendered on the server. If a print job cannot be rendered on the server, it + /// will fail. A value of 1 will render print jobs on the client. If a print job cannot be rendered on the client, it will fail. + /// + /// + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/setprinterdata DWORD SetPrinterData( _In_ HANDLE hPrinter, _In_ LPTSTR + // pValueName, _In_ DWORD Type, _In_ LPBYTE pData, _In_ DWORD cbData ); + [DllImport(Lib.Winspool, SetLastError = false, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "16072de9-98fb-4ada-8216-180b64cf44c8")] + public static extern Win32Error SetPrinterData(HPRINTER hPrinter, string pValueName, REG_VALUE_TYPE Type, IntPtr pData, uint cbData); + + /// + /// The SetPrinterData function sets the configuration data for a printer or print server. + /// + /// To specify the registry key under which to store the data, call the SetPrinterDataEx function. Calling + /// SetPrinterData is equivalent to calling the SetPrinterDataEx function with the pKeyName parameter set to "PrinterDriverData". + /// + /// + /// + /// A handle to the printer or print server for which the function sets configuration data. Use the OpenPrinter, + /// OpenPrinter2, or AddPrinter function to retrieve a printer handle. + /// + /// + /// A pointer to a null-terminated string that identifies the data to set. + /// For printers, this string is the name of a registry value under the printer's "PrinterDriverData" key in the registry. + /// For print servers, this string is one of the predefined strings listed in the following Remarks section. + /// + /// + /// A code that indicates the type of data that the pData parameter points to. For a list of the possible type codes, see Registry + /// Value Types. + /// + /// A pointer to an array of bytes that contains the printer configuration data. + /// The size, in bytes, of the array. + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. + /// If the function fails, the return value is an error value. + /// + /// + /// To retrieve existing configuration data for a printer, call the GetPrinterDataEx or GetPrinterData function. + /// If hPrinter is a handle to a print server, pValueName can specify one of the following predefined values. + /// + /// + /// Value + /// Comments + /// + /// + /// SPLREG_ALLOW_USER_MANAGEFORMS + /// Windows XP with Service Pack 2 (SP2) and later Windows Server 2003 with Service Pack 1 (SP1) and later + /// + /// + /// SPLREG_BEEP_ENABLED + /// + /// + /// + /// SPLREG_DEFAULT_SPOOL_DIRECTORY + /// + /// + /// + /// SPLREG_EVENT_LOG + /// + /// + /// + /// SPLREG_NET_POPUP + /// Not supported in Windows Server 2003 and later + /// + /// + /// SPLREG_PORT_THREAD_PRIORITY_DEFAULT + /// + /// + /// + /// SPLREG_PORT_THREAD_PRIORITY + /// + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_GROUPS + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_TIME_BEFORE_RECYCLE + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_MAX_OBJECTS_BEFORE_RECYCLE + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_IDLE_TIMEOUT + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_EXECUTION_POLICY + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_OVERRIDE_POLICY + /// Windows 7 and later + /// + /// + /// SPLREG_RETRY_POPUP + /// + /// On successful return, pData contains 1 if server is set to retry pop-up windows for all jobs, or 0 if server does not retry + /// pop-up windows for all jobs. Not supported in Windows Server 2003 and later + /// + /// + /// + /// SPLREG_SCHEDULER_THREAD_PRIORITY + /// + /// + /// + /// SPLREG_SCHEDULER_THREAD_PRIORITY_DEFAULT + /// + /// + /// + /// SPLREG_WEBSHAREMGMT + /// Windows Server 2003 and later + /// + /// + /// The following values of pValueName determine the pool printing behavior when an error occurs. + /// + /// + /// Value + /// Comments + /// + /// + /// SPLREG_RESTART_JOB_ON_POOL_ERROR + /// + /// The value of pData indicates the time, in seconds, when a job is restarted on another port after an error occurs. This setting + /// is used with SPLREG_RESTART_JOB_ON_POOL_ENABLED. + /// + /// + /// + /// SPLREG_RESTART_JOB_ON_POOL_ENABLED + /// A nonzero value in pData indicates that SPLREG_RESTART_JOB_ON_POOL_ERROR is enabled. + /// + /// + /// + /// The time specified in SPLREG_RESTART_JOB_ON_POOL_ERROR is a minimum time. The actual time can be longer, depending on the + /// following port monitor settings, which are registry values under this registry key: + /// + /// HKLM\SYSTEM\CurrentControlSet\Control\Print\Monitors\<MonitorName>\Ports + /// Call the RegSetValueEx function to set these values. + /// + /// + /// Port monitor setting + /// Data type + /// Meaning + /// + /// + /// StatusUpdateEnabled + /// REG_DWORD + /// If a nonzero value, enables the port monitor to update the spooler with the port status. + /// + /// + /// StatusUpdateInterval + /// REG_DWORD + /// Specifies the interval, in minutes, when the port monitor updates the spooler with the port status. + /// + /// + /// + /// In Windows 7 and later versions of Windows, print jobs that are sent to a print server are rendered on the client by default. + /// Client-side rendering of a print jobs can be configured for each printer by setting the following values in pValueName. + /// + /// + /// + /// Setting + /// Data type + /// Description + /// + /// + /// EMFDespoolingSetting + /// REG_DWORD + /// + /// A value of 0, or if this value is not present in the registry, enables the default client-side rendering of print jobs. A value + /// of 1 disables client-side rendering of print jobs. + /// + /// + /// + /// ForceClientSideRendering + /// REG_DWORD + /// + /// A value of 0, or if this value is not present in the registry, causes the print jobs to be rendered on the client. If a print + /// job cannot be rendered on the client, it will be rendered on the server. If a print job cannot be rendered on the server, it + /// will fail. A value of 1 will render print jobs on the client. If a print job cannot be rendered on the client, it will fail. + /// + /// + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/setprinterdata DWORD SetPrinterData( _In_ HANDLE hPrinter, _In_ LPTSTR + // pValueName, _In_ DWORD Type, _In_ LPBYTE pData, _In_ DWORD cbData ); + [DllImport(Lib.Winspool, SetLastError = false, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "16072de9-98fb-4ada-8216-180b64cf44c8")] + public static extern Win32Error SetPrinterData(HPRINTER hPrinter, string pValueName, REG_VALUE_TYPE Type, byte[] pData, int cbData); + + /// + /// The SetPrinterData function sets the configuration data for a printer or print server. + /// + /// To specify the registry key under which to store the data, call the SetPrinterDataEx function. Calling + /// SetPrinterData is equivalent to calling the SetPrinterDataEx function with the pKeyName parameter set to "PrinterDriverData". + /// + /// + /// + /// A handle to the printer or print server for which the function sets configuration data. Use the OpenPrinter, + /// OpenPrinter2, or AddPrinter function to retrieve a printer handle. + /// + /// + /// A pointer to a null-terminated string that identifies the data to set. + /// For printers, this string is the name of a registry value under the printer's "PrinterDriverData" key in the registry. + /// For print servers, this string is one of the predefined strings listed in the following Remarks section. + /// + /// A pointer to an array of bytes that contains the printer configuration data. + /// + /// A code that indicates the type of data that the pData parameter points to. For a list of the possible type codes, see Registry + /// Value Types. + /// + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. + /// If the function fails, the return value is an error value. + /// + /// + /// To retrieve existing configuration data for a printer, call the GetPrinterDataEx or GetPrinterData function. + /// If hPrinter is a handle to a print server, pValueName can specify one of the following predefined values. + /// + /// + /// Value + /// Comments + /// + /// + /// SPLREG_ALLOW_USER_MANAGEFORMS + /// Windows XP with Service Pack 2 (SP2) and later Windows Server 2003 with Service Pack 1 (SP1) and later + /// + /// + /// SPLREG_BEEP_ENABLED + /// + /// + /// + /// SPLREG_DEFAULT_SPOOL_DIRECTORY + /// + /// + /// + /// SPLREG_EVENT_LOG + /// + /// + /// + /// SPLREG_NET_POPUP + /// Not supported in Windows Server 2003 and later + /// + /// + /// SPLREG_PORT_THREAD_PRIORITY_DEFAULT + /// + /// + /// + /// SPLREG_PORT_THREAD_PRIORITY + /// + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_GROUPS + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_TIME_BEFORE_RECYCLE + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_MAX_OBJECTS_BEFORE_RECYCLE + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_IDLE_TIMEOUT + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_EXECUTION_POLICY + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_OVERRIDE_POLICY + /// Windows 7 and later + /// + /// + /// SPLREG_RETRY_POPUP + /// + /// On successful return, pData contains 1 if server is set to retry pop-up windows for all jobs, or 0 if server does not retry + /// pop-up windows for all jobs. Not supported in Windows Server 2003 and later + /// + /// + /// + /// SPLREG_SCHEDULER_THREAD_PRIORITY + /// + /// + /// + /// SPLREG_SCHEDULER_THREAD_PRIORITY_DEFAULT + /// + /// + /// + /// SPLREG_WEBSHAREMGMT + /// Windows Server 2003 and later + /// + /// + /// The following values of pValueName determine the pool printing behavior when an error occurs. + /// + /// + /// Value + /// Comments + /// + /// + /// SPLREG_RESTART_JOB_ON_POOL_ERROR + /// + /// The value of pData indicates the time, in seconds, when a job is restarted on another port after an error occurs. This setting + /// is used with SPLREG_RESTART_JOB_ON_POOL_ENABLED. + /// + /// + /// + /// SPLREG_RESTART_JOB_ON_POOL_ENABLED + /// A nonzero value in pData indicates that SPLREG_RESTART_JOB_ON_POOL_ERROR is enabled. + /// + /// + /// + /// The time specified in SPLREG_RESTART_JOB_ON_POOL_ERROR is a minimum time. The actual time can be longer, depending on the + /// following port monitor settings, which are registry values under this registry key: + /// + /// HKLM\SYSTEM\CurrentControlSet\Control\Print\Monitors\<MonitorName>\Ports + /// Call the RegSetValueEx function to set these values. + /// + /// + /// Port monitor setting + /// Data type + /// Meaning + /// + /// + /// StatusUpdateEnabled + /// REG_DWORD + /// If a nonzero value, enables the port monitor to update the spooler with the port status. + /// + /// + /// StatusUpdateInterval + /// REG_DWORD + /// Specifies the interval, in minutes, when the port monitor updates the spooler with the port status. + /// + /// + /// + /// In Windows 7 and later versions of Windows, print jobs that are sent to a print server are rendered on the client by default. + /// Client-side rendering of a print jobs can be configured for each printer by setting the following values in pValueName. + /// + /// + /// + /// Setting + /// Data type + /// Description + /// + /// + /// EMFDespoolingSetting + /// REG_DWORD + /// + /// A value of 0, or if this value is not present in the registry, enables the default client-side rendering of print jobs. A value + /// of 1 disables client-side rendering of print jobs. + /// + /// + /// + /// ForceClientSideRendering + /// REG_DWORD + /// + /// A value of 0, or if this value is not present in the registry, causes the print jobs to be rendered on the client. If a print + /// job cannot be rendered on the client, it will be rendered on the server. If a print job cannot be rendered on the server, it + /// will fail. A value of 1 will render print jobs on the client. If a print job cannot be rendered on the client, it will fail. + /// + /// + /// + /// + [PInvokeData("winspool.h", MSDNShortId = "16072de9-98fb-4ada-8216-180b64cf44c8")] + public static Win32Error SetPrinterData(HPRINTER hPrinter, string pValueName, object pData, REG_VALUE_TYPE type = 0) + { + return InlineSetPrinterData(SetData, hPrinter, null, pValueName, pData, type); + + static Win32Error SetData(HPRINTER p1, string p2, string p3, REG_VALUE_TYPE p4, IntPtr p5, uint p6) => + SetPrinterData(p1, p3, p4, p5, p6); + } + + /// + /// The SetPrinterDataEx function sets the configuration data for a printer or print server. The function stores the + /// configuration data under the printer's registry key. + /// + /// + /// A handle to the printer or print server for which the function sets configuration data. Use the OpenPrinter, + /// OpenPrinter2, or AddPrinter function to retrieve a printer handle. + /// + /// + /// + /// A pointer to a null-terminated string that specifies the key containing the value to set. If the specified key or subkeys do not + /// exist, the function creates them. + /// + /// + /// To store configuration data that can be published in the directory service (DS), specify one of the following predefined + /// registry keys. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// SPLDS_DRIVER_KEY + /// Printer drivers use this key to store driver properties. + /// + /// + /// SPLDS_SPOOLER_KEY + /// Reserved. Used only by the print spooler to store internal spooler properties. + /// + /// + /// SPLDS_USER_KEY + /// Applications use this key to store printer properties such as printer asset numbers. + /// + /// + /// + /// Values that are stored under the SPLDS_USER_KEY key are published in the directory service only if there is a corresponding + /// property in the schema. A domain administrator must create the property if it doesn't already exist. To publish a user-defined + /// property after you use SetPrinterDataEx to add or change a value, call SetPrinter with Level = 7 and with the + /// dwAction member of PRINTER_INFO_7 set to DSPRINT_UPDATE. + /// + /// + /// You can specify other keys to store non-DS configuration data. Use the backslash ( \ ) character as a delimiter to specify a + /// path that has one or more subkeys. + /// + /// If hPrinter is a handle to a printer and pKeyName is NULL or an empty string, SetPrinterDataEx returns ERROR_INVALID_PARAMETER. + /// If hPrinter is a handle to a print server, pKeyName is ignored. + /// Do not use SPLDS_SPOOLER_KEY. To change the spooler printer properties, use SetPrinter with Level = 2. + /// + /// + /// A pointer to a null-terminated string that identifies the data to set. + /// For printers, this string specifies the name of a value under the pKeyName key. + /// For print servers, this string is one of the predefined strings listed in the following Remarks section. + /// + /// + /// + /// A code indicating the type of data pointed to by the pData parameter. For a list of the possible type codes, see Registry Value Types. + /// + /// + /// If pKeyName specifies one of the predefined directory service keys, Type must be REG_SZ, REG_MULTI_SZ, + /// REG_DWORD, or REG_BINARY. If REG_BINARY is used, cbData must be equal to 1, and the directory service + /// treats the data as a Boolean value. + /// + /// + /// A pointer to a buffer that contains the printer configuration data. + /// The size, in bytes, of the array. + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. + /// If the function fails, the return value is an error value. + /// + /// + /// To retrieve existing configuration data for a printer or print spooler, call the GetPrinterDataEx function. + /// + /// Calling SetPrinterDataEx with the pKeyName parameter set to "PrinterDriverData" is equivalent to calling the + /// SetPrinterData function. + /// + /// If hPrinter is a handle to a print server, pValueName can specify one of the following predefined values. + /// + /// + /// Value + /// Comments + /// + /// + /// SPLREG_ALLOW_USER_MANAGEFORMS + /// Windows XP with Service Pack 2 (SP2) and later Windows Server 2003 with Service Pack 1 (SP1) and later + /// + /// + /// SPLREG_BEEP_ENABLED + /// + /// + /// + /// SPLREG_DEFAULT_SPOOL_DIRECTORY + /// + /// + /// + /// SPLREG_EVENT_LOG + /// + /// + /// + /// SPLREG_NET_POPUP + /// Not supported in Windows Server 2003 and later + /// + /// + /// SPLREG_PORT_THREAD_PRIORITY_DEFAULT + /// + /// + /// + /// SPLREG_PORT_THREAD_PRIORITY + /// + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_GROUPS + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_TIME_BEFORE_RECYCLE + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_MAX_OBJECTS_BEFORE_RECYCLE + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_IDLE_TIMEOUT + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_EXECUTION_POLICY + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_OVERRIDE_POLICY + /// Windows 7 and later + /// + /// + /// SPLREG_RETRY_POPUP + /// + /// On successful return, pData contains 1 if server is set to retry pop-up windows for all jobs, or 0 if server does not retry + /// pop-up windows for all jobs. Not supported in Windows Server 2003 and later + /// + /// + /// + /// SPLREG_SCHEDULER_THREAD_PRIORITY + /// + /// + /// + /// SPLREG_SCHEDULER_THREAD_PRIORITY_DEFAULT + /// + /// + /// + /// SPLREG_WEBSHAREMGMT + /// Windows Server 2003 and later + /// + /// + /// Passing one of the following predefined values as pValueName sets the pool printing behavior when an error occurs. + /// + /// + /// Value + /// Comments + /// + /// + /// SPLREG_RESTART_JOB_ON_POOL_ERROR + /// + /// The value of pData indicates the time, in seconds, when a job is restarted on another port after an error occurs. This setting + /// is used with SPLREG_RESTART_JOB_ON_POOL_ENABLED. + /// + /// + /// + /// SPLREG_RESTART_JOB_ON_POOL_ENABLED + /// A nonzero value in pData indicates that SPLREG_RESTART_JOB_ON_POOL_ERROR is enabled. + /// + /// + /// + /// The time specified in SPLREG_RESTART_JOB_ON_POOL_ERROR is a minimum time. The actual time can be longer, depending on the + /// following port monitor settings, which are registry values under this registry key: + /// + /// HKLM\SYSTEM\CurrentControlSet\Control\Print\Monitors\<MonitorName>\Ports + /// Call the RegSetValueEx function to set these values. + /// + /// + /// Port monitor setting + /// Data type + /// Meaning + /// + /// + /// StatusUpdateEnabled + /// REG_DWORD + /// If a nonzero value, enables the port monitor to update the spooler with the port status. + /// + /// + /// StatusUpdateInterval + /// REG_DWORD + /// Specifies the interval, in minutes, when the port monitor updates the spooler with the port status. + /// + /// + /// + /// To ensure that the spooler redirects jobs to the next available printer in the pool (when the print job is not printed within + /// the set time), the port monitor must support SNMP and the network ports in the pool must be configured as "SNMP status enabled." + /// The port monitor that supports SNMP is Standard TCP/IP port monitor. + /// + /// + /// In Windows 7 and later versions of Windows, print jobs that are sent to a print server are rendered on the client by default. + /// Client-side rendering of print jobs can be configured by setting pKeyName to "PrinterDriverData" and pValueName to the setting + /// value in the following table. + /// + /// + /// + /// Setting + /// Data type + /// Description + /// + /// + /// EMFDespoolingSetting + /// REG_DWORD + /// + /// A value of 0, or if this value is not present in the registry, enables the default client-side rendering of print jobs. A value + /// of 1 disables client-side rendering of print jobs. + /// + /// + /// + /// ForceClientSideRendering + /// REG_DWORD + /// + /// A value of 0, or if this value is not present in the registry, will cause the print jobs to be rendered on the client. If a + /// print job cannot be rendered on the client, it will be rendered on the server. If a print job cannot be rendered on the server, + /// it will fail. A value of 1 will render print jobs on the client. If a print job cannot be rendered on the client, it will fail. + /// + /// + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/setprinterdataex DWORD SetPrinterDataEx( _In_ HANDLE hPrinter, _In_ + // LPCTSTR pKeyName, _In_ LPCTSTR pValueName, _In_ DWORD Type, _In_ LPBYTE pData, _In_ DWORD cbData ); + [DllImport(Lib.Winspool, SetLastError = false, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "b7faadfc-1c81-4ddf-8fe5-68f4cc0376f1")] + public static extern Win32Error SetPrinterDataEx(HPRINTER hPrinter, string pKeyName, string pValueName, REG_VALUE_TYPE Type, IntPtr pData, uint cbData); + + /// + /// The SetPrinterDataEx function sets the configuration data for a printer or print server. The function stores the + /// configuration data under the printer's registry key. + /// + /// + /// A handle to the printer or print server for which the function sets configuration data. Use the OpenPrinter, + /// OpenPrinter2, or AddPrinter function to retrieve a printer handle. + /// + /// + /// + /// A pointer to a null-terminated string that specifies the key containing the value to set. If the specified key or subkeys do not + /// exist, the function creates them. + /// + /// + /// To store configuration data that can be published in the directory service (DS), specify one of the following predefined + /// registry keys. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// SPLDS_DRIVER_KEY + /// Printer drivers use this key to store driver properties. + /// + /// + /// SPLDS_SPOOLER_KEY + /// Reserved. Used only by the print spooler to store internal spooler properties. + /// + /// + /// SPLDS_USER_KEY + /// Applications use this key to store printer properties such as printer asset numbers. + /// + /// + /// + /// Values that are stored under the SPLDS_USER_KEY key are published in the directory service only if there is a corresponding + /// property in the schema. A domain administrator must create the property if it doesn't already exist. To publish a user-defined + /// property after you use SetPrinterDataEx to add or change a value, call SetPrinter with Level = 7 and with the + /// dwAction member of PRINTER_INFO_7 set to DSPRINT_UPDATE. + /// + /// + /// You can specify other keys to store non-DS configuration data. Use the backslash ( \ ) character as a delimiter to specify a + /// path that has one or more subkeys. + /// + /// If hPrinter is a handle to a printer and pKeyName is NULL or an empty string, SetPrinterDataEx returns ERROR_INVALID_PARAMETER. + /// If hPrinter is a handle to a print server, pKeyName is ignored. + /// Do not use SPLDS_SPOOLER_KEY. To change the spooler printer properties, use SetPrinter with Level = 2. + /// + /// + /// A pointer to a null-terminated string that identifies the data to set. + /// For printers, this string specifies the name of a value under the pKeyName key. + /// For print servers, this string is one of the predefined strings listed in the following Remarks section. + /// + /// + /// + /// A code indicating the type of data pointed to by the pData parameter. For a list of the possible type codes, see Registry Value Types. + /// + /// + /// If pKeyName specifies one of the predefined directory service keys, Type must be REG_SZ, REG_MULTI_SZ, + /// REG_DWORD, or REG_BINARY. If REG_BINARY is used, cbData must be equal to 1, and the directory service + /// treats the data as a Boolean value. + /// + /// + /// A pointer to a buffer that contains the printer configuration data. + /// The size, in bytes, of the array. + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. + /// If the function fails, the return value is an error value. + /// + /// + /// To retrieve existing configuration data for a printer or print spooler, call the GetPrinterDataEx function. + /// + /// Calling SetPrinterDataEx with the pKeyName parameter set to "PrinterDriverData" is equivalent to calling the + /// SetPrinterData function. + /// + /// If hPrinter is a handle to a print server, pValueName can specify one of the following predefined values. + /// + /// + /// Value + /// Comments + /// + /// + /// SPLREG_ALLOW_USER_MANAGEFORMS + /// Windows XP with Service Pack 2 (SP2) and later Windows Server 2003 with Service Pack 1 (SP1) and later + /// + /// + /// SPLREG_BEEP_ENABLED + /// + /// + /// + /// SPLREG_DEFAULT_SPOOL_DIRECTORY + /// + /// + /// + /// SPLREG_EVENT_LOG + /// + /// + /// + /// SPLREG_NET_POPUP + /// Not supported in Windows Server 2003 and later + /// + /// + /// SPLREG_PORT_THREAD_PRIORITY_DEFAULT + /// + /// + /// + /// SPLREG_PORT_THREAD_PRIORITY + /// + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_GROUPS + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_TIME_BEFORE_RECYCLE + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_MAX_OBJECTS_BEFORE_RECYCLE + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_IDLE_TIMEOUT + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_EXECUTION_POLICY + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_OVERRIDE_POLICY + /// Windows 7 and later + /// + /// + /// SPLREG_RETRY_POPUP + /// + /// On successful return, pData contains 1 if server is set to retry pop-up windows for all jobs, or 0 if server does not retry + /// pop-up windows for all jobs. Not supported in Windows Server 2003 and later + /// + /// + /// + /// SPLREG_SCHEDULER_THREAD_PRIORITY + /// + /// + /// + /// SPLREG_SCHEDULER_THREAD_PRIORITY_DEFAULT + /// + /// + /// + /// SPLREG_WEBSHAREMGMT + /// Windows Server 2003 and later + /// + /// + /// Passing one of the following predefined values as pValueName sets the pool printing behavior when an error occurs. + /// + /// + /// Value + /// Comments + /// + /// + /// SPLREG_RESTART_JOB_ON_POOL_ERROR + /// + /// The value of pData indicates the time, in seconds, when a job is restarted on another port after an error occurs. This setting + /// is used with SPLREG_RESTART_JOB_ON_POOL_ENABLED. + /// + /// + /// + /// SPLREG_RESTART_JOB_ON_POOL_ENABLED + /// A nonzero value in pData indicates that SPLREG_RESTART_JOB_ON_POOL_ERROR is enabled. + /// + /// + /// + /// The time specified in SPLREG_RESTART_JOB_ON_POOL_ERROR is a minimum time. The actual time can be longer, depending on the + /// following port monitor settings, which are registry values under this registry key: + /// + /// HKLM\SYSTEM\CurrentControlSet\Control\Print\Monitors\<MonitorName>\Ports + /// Call the RegSetValueEx function to set these values. + /// + /// + /// Port monitor setting + /// Data type + /// Meaning + /// + /// + /// StatusUpdateEnabled + /// REG_DWORD + /// If a nonzero value, enables the port monitor to update the spooler with the port status. + /// + /// + /// StatusUpdateInterval + /// REG_DWORD + /// Specifies the interval, in minutes, when the port monitor updates the spooler with the port status. + /// + /// + /// + /// To ensure that the spooler redirects jobs to the next available printer in the pool (when the print job is not printed within + /// the set time), the port monitor must support SNMP and the network ports in the pool must be configured as "SNMP status enabled." + /// The port monitor that supports SNMP is Standard TCP/IP port monitor. + /// + /// + /// In Windows 7 and later versions of Windows, print jobs that are sent to a print server are rendered on the client by default. + /// Client-side rendering of print jobs can be configured by setting pKeyName to "PrinterDriverData" and pValueName to the setting + /// value in the following table. + /// + /// + /// + /// Setting + /// Data type + /// Description + /// + /// + /// EMFDespoolingSetting + /// REG_DWORD + /// + /// A value of 0, or if this value is not present in the registry, enables the default client-side rendering of print jobs. A value + /// of 1 disables client-side rendering of print jobs. + /// + /// + /// + /// ForceClientSideRendering + /// REG_DWORD + /// + /// A value of 0, or if this value is not present in the registry, will cause the print jobs to be rendered on the client. If a + /// print job cannot be rendered on the client, it will be rendered on the server. If a print job cannot be rendered on the server, + /// it will fail. A value of 1 will render print jobs on the client. If a print job cannot be rendered on the client, it will fail. + /// + /// + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/setprinterdataex DWORD SetPrinterDataEx( _In_ HANDLE hPrinter, _In_ + // LPCTSTR pKeyName, _In_ LPCTSTR pValueName, _In_ DWORD Type, _In_ LPBYTE pData, _In_ DWORD cbData ); + [DllImport(Lib.Winspool, SetLastError = false, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "b7faadfc-1c81-4ddf-8fe5-68f4cc0376f1")] + public static extern Win32Error SetPrinterDataEx(HPRINTER hPrinter, string pKeyName, string pValueName, REG_VALUE_TYPE Type, byte[] pData, uint cbData); + + /// + /// The SetPrinterDataEx function sets the configuration data for a printer or print server. The function stores the + /// configuration data under the printer's registry key. + /// + /// + /// A handle to the printer or print server for which the function sets configuration data. Use the OpenPrinter, + /// OpenPrinter2, or AddPrinter function to retrieve a printer handle. + /// + /// + /// + /// A pointer to a null-terminated string that specifies the key containing the value to set. If the specified key or subkeys do not + /// exist, the function creates them. + /// + /// + /// To store configuration data that can be published in the directory service (DS), specify one of the following predefined + /// registry keys. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// SPLDS_DRIVER_KEY + /// Printer drivers use this key to store driver properties. + /// + /// + /// SPLDS_SPOOLER_KEY + /// Reserved. Used only by the print spooler to store internal spooler properties. + /// + /// + /// SPLDS_USER_KEY + /// Applications use this key to store printer properties such as printer asset numbers. + /// + /// + /// + /// Values that are stored under the SPLDS_USER_KEY key are published in the directory service only if there is a corresponding + /// property in the schema. A domain administrator must create the property if it doesn't already exist. To publish a user-defined + /// property after you use SetPrinterDataEx to add or change a value, call SetPrinter with Level = 7 and with the + /// dwAction member of PRINTER_INFO_7 set to DSPRINT_UPDATE. + /// + /// + /// You can specify other keys to store non-DS configuration data. Use the backslash ( \ ) character as a delimiter to specify a + /// path that has one or more subkeys. + /// + /// If hPrinter is a handle to a printer and pKeyName is NULL or an empty string, SetPrinterDataEx returns ERROR_INVALID_PARAMETER. + /// If hPrinter is a handle to a print server, pKeyName is ignored. + /// Do not use SPLDS_SPOOLER_KEY. To change the spooler printer properties, use SetPrinter with Level = 2. + /// + /// + /// A pointer to a null-terminated string that identifies the data to set. + /// For printers, this string specifies the name of a value under the pKeyName key. + /// For print servers, this string is one of the predefined strings listed in the following Remarks section. + /// + /// A pointer to a buffer that contains the printer configuration data. + /// + /// + /// A code indicating the type of data pointed to by the pData parameter. For a list of the possible type codes, see Registry Value Types. + /// + /// + /// If pKeyName specifies one of the predefined directory service keys, Type must be REG_SZ, REG_MULTI_SZ, + /// REG_DWORD, or REG_BINARY. If REG_BINARY is used, cbData must be equal to 1, and the directory service + /// treats the data as a Boolean value. + /// + /// + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. + /// If the function fails, the return value is an error value. + /// + /// + /// To retrieve existing configuration data for a printer or print spooler, call the GetPrinterDataEx function. + /// + /// Calling SetPrinterDataEx with the pKeyName parameter set to "PrinterDriverData" is equivalent to calling the + /// SetPrinterData function. + /// + /// If hPrinter is a handle to a print server, pValueName can specify one of the following predefined values. + /// + /// + /// Value + /// Comments + /// + /// + /// SPLREG_ALLOW_USER_MANAGEFORMS + /// Windows XP with Service Pack 2 (SP2) and later Windows Server 2003 with Service Pack 1 (SP1) and later + /// + /// + /// SPLREG_BEEP_ENABLED + /// + /// + /// + /// SPLREG_DEFAULT_SPOOL_DIRECTORY + /// + /// + /// + /// SPLREG_EVENT_LOG + /// + /// + /// + /// SPLREG_NET_POPUP + /// Not supported in Windows Server 2003 and later + /// + /// + /// SPLREG_PORT_THREAD_PRIORITY_DEFAULT + /// + /// + /// + /// SPLREG_PORT_THREAD_PRIORITY + /// + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_GROUPS + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_TIME_BEFORE_RECYCLE + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_MAX_OBJECTS_BEFORE_RECYCLE + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_IDLE_TIMEOUT + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_EXECUTION_POLICY + /// Windows 7 and later + /// + /// + /// SPLREG_PRINT_DRIVER_ISOLATION_OVERRIDE_POLICY + /// Windows 7 and later + /// + /// + /// SPLREG_RETRY_POPUP + /// + /// On successful return, pData contains 1 if server is set to retry pop-up windows for all jobs, or 0 if server does not retry + /// pop-up windows for all jobs. Not supported in Windows Server 2003 and later + /// + /// + /// + /// SPLREG_SCHEDULER_THREAD_PRIORITY + /// + /// + /// + /// SPLREG_SCHEDULER_THREAD_PRIORITY_DEFAULT + /// + /// + /// + /// SPLREG_WEBSHAREMGMT + /// Windows Server 2003 and later + /// + /// + /// Passing one of the following predefined values as pValueName sets the pool printing behavior when an error occurs. + /// + /// + /// Value + /// Comments + /// + /// + /// SPLREG_RESTART_JOB_ON_POOL_ERROR + /// + /// The value of pData indicates the time, in seconds, when a job is restarted on another port after an error occurs. This setting + /// is used with SPLREG_RESTART_JOB_ON_POOL_ENABLED. + /// + /// + /// + /// SPLREG_RESTART_JOB_ON_POOL_ENABLED + /// A nonzero value in pData indicates that SPLREG_RESTART_JOB_ON_POOL_ERROR is enabled. + /// + /// + /// + /// The time specified in SPLREG_RESTART_JOB_ON_POOL_ERROR is a minimum time. The actual time can be longer, depending on the + /// following port monitor settings, which are registry values under this registry key: + /// + /// HKLM\SYSTEM\CurrentControlSet\Control\Print\Monitors\<MonitorName>\Ports + /// Call the RegSetValueEx function to set these values. + /// + /// + /// Port monitor setting + /// Data type + /// Meaning + /// + /// + /// StatusUpdateEnabled + /// REG_DWORD + /// If a nonzero value, enables the port monitor to update the spooler with the port status. + /// + /// + /// StatusUpdateInterval + /// REG_DWORD + /// Specifies the interval, in minutes, when the port monitor updates the spooler with the port status. + /// + /// + /// + /// To ensure that the spooler redirects jobs to the next available printer in the pool (when the print job is not printed within + /// the set time), the port monitor must support SNMP and the network ports in the pool must be configured as "SNMP status enabled." + /// The port monitor that supports SNMP is Standard TCP/IP port monitor. + /// + /// + /// In Windows 7 and later versions of Windows, print jobs that are sent to a print server are rendered on the client by default. + /// Client-side rendering of print jobs can be configured by setting pKeyName to "PrinterDriverData" and pValueName to the setting + /// value in the following table. + /// + /// + /// + /// Setting + /// Data type + /// Description + /// + /// + /// EMFDespoolingSetting + /// REG_DWORD + /// + /// A value of 0, or if this value is not present in the registry, enables the default client-side rendering of print jobs. A value + /// of 1 disables client-side rendering of print jobs. + /// + /// + /// + /// ForceClientSideRendering + /// REG_DWORD + /// + /// A value of 0, or if this value is not present in the registry, will cause the print jobs to be rendered on the client. If a + /// print job cannot be rendered on the client, it will be rendered on the server. If a print job cannot be rendered on the server, + /// it will fail. A value of 1 will render print jobs on the client. If a print job cannot be rendered on the client, it will fail. + /// + /// + /// + /// + [PInvokeData("winspool.h", MSDNShortId = "b7faadfc-1c81-4ddf-8fe5-68f4cc0376f1")] + public static Win32Error SetPrinterDataEx(HPRINTER hPrinter, string pKeyName, string pValueName, object pData, REG_VALUE_TYPE type = 0) => + InlineSetPrinterData(SetPrinterDataEx, hPrinter, pKeyName, pValueName, pData, type); + + /// The StartDocPrinter function notifies the print spooler that a document is to be spooled for printing. + /// + /// A handle to the printer. Use the OpenPrinter or AddPrinter function to retrieve a printer handle. + /// + /// The version of the structure to which pDocInfo points. This value must be 1. + /// A pointer to a DOC_INFO_1 structure that describes the document to print. + /// + /// If the function succeeds, the return value identifies the print job. + /// If the function fails, the return value is zero. + /// + /// + /// The typical sequence for a print job is as follows: + /// + /// + /// To begin a print job, call StartDocPrinter. + /// + /// + /// To begin each page, call StartPagePrinter. + /// + /// + /// To write data to a page, call WritePrinter. + /// + /// + /// To end each page, call EndPagePrinter. + /// + /// + /// Repeat 2, 3, and 4 for as many pages as necessary. + /// + /// + /// To end the print job, call EndDocPrinter. + /// + /// + /// + /// Note that calling StartPagePrinter and EndPagePrinter may not be necessary, such as if the print data type + /// includes the page information. + /// + /// + /// When a page in a spooled file exceeds approximately 350 MB, it can fail to print and not send an error message. For example, + /// this can occur when printing large EMF files. The page size limit depends on many factors including the amount of virtual memory + /// available, the amount of memory allocated by calling processes, and the amount of fragmentation in the process heap. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/startdocprinter DWORD StartDocPrinter( _In_ HANDLE hPrinter, _In_ DWORD + // Level, _In_ LPBYTE pDocInfo ); + [DllImport(Lib.Winspool, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("winspool.h", MSDNShortId = "caa2bd80-4af3-4968-a5b9-d12f16cac6fc")] + public static extern uint StartDocPrinter(HPRINTER hPrinter, uint Level, in DOC_INFO_1 pDocInfo); + + /// The StartPagePrinter function notifies the spooler that a page is about to be printed on the specified printer. + /// + /// Handle to a printer. Use the OpenPrinter or AddPrinter function to retrieve a printer handle. + /// + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + /// + /// The sequence for a print job is as follows: + /// + /// + /// To begin a print job, call StartDocPrinter. + /// + /// + /// To begin each page, call StartPagePrinter. + /// + /// + /// To write data to a page, call WritePrinter. + /// + /// + /// To end each page, call EndPagePrinter. + /// + /// + /// Repeat 2, 3, and 4 for as many pages as necessary. + /// + /// + /// To end the print job, call EndDocPrinter. + /// + /// + /// + /// When a page in a spooled file exceeds approximately 350 MB, it can fail to print and not send an error message. For example, + /// this can occur when printing large EMF files. The page size limit depends on many factors including the amount of virtual memory + /// available, the amount of memory allocated by calling processes, and the amount of fragmentation in the process heap. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/startpageprinter BOOL StartPagePrinter( _In_ HANDLE hPrinter ); + [DllImport(Lib.Winspool, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winspool.h", MSDNShortId = "8ac7c47b-b3a7-4642-bfb7-54e014139fbf")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool StartPagePrinter(HPRINTER hPrinter); + + /// The WritePrinter function notifies the print spooler that data should be written to the specified printer. + /// + /// A handle to the printer. Use the OpenPrinter or AddPrinter function to retrieve a printer handle. + /// + /// A pointer to an array of bytes that contains the data that should be written to the printer. + /// The size, in bytes, of the array. + /// A pointer to a value that receives the number of bytes of data that were written to the printer. + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + /// + /// The sequence for a print job is as follows: + /// + /// + /// To begin a print job, call StartDocPrinter. + /// + /// + /// To begin each page, call StartPagePrinter. + /// + /// + /// To write data to a page, call WritePrinter. + /// + /// + /// To end each page, call EndPagePrinter. + /// + /// + /// Repeat 2, 3, and 4 for as many pages as necessary. + /// + /// + /// To end the print job, call EndDocPrinter. + /// + /// + /// + /// When a high-level document (such as an Adobe PDF or Microsoft Word file) or other printer data (such PCL, PS, or HPGL) is sent + /// directly to a printer, the print settings defined in the document take precedent over Windows print settings. Documents output + /// when the value of the pDatatype member of the DOC_INFO_1 structure that was passed in the pDocInfo parameter of the + /// StartDocPrinter call is "RAW" must fully describe the DEVMODE-style print job settings in the language understood + /// by the hardware. + /// + /// + /// In versions of Windows prior to Windows XP, when a page in a spooled file exceeds approximately 350 MB, it can fail to print and + /// not send an error message. For example, this can occur when printing large EMF files. The page size limit in versions of Windows + /// prior to Windows XP depends on many factors including the amount of virtual memory available, the amount of memory allocated by + /// calling processes, and the amount of fragmentation in the process heap. In Windows XP and later versions of Windows, EMF files + /// must be 2GB or less in size. If WritePrinter is used to write non EMF data, such as printer-ready PDL, the size of the + /// file is limited only by the available disk space. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/writeprinter BOOL WritePrinter( _In_ HANDLE hPrinter, _In_ LPVOID pBuf, + // _In_ DWORD cbBuf, _Out_ LPDWORD pcWritten ); + [DllImport(Lib.Winspool, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winspool.h", MSDNShortId = "9411b71f-d686-44ed-9051-d410e5ab228e")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool WritePrinter(HPRINTER hPrinter, IntPtr pBuf, uint cbBuf, out uint pcWritten); + + /// The WritePrinter function notifies the print spooler that data should be written to the specified printer. + /// + /// A handle to the printer. Use the OpenPrinter or AddPrinter function to retrieve a printer handle. + /// + /// A pointer to an array of bytes that contains the data that should be written to the printer. + /// The size, in bytes, of the array. + /// A pointer to a value that receives the number of bytes of data that were written to the printer. + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. + /// + /// + /// The sequence for a print job is as follows: + /// + /// + /// To begin a print job, call StartDocPrinter. + /// + /// + /// To begin each page, call StartPagePrinter. + /// + /// + /// To write data to a page, call WritePrinter. + /// + /// + /// To end each page, call EndPagePrinter. + /// + /// + /// Repeat 2, 3, and 4 for as many pages as necessary. + /// + /// + /// To end the print job, call EndDocPrinter. + /// + /// + /// + /// When a high-level document (such as an Adobe PDF or Microsoft Word file) or other printer data (such PCL, PS, or HPGL) is sent + /// directly to a printer, the print settings defined in the document take precedent over Windows print settings. Documents output + /// when the value of the pDatatype member of the DOC_INFO_1 structure that was passed in the pDocInfo parameter of the + /// StartDocPrinter call is "RAW" must fully describe the DEVMODE-style print job settings in the language understood + /// by the hardware. + /// + /// + /// In versions of Windows prior to Windows XP, when a page in a spooled file exceeds approximately 350 MB, it can fail to print and + /// not send an error message. For example, this can occur when printing large EMF files. The page size limit in versions of Windows + /// prior to Windows XP depends on many factors including the amount of virtual memory available, the amount of memory allocated by + /// calling processes, and the amount of fragmentation in the process heap. In Windows XP and later versions of Windows, EMF files + /// must be 2GB or less in size. If WritePrinter is used to write non EMF data, such as printer-ready PDL, the size of the + /// file is limited only by the available disk space. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/writeprinter BOOL WritePrinter( _In_ HANDLE hPrinter, _In_ LPVOID pBuf, + // _In_ DWORD cbBuf, _Out_ LPDWORD pcWritten ); + [DllImport(Lib.Winspool, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winspool.h", MSDNShortId = "9411b71f-d686-44ed-9051-d410e5ab228e")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool WritePrinter(HPRINTER hPrinter, byte[] pBuf, int cbBuf, out uint pcWritten); + + [DllImport(Lib.Winspool, SetLastError = true, CharSet = CharSet.Unicode)] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool AddPrinterConnection2([Optional] HWND hWnd, string pszName, uint dwLevel, in PRINTER_CONNECTION_INFO_1 pConnectionInfo); + + private static Win32Error InlineSetPrinterData(Func f, HPRINTER hPrinter, string pKeyName, string pValueName, object pData, REG_VALUE_TYPE type) + { + var pDataType = pData.GetType(); + if (type == 0) type = RegistryTypeExt.GetFromType(pDataType); + switch (type) + { + case REG_VALUE_TYPE.REG_NONE: + case REG_VALUE_TYPE.REG_BINARY: + using (var str = new NativeMemoryStream()) + { + str.WriteObject(pData); + str.Flush(); + return f(hPrinter, pKeyName, pValueName, type, str.Pointer, (uint)str.Length); + } + + case REG_VALUE_TYPE.REG_DWORD: + case REG_VALUE_TYPE.REG_DWORD_BIG_ENDIAN: + var bytes = BitConverter.GetBytes(Convert.ToUInt32(pData)); + if (BitConverter.IsLittleEndian && type == REG_VALUE_TYPE.REG_DWORD_BIG_ENDIAN || !BitConverter.IsLittleEndian && type == REG_VALUE_TYPE.REG_DWORD) + Array.Reverse(bytes); + using (var bs = SafeCoTaskMemHandle.CreateFromList(bytes)) + return f(hPrinter, pKeyName, pValueName, type, bs, bs.Size); + + case REG_VALUE_TYPE.REG_MULTI_SZ: + using (var ms = SafeCoTaskMemHandle.CreateFromStringList((IEnumerable)pData)) + return f(hPrinter, pKeyName, pValueName, type, ms, ms.Size); + + case REG_VALUE_TYPE.REG_QWORD: + var q = Convert.ToUInt64(pData); + return f(hPrinter, pKeyName, pValueName, type, new PinnedObject(q), 8); + + case REG_VALUE_TYPE.REG_SZ: + case REG_VALUE_TYPE.REG_EXPAND_SZ: + using (var ms = new SafeCoTaskMemString(pData.ToString())) + return f(hPrinter, pKeyName, pValueName, type, ms, ms.Size); + + default: + throw new ArgumentException("Cannot convert to a registry format.", nameof(pData)); + } + } + + [DllImport(Lib.Winspool, SetLastError = true, EntryPoint = "GetSpoolFileHandle")] + private static extern IntPtr InternalGetSpoolFileHandle(HPRINTER hPrinter); + + private static bool TryGetLevel(string prefix, out uint level) + { + level = 0; + return typeof(T).Name.StartsWith(prefix) && uint.TryParse(typeof(T).Name.Substring(typeof(T).Name.LastIndexOf('_') + 1), out level); + } + + /* + AddMonitor + AddPort + AddPrinterDriver + AddPrinterDriverEx + AddPrintProcessor + AddPrintProvidor + CorePrinterDriverInstalled + DeleteMonitor + DeletePort + DeletePrinterDriver + DeletePrinterDriverEx + DeletePrinterDriverPackage + DeletePrintProcessor + DeletePrintProvidor + EnumMonitors + EnumPorts + EnumPrinterDrivers + EnumPrintProcessorDatatypes + EnumPrintProcessors + GetCorePrinterDrivers + GetPrinterDriver + GetPrinterDriver2 + GetPrinterDriverDirectory + GetPrinterDriverPackagePath + GetPrintProcessorDirectory + InstallPrinterDriverFromPackage + UploadPrinterDriverPackage + */ + } +} \ No newline at end of file diff --git a/PInvoke/Printing/WinSpool.Structs.cs b/PInvoke/Printing/WinSpool.Structs.cs new file mode 100644 index 00000000..4d2aa78f --- /dev/null +++ b/PInvoke/Printing/WinSpool.Structs.cs @@ -0,0 +1,3789 @@ +using System; +using System.Runtime.InteropServices; +using Vanara.Extensions; +using Vanara.InteropServices; +using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME; + +namespace Vanara.PInvoke +{ + public static partial class WinSpool + { + /// + /// The ADDJOB_INFO_1 structure identifies a print job as well as the directory and file in which an application can store + /// that job. + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/addjob-info-1 typedef struct _ADDJOB_INFO_1 { LPTSTR Path; DWORD JobId; + // } ADDJOB_INFO_1, *PADDJOB_INFO_1; + [PInvokeData("winspool.h", MSDNShortId = "de915932-11a7-47e8-9be9-edab76d94189")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct ADDJOB_INFO_1 + { + /// + /// Pointer to a null-terminated string that contains the path and file name that the application can use to store the print job. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string Path; + + /// A handle to the print job. + public uint JobId; + } + + /// Represents a printer driver on which other printer drivers depend. + /// This structure can represent a manufacturer's base driver on which the drivers for various printer models are dependent. + // https://docs.microsoft.com/en-us/windows/win32/printdocs/core-printer-driver typedef struct _CORE_PRINTER_DRIVER { GUID + // CoreDriverGUID; FILETIME ftDriverDate; DWORDLONG dwlDriverVersion; TCHAR szPackageID[MAX_PATH]; } CORE_PRINTER_DRIVER, *PCORE_PRINTER_DRIVER; + [PInvokeData("winspool.h", MSDNShortId = "b03f9ac1-7ad2-4aee-b496-e1ee15ba7d38")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct CORE_PRINTER_DRIVER + { + /// The GUID of the core printer driver. + public Guid CoreDriverGUID; + + /// The date and time of the latest version of the core printer driver. + public FILETIME ftDriverDate; + + /// The version ID of the latest version of the core printer driver. + public ulong dwlDriverVersion; + + /// The path to the driver package that contains the core printer driver. + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] + public string szPackageID; + } + + /// The DATATYPES_INFO_1 structure contains information about the data type used to record a print job. + // https://docs.microsoft.com/en-us/windows/win32/printdocs/datatypes-info-1 typedef struct _DATATYPES_INFO_1 { LPTSTR pName; } + // DATATYPES_INFO_1, *PDATATYPES_INFO_1; + [PInvokeData("winspool.h", MSDNShortId = "6169006c-12d4-4608-865c-732f04107f9f")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct DATATYPES_INFO_1 + { + /// Pointer to a null-terminated string that identifies the data type used to record a print job. + [MarshalAs(UnmanagedType.LPTStr)] + public string pName; + } + + /// The DOC_INFO_1 structure describes a document that will be printed. + // https://docs.microsoft.com/en-us/windows/win32/printdocs/doc-info-1 typedef struct _DOC_INFO_1 { LPTSTR pDocName; LPTSTR + // pOutputFile; LPTSTR pDatatype; } DOC_INFO_1; + [PInvokeData("winspool.h", MSDNShortId = "142d988b-dd74-4312-8b27-331a7ec70344")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct DOC_INFO_1 + { + /// Pointer to a null-terminated string that specifies the name of the document. + [MarshalAs(UnmanagedType.LPTStr)] + public string pDocName; + + /// + /// Pointer to a null-terminated string that specifies the name of an output file. To print to a printer, set this to NULL. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pOutputFile; + + /// Pointer to a null-terminated string that identifies the type of data used to record the document. + [MarshalAs(UnmanagedType.LPTStr)] + public string pDatatype; + } + + /// The DOC_INFO_2 structure describes a document that will be printed. + // https://docs.microsoft.com/en-us/windows/win32/printdocs/doc-info-2 typedef struct _DOC_INFO_2 { LPTSTR pDocName; LPTSTR + // pOutputFile; LPTSTR pDatatype; DWORD dwMode; DWORD JobId; } DOC_INFO_2, *PDOC_INFO_2; + [PInvokeData("winspool.h", MSDNShortId = "d62333f3-cc39-4c9b-8fb3-02a2d24bbbad")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct DOC_INFO_2 + { + /// Pointer to a null-terminated string that specifies the name of the document. + [MarshalAs(UnmanagedType.LPTStr)] + public string pDocName; + + /// Pointer to a null-terminated string that specifies the name of an output file. + [MarshalAs(UnmanagedType.LPTStr)] + public string pOutputFile; + + /// Pointer to a null-terminated string that identifies the type of data used to record the document. + [MarshalAs(UnmanagedType.LPTStr)] + public string pDatatype; + + /// + /// Informs the print spooler of the nature of the data to follow. If this value is zero, the print spooler treats the data sent + /// by subsequent calls to WritePrinter as a normal print job (whether or not it is spooled depends on the printer + /// property). If this value is DI_CHANNEL, only a communications channel is opened. In this case, the data passed into + /// subsequent calls to WritePrinter is sent to the printer or subsequent calls to ReadPrinter retrieve data from + /// the printer. This mode remains effective until EndDoc is called. + /// + public uint dwMode; + + /// Reserved for internal use; should be zero. + public uint JobId; + } + + /// The DOC_INFO_3 structure describes a document that will be printed. + /// + /// The DI_MEMORYMAP_WRITE setting in DOC_INFO_3 is an optimization. This allows GDI to map spool files in the application + /// and speed up the recording. + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/doc-info-3 typedef struct _DOC_INFO_3 { LPTSTR pDocName; LPTSTR + // pOutputFile; LPTSTR pDatatype; DWORD dwFlags; } DOC_INFO_3, *PDOC_INFO_3; + [PInvokeData("winspool.h", MSDNShortId = "6e7b6727-da04-4f67-af77-6b51c68a4eb3")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct DOC_INFO_3 + { + /// Pointer to a null-terminated string that specifies the name of the document. + [MarshalAs(UnmanagedType.LPTStr)] + public string pDocName; + + /// Pointer to a null-terminated string that specifies the name of an output file. + [MarshalAs(UnmanagedType.LPTStr)] + public string pOutputFile; + + /// Pointer to a null-terminated string that identifies the type of data used to record the document. + [MarshalAs(UnmanagedType.LPTStr)] + public string pDatatype; + + /// + /// Flags. Currently, it can be NULL or the following. + /// + /// + /// Flag + /// Meaning + /// + /// + /// DI_MEMORYMAP_WRITE + /// Causes StartDocPrinter to not use AddJob and ScheduleJob for local printing. + /// + /// + /// + public uint dwFlags; + } + + /// + /// The DOCINFO structure contains the input and output file names and other information used by the StartDoc function. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-docinfoa typedef struct _DOCINFOA { int cbSize; LPCSTR + // lpszDocName; LPCSTR lpszOutput; LPCSTR lpszDatatype; DWORD fwType; } DOCINFOA, *LPDOCINFOA; + [PInvokeData("wingdi.h", MSDNShortId = "329bf0d9-399b-4f64-a029-361ef7558aeb")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct DOCINFO + { + /// The size, in bytes, of the structure. + public int cbSize; + + /// Pointer to a null-terminated string that specifies the name of the document. + [MarshalAs(UnmanagedType.LPTStr)] + public string lpszDocName; + + /// + /// Pointer to a null-terminated string that specifies the name of an output file. If this pointer is NULL, the output + /// will be sent to the device identified by the device context handle that was passed to the StartDoc function. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string lpszOutput; + + /// + /// Pointer to a null-terminated string that specifies the type of data used to record the print job. The legal values for this + /// member can be found by calling EnumPrintProcessorDatatypes and can include such values as raw, emf, or XPS_PASS. This member + /// can be NULL. Note that the requested data type might be ignored. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string lpszDatatype; + + /// + /// Specifies additional information about the print job. This member must be zero or one of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// DI_APPBANDING + /// Applications that use banding should set this flag for optimal performance during printing. + /// + /// + /// DI_ROPS_READ_DESTINATION + /// The application will use raster operations that involve reading from the destination surface. + /// + /// + /// + public DI fwType; + } + + /// The DRIVER_INFO_1 structure identifies a printer driver. + // https://docs.microsoft.com/en-us/windows/win32/printdocs/driver-info-1 typedef struct _DRIVER_INFO_1 { LPTSTR pName; } + // DRIVER_INFO_1, *PDRIVER_INFO_1; + [PInvokeData("winspool.h", MSDNShortId = "9435192b-3eba-4937-8cd3-bff4e9eb84d3")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct DRIVER_INFO_1 + { + /// Pointer to a null-terminated string that specifies the name of a printer driver. + [MarshalAs(UnmanagedType.LPTStr)] + public string pName; + } + + /// + /// The DRIVER_INFO_2 structure identifies a printer driver, the driver version number, the environment for which the driver + /// was written, the name of the file in which the driver is stored, and so on. + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/driver-info-2 typedef struct _DRIVER_INFO_2 { DWORD cVersion; LPTSTR + // pName; LPTSTR pEnvironment; LPTSTR pDriverPath; LPTSTR pDataFile; LPTSTR pConfigFile; } DRIVER_INFO_2, *PDRIVER_INFO_2; + [PInvokeData("winspool.h", MSDNShortId = "cca1227d-69b9-44df-8dac-384c2f8843ae")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct DRIVER_INFO_2 + { + /// The operating system version for which the driver was written. The supported value is 3. + public uint cVersion; + + /// A pointer to a null-terminated string that specifies the name of the driver (for example, "QMS 810"). + [MarshalAs(UnmanagedType.LPTStr)] + public string pName; + + /// + /// A pointer to a null-terminated string that specifies the environment for which the driver was written (for example, Windows + /// x86, Windows IA64, and Windows x64). + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pEnvironment; + + /// + /// A pointer to null-terminated string that specifies a file name or full path and file name for the file that contains the + /// device driver (for example, "c:\drivers\pscript.dll"). + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pDriverPath; + + /// + /// A pointer to a null-terminated string that specifies a file name or a full path and file name for the file that contains + /// driver data (for example, "c:\drivers\Qms810.ppd"). + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pDataFile; + + /// + /// A pointer to a null-terminated string that specifies a file name or a full path and file name for the device-driver's + /// configuration .dll (for example, "c:\drivers\Pscrptui.dll"). + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pConfigFile; + } + + /// The DRIVER_INFO_3 structure contains printer driver information. + // https://docs.microsoft.com/en-us/windows/win32/printdocs/driver-info-3 typedef struct _DRIVER_INFO_3 { DWORD cVersion; LPTSTR + // pName; LPTSTR pEnvironment; LPTSTR pDriverPath; LPTSTR pDataFile; LPTSTR pConfigFile; LPTSTR pHelpFile; LPTSTR pDependentFiles; + // LPTSTR pMonitorName; LPTSTR pDefaultDataType; } DRIVER_INFO_3, *PDRIVER_INFO_3; + [PInvokeData("winspool.h", MSDNShortId = "ccf87319-0bcf-4f71-8de3-0190459d2b0e")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct DRIVER_INFO_3 + { + /// + /// The operating system version for which the driver was written. The supported values are 3 and 4, which represent the V3 and + /// V4 drivers, respectively. + /// + public uint cVersion; + + /// A pointer to a null-terminated string that specifies the name of the driver (for example, "QMS 810"). + [MarshalAs(UnmanagedType.LPTStr)] + public string pName; + + /// + /// A pointer to a null-terminated string that specifies the environment for which the driver was written (for example, Windows + /// x86, Windows IA64, and Windows x64). + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pEnvironment; + + /// + /// A pointer to a null-terminated string that specifies a file name or full path and file name for the file that contains the + /// device driver (for example, "C:\DRIVERS\Pscript.dll"). + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pDriverPath; + + /// + /// A pointer to a null-terminated string that specifies a file name or a full path and file name for the file that contains + /// driver data (for example, "C:\DRIVERS\Qms810.ppd"). + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pDataFile; + + /// + /// A pointer to a null-terminated string that specifies a file name or a full path and file name for the device driver's + /// configuration dynamic-link library (for example, "C:\DRIVERS\Pscrptui.dll"). + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pConfigFile; + + /// + /// A pointer to a null-terminated string that specifies a file name or a full path and file name for the device driver's help file. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pHelpFile; + + /// + /// A pointer to a MultiSZ buffer that contains a sequence of null-terminated strings. Each null-terminated string in the buffer + /// contains the name of a file the driver depends on. The sequence of strings is terminated by an empty, zero-length string. If + /// pDependentFiles is not NULL and does not contain any file names, it will point to a buffer that contains two + /// empty strings. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pDependentFiles; + + /// + /// A pointer to a null-terminated string that specifies a language monitor (for example, "PJL monitor"). This member can be + /// NULL and should be specified only for printers capable of bidirectional communication. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pMonitorName; + + /// A pointer to a null-terminated string that specifies the default data type of the print job (for example, "EMF"). + [MarshalAs(UnmanagedType.LPTStr)] + public string pDefaultDataType; + } + + /// The DRIVER_INFO_4 structure contains printer driver information. + // https://docs.microsoft.com/en-us/windows/win32/printdocs/driver-info-4 typedef struct _DRIVER_INFO_4 { DWORD cVersion; LPTSTR + // pName; LPTSTR pEnvironment; LPTSTR pDriverPath; LPTSTR pDataFile; LPTSTR pConfigFile; LPTSTR pHelpFile; LPTSTR pDependentFiles; + // LPTSTR pMonitorName; LPTSTR pDefaultDataType; LPTSTR pszzPreviousNames; } DRIVER_INFO_4, *PDRIVER_INFO_4; + [PInvokeData("winspool.h", MSDNShortId = "63000de6-74e7-4427-98d7-7bbd2dd61080")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct DRIVER_INFO_4 + { + /// The operating system version for which the driver was written. The supported value is 3. + public uint cVersion; + + /// Pointer to a null-terminated string that specifies the name of the driver (for example, "QMS 810"). + [MarshalAs(UnmanagedType.LPTStr)] + public string pName; + + /// + /// Pointer to a null-terminated string that specifies the environment for which the driver was written (for example, Windows + /// x86, Windows IA64, and Windows x64). + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pEnvironment; + + /// + /// Pointer to a null-terminated string that specifies a file name or full path and file name for the file that contains the + /// device driver (for example, C:\DRIVERS\Pscript.dll). + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pDriverPath; + + /// + /// Pointer to a null-terminated string that specifies a file name or a full path and file name for the file that contains + /// driver data (for example, C:\DRIVERS\Qms810.ppd). + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pDataFile; + + /// + /// Pointer to a null-terminated string that specifies a file name or a full path and file name for the device driver's + /// configuration dynamic-link library (for example, C:\DRIVERS\Pscrptui.dll). + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pConfigFile; + + /// + /// Pointer to a null-terminated string that specifies a file name or a full path and file name for the device driver's help file. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pHelpFile; + + /// + /// A pointer to a MultiSZ buffer that contains a sequence of null-terminated strings. Each null-terminated string in the buffer + /// contains the name of a file the driver depends on. The sequence of strings is terminated by an empty, zero-length string. If + /// pDependentFiles is not NULL and does not contain any file names, it will point to a buffer that contains two + /// empty strings. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pDependentFiles; + + /// + /// A pointer to a null-terminated string that specifies a language monitor (for example, PJL monitor). This member can be + /// NULL and should be specified only for printers capable of bidirectional communication. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pMonitorName; + + /// A pointer to a null-terminated string that specifies the default data type of the print job (for example, EMF). + [MarshalAs(UnmanagedType.LPTStr)] + public string pDefaultDataType; + + /// + /// A pointer to a null-terminated string that specifies previous printer driver names that are compatible with this driver. For + /// example, OldName1\0OldName2\0\0. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pszzPreviousNames; + } + + /// The DRIVER_INFO_5 structure contains printer driver information. + // https://docs.microsoft.com/en-us/windows/win32/printdocs/driver-info-5 typedef struct _DRIVER_INFO_5 { DWORD cVersion; LPTSTR + // pName; LPTSTR pEnvironment; LPTSTR pDriverPath; LPTSTR pDataFile; LPTSTR pConfigFile; DWORD dwDriverAttributes; DWORD + // dwConfigVersion; DWORD dwDriverVersion; } DRIVER_INFO_5, *PDRIVER_INFO_5; + [PInvokeData("winspool.h", MSDNShortId = "6fb63a9f-5227-46a3-97dc-8de1968e9d63")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct DRIVER_INFO_5 + { + /// The operating system version for which the driver was written. The supported value is 3. + public uint cVersion; + + /// Pointer to a null-terminated string that specifies the name of the driver (for example, QMS 810). + [MarshalAs(UnmanagedType.LPTStr)] + public string pName; + + /// + /// Pointer to a null-terminated string that specifies the environment for which the driver was written (for example, Windows + /// x86, Windows IA64, and Windows x64). + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pEnvironment; + + /// + /// Pointer to a null-terminated string that specifies a file name or a full path and file name for the file that contains the + /// device driver (for example, C:\DRIVERS\Pscript.dll). + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pDriverPath; + + /// + /// Pointer to a null-terminated string that specifies a file name or a full path and file name for the file that contains + /// driver data (for example, C:\DRIVERS\Qms810.ppd). + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pDataFile; + + /// + /// Pointer to a null-terminated string that specifies a file name or a full path and file name for the device driver's + /// configuration dynamic-link library (for example, C:\DRIVERS\Pscrptui.dll). + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pConfigFile; + + /// Driver attributes, like UMPD/KMPD. + public uint dwDriverAttributes; + + /// + /// Number of times the configuration file for this driver has been upgraded or downgraded since the last spooler restart. + /// + public uint dwConfigVersion; + + /// Number of times the driver file for this driver has been upgraded or downgraded since the last spooler restart. + public uint dwDriverVersion; + } + + /// The DRIVER_INFO_6 structure contains printer driver information. + /// + /// The strings for these members are contained in the .inf file that is used to add the driver. + /// + /// If you call AddPrinterDriver or AddPrinterDriverEx with Level not equal to 6, and then you call + /// GetPrinterDriver or EnumPrinterDrivers with Level equal to 6, the DRIVER_INFO_6 structure is returned with + /// pszMfgName, pszOEMUrl, pszHardwareID, and pszProvider set to NULL, dwlDriverVersion + /// set to 0, and ftDriverDate set to (0,0). + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/driver-info-6 typedef struct _DRIVER_INFO_6 { DWORD cVersion; LPTSTR + // pName; LPTSTR pEnvironment; LPTSTR pDriverPath; LPTSTR pDataFile; LPTSTR pConfigFile; LPTSTR pHelpFile; LPTSTR pDependentFiles; + // LPTSTR pMonitorName; LPTSTR pDefaultDataType; LPTSTR pszzPreviousNames; FILETIME ftDriverDate; DWORDLONG dwlDriverVersion; LPTSTR + // pszMfgName; LPTSTR pszOEMUrl; LPTSTR pszHardwareID; LPTSTR pszProvider; } DRIVER_INFO_6, *PDRIVER_INFO_6, *LPDRIVER_INFO_6; + [PInvokeData("winspool.h", MSDNShortId = "9771cbb5-caaa-4b7d-9a96-d24234440bac")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct DRIVER_INFO_6 + { + /// The operating system version for which the driver was written. The supported value is 3. + public uint cVersion; + + /// Pointer to a null-terminated string that specifies the name of the driver (for example, QMS 810). + [MarshalAs(UnmanagedType.LPTStr)] + public string pName; + + /// + /// Pointer to a null-terminated string that specifies the environment for which the driver was written (for example, Windows NT + /// x86, Windows IA64, and Windows x64. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pEnvironment; + + /// + /// Pointer to a null-terminated string that specifies a file name or a full path and file name for the file that contains the + /// device driver (for example, C:\DRIVERS\Pscript.dll). + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pDriverPath; + + /// + /// Pointer to a null-terminated string that specifies a file name or a full path and file name for the file that contains + /// driver data (for example, C:\DRIVERS\Qms810.ppd). + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pDataFile; + + /// + /// Pointer to a null-terminated string that specifies a file name or a full path and file name for the device driver's + /// configuration dynamic-link library (for example, C:\DRIVERS\Pscrptui.dll). + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pConfigFile; + + /// + /// Pointer to a null-terminated string that specifies a file name or a full path and file name for the device driver's help + /// file (for example, C:\DRIVERS\Pscrptui.hlp). + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pHelpFile; + + /// + /// A pointer to a MultiSZ buffer that contains a sequence of null-terminated strings. Each null-terminated string in the buffer + /// contains the name of a file the driver depends on. The sequence of strings is terminated by an empty, zero-length string. If + /// pDependentFiles is not NULL and does not contain any file names, it will point to a buffer that contains two + /// empty strings. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pDependentFiles; + + /// + /// A pointer to a null-terminated string that specifies a language monitor (for example, "PJL monitor"). This member can be + /// NULL and should be specified only for printers capable of bidirectional communication. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pMonitorName; + + /// A pointer to a null-terminated string that specifies the default data type of the print job (for example, "EMF"). + [MarshalAs(UnmanagedType.LPTStr)] + public string pDefaultDataType; + + /// + /// A pointer to a null-terminated string that specifies previous printer driver names that are compatible with this driver. For + /// example, OldName1\0OldName2\0\0. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pszzPreviousNames; + + /// The date of the driver package, as coded in the driver files. + public FILETIME ftDriverDate; + + /// Version number of the driver. This comes out of the version structure of the driver. + public ulong dwlDriverVersion; + + /// Pointer to a null-terminated string that specifies the manufacturer's name. + [MarshalAs(UnmanagedType.LPTStr)] + public string pszMfgName; + + /// Pointer to a null-terminated string that specifies the URL for the manufacturer. + [MarshalAs(UnmanagedType.LPTStr)] + public string pszOEMUrl; + + /// Pointer to a null-terminated string that specifies the hardware ID for the printer driver. + [MarshalAs(UnmanagedType.LPTStr)] + public string pszHardwareID; + + /// + /// Pointer to a null-terminated string that specifies the provider of the printer driver (for example, "Microsoft Windows 2000") + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pszProvider; + } + + /// Contains printer driver information. + /// The strings for these members are contained in the .inf file that is used to add the driver. + // https://docs.microsoft.com/en-us/windows/win32/printdocs/driver-info-8 typedef struct _DRIVER_INFO_8 { DWORD cVersion; LPTSTR + // pName; LPTSTR pEnvironment; LPTSTR pDriverPath; LPTSTR pDataFile; LPTSTR pConfigFile; LPTSTR pHelpFile; LPTSTR pDependentFiles; + // LPTSTR pMonitorName; LPTSTR pDefaultDataType; LPTSTR pszzPreviousNames; FILETIME ftDriverDate; DWORDLONG dwlDriverVersion; LPTSTR + // pszMfgName; LPTSTR pszOEMUrl; LPTSTR pszHardwareID; LPTSTR pszProvider; LPTSTR pszPrintProcessor; LPTSTR pszVendorSetup; LPTSTR + // pszzColorProfiles; LPTSTR pszInfPath; DWORD dwPrinterDriverAttributes; LPTSTR pszzCoreDriverDependencies; FILETIME + // ftMinInboxDriverVerDate; DWORDLONG dwlMinInboxDriverVerVersion; } DRIVER_INFO_8, *PDRIVER_INFO_8, *LPDRIVER_INFO_8; + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct DRIVER_INFO_8 + { + /// The operating system version for which the driver was written. The supported value is 3. + public uint cVersion; + + /// A pointer to a null-terminated string that specifies the name of the driver (for example, QMS 810). + [MarshalAs(UnmanagedType.LPTStr)] + public string pName; + + /// + /// A pointer to a null-terminated string that specifies the environment for which the driver was written (for example, Windows + /// x86, Windows IA64, and Windows x64. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pEnvironment; + + /// + /// A pointer to a null-terminated string that specifies a file name or a full path and file name for the file that contains the + /// device driver (for example, C:\DRIVERS\Pscript.dll). + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pDriverPath; + + /// + /// A pointer to a null-terminated string that specifies a file name or a full path and file name for the file that contains + /// driver data (for example, C:\DRIVERS\Qms810.ppd). + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pDataFile; + + /// + /// A pointer to a null-terminated string that specifies a file name or a full path and file name for the device driver's + /// configuration dynamic-link library (for example, C:\DRIVERS\Pscrptui.dll). + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pConfigFile; + + /// + /// A pointer to a null-terminated string that specifies a file name or a full path and file name for the device driver's help + /// file (for example, C:\DRIVERS\Pscrptui.hlp). + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pHelpFile; + + /// + /// A pointer to a MultiSZ buffer that contains a sequence of null-terminated strings. Each null-terminated string in the buffer + /// contains the name of a file the driver depends on. The sequence of strings is terminated by an empty, zero-length string. If + /// pDependentFiles is not NULL and does not contain any file names, it will point to a buffer that contains two + /// empty strings. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pDependentFiles; + + /// + /// A pointer to a null-terminated string that specifies a language monitor (for example, "PJL monitor"). This member can be + /// NULL and should be specified only for printers capable of bidirectional communication. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pMonitorName; + + /// A pointer to a null-terminated string that specifies the default data type of the print job (for example, "EMF"). + [MarshalAs(UnmanagedType.LPTStr)] + public string pDefaultDataType; + + /// + /// A pointer to a null-terminated string that specifies previous printer driver names that are compatible with this driver. For + /// example, OldName1\0OldName2\0\0. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pszzPreviousNames; + + /// The date of the driver package, as coded in the driver files. + public FILETIME ftDriverDate; + + /// The version number of the driver. This comes from the version structure of the driver. + public ulong dwlDriverVersion; + + /// A pointer to a null-terminated string that specifies the manufacturer's name. + [MarshalAs(UnmanagedType.LPTStr)] + public string pszMfgName; + + /// A pointer to a null-terminated string that specifies the URL for the manufacturer. + [MarshalAs(UnmanagedType.LPTStr)] + public string pszOEMUrl; + + /// A pointer to a null-terminated string that specifies the hardware ID for the printer driver. + [MarshalAs(UnmanagedType.LPTStr)] + public string pszHardwareID; + + /// + /// A pointer to a null-terminated string that specifies the provider of the printer driver (for example, "Microsoft Windows 2000"). + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pszProvider; + + /// A pointer to a null-terminated string that specifies the print processor (for example, "WinPrint"). + [MarshalAs(UnmanagedType.LPTStr)] + public string pszPrintProcessor; + + /// A pointer to a null-terminated string that specifies the vendor's driver setup DLL and entry point. + [MarshalAs(UnmanagedType.LPTStr)] + public string pszVendorSetup; + + /// A pointer to a null-terminated string that specifies the color profiles associated with the driver. + [MarshalAs(UnmanagedType.LPTStr)] + public string pszzColorProfiles; + + /// + /// A pointer to a null-terminated string that specifies the path to the driver's .inf file in the driver store. (See Remarks.) + /// This must be NULL if the DRIVER_INFO_8 is being passed to AddPrinterDriver or AddPrinterDriverEx. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pszInfPath; + + /// + /// + /// Attribute flags for printer drivers. This must be 0 if the DRIVER_INFO_8 is being passed to AddPrinterDriver or + /// AddPrinterDriverEx. Otherwise, it can be any combination of the following flags: + /// + /// + /// + /// Flag name/value + /// Meaning + /// Minimum OS + /// + /// + /// PRINTER_DRIVER_PACKAGE_AWARE 0x00000001 + /// The printer driver is part of a driver package. + /// Windows Vista + /// + /// + /// PRINTER_DRIVER_XPS 0x00000002 + /// + /// The printer driver supports the Microsoft XPS format described in the XML Paper Specification: Overview, and also in Product + /// Behavior, section <27>. + /// + /// Windows 8 Windows Server 2012 + /// + /// + /// PRINTER_DRIVER_SANDBOX_ENABLED 0x00000004 + /// + /// The printer driver is compatible with printer driver isolation. For more information, see Product Behavior, section <28>. + /// + /// Windows 7 Windows Server 2008 R2 + /// + /// + /// PRINTER_DRIVER_CLASS 0x00000008 + /// The printer driver is a class printer driver. + /// Windows 8 Windows Server 2012 + /// + /// + /// PRINTER_DRIVER_DERIVED 0x00000010 + /// The printer driver is a derived printer driver. + /// Windows 8 Windows Server 2012 + /// + /// + /// PRINTER_DRIVER_NOT_SHAREABLE 0x00000020 + /// Printers using this printer driver cannot be shared. + /// Windows 8 Windows Server 2012 + /// + /// + /// PRINTER_DRIVER_CATEGORY_FAX 0x00000040 + /// The printer driver is intended for use with fax printers. + /// Windows 8 Windows Server 2012 + /// + /// + /// PRINTER_DRIVER_CATEGORY_FILE 0x00000080 + /// The printer driver is intended for use with file printers. + /// Windows 8 Windows Server 2012 + /// + /// + /// PRINTER_DRIVER_CATEGORY_VIRTUAL 0x00000100 + /// The printer driver is intended for use with virtual printers. + /// Windows 8 Windows Server 2012 + /// + /// + /// PRINTER_DRIVER_CATEGORY_SERVICE 0x00000200 + /// The printer driver is intended for use with service printers. + /// Windows 8 Windows Server 2012 + /// + /// + /// PRINTER_DRIVER_SOFT_RESET_REQUIRED 0x00000400 + /// + /// Printers that use this printer driver should follow the guidelines outlined in the USB Device Class Definition. For more + /// information, see Product Behavior, section <36> + /// + /// Windows 8 Windows Server 2012 + /// + /// + /// + public PrinterDriverAttributes dwPrinterDriverAttributes; + + /// + /// A pointer to a null-terminated multi-string that specifies all the core printer drivers that the driver depends on. This + /// must be NULL if the DRIVER_INFO_8 is being passed to AddPrinterDriver or AddPrinterDriverEx. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pszzCoreDriverDependencies; + + /// The earliest allowed date of any drivers that shipped with Windows and on which this driver depends. + public FILETIME ftMinInboxDriverVerDate; + + /// The earliest allowed version of any drivers that shipped with Windows and on which this driver depends. + public ulong dwlMinInboxDriverVerVersion; + } + + /// + /// The FORM_INFO_1 structure contains information about a print form. The information includes the print form's origin, its + /// name, its dimensions, and the dimensions of its printable area. + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/form-info-1 typedef struct _FORM_INFO_1 { DWORD Flags; LPTSTR pName; + // SIZEL Size; RECTL ImageableArea; } FORM_INFO_1, *PFORM_INFO_1; + [PInvokeData("winspool.h", MSDNShortId = "1c42ea6c-82cf-463c-bc67-44a8d8c4a1e7")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct FORM_INFO_1 + { + /// + /// The form properties. The following values are defined. + /// + /// + /// Value + /// Meaning + /// + /// + /// FORM_USER + /// If this bit flag is set, the form has been defined by the user. Forms with this flag set are defined in the registry. + /// + /// + /// FORM_BUILTIN + /// + /// If this bit-flag is set, the form is part of the spooler. Form definitions with this flag set do not appear in the registry. + /// + /// + /// + /// FORM_PRINTER + /// If this bit flag is set, the form is associated with a certain printer, and its definition appears in the registry. + /// + /// + /// + public FormFlags Flags; + + /// Pointer to a null-terminated string that specifies the name of the form. The form name cannot exceed 31 characters. + [MarshalAs(UnmanagedType.LPTStr)] + public string pName; + + /// The width and height, in thousandths of millimeters, of the form. + public SIZE Size; + + /// The width and height, in thousandths of millimeters, of the form. + public RECT ImageableArea; + } + + /// Contains information about a localizable print form. + /// + /// On a call to AddForm or SetForm: + /// + /// + /// + /// If StringType is STRING_NONE, both pMuiDll and pDisplayName must be NULL and both + /// dwResourceId and wLangId must be 0. + /// + /// + /// + /// If StringType is STRING_MUIDLL, pDisplayName must be NULL and wLangId must be 0. + /// + /// + /// If StringType is STRING_LANGPAIR, pMuiDll must be NULL and dwResourceId must be 0. + /// + /// + /// For a FORM_INFO_2 returned by a call to GetForm or EnumForms: + /// + /// + /// + /// If StringType is both STRING_MUIDLL and STRING_LANGPAIR, pMuiDll, pDisplayName, dwResourceId, and + /// wLangId will all have valid values. + /// + /// + /// + /// + /// If StringType is STRING_MUIDLL only, pMuiDll and dwResourceId will have valid values. pDisplayName + /// will be NULL and wLangId will be 0. + /// + /// + /// + /// + /// If StringType is STRING_LANGPAIR only, pDisplayName and wLangId will have valid values. pMuiDll will + /// be NULL and dwResourceId will be 0. + /// + /// + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/form-info-2 typedef struct _FORM_INFO_2 { DWORD Flags; LPTSTR pName; + // SIZEL Size; RECTL ImageableArea; LPCSTR pKeyword; DWORD StringType; LPCTSTR pMuiDll; DWORD dwResourceId; LPCTSTR pDisplayName; + // LANGID wLangId; } FORM_INFO_2, *PFORM_INFO_2; + [PInvokeData("winspool.h", MSDNShortId = "5cc11a77-2b9d-44a4-88de-6ed0b7460bc8")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct FORM_INFO_2 + { + /// + /// + /// The form properties. The following values are defined, but only one can be set. When the FORM_INFO_2 is returned by + /// GetForm or EnumForms, Flags is set to the current value in the forms database. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// FORM_USER + /// If this bit flag is set, the form has been defined by the user. Forms with this flag set are defined in the registry. + /// + /// + /// FORM_BUILTIN + /// + /// If this bit-flag is set, the form is part of the spooler. Form definitions with this flag set do not appear in the registry. + /// Built-in forms cannot be modified, so this flag should not be set when the structure is passed to AddForm or SetForm. + /// + /// + /// + /// FORM_PRINTER + /// If this bit flag is set, the form is associated with a certain printer, and its definition appears in the registry. + /// + /// + /// + public FormFlags Flags; + + /// A pointer to a null-terminated string that specifies the name of the form. The form name cannot exceed 31 characters. + [MarshalAs(UnmanagedType.LPTStr)] + public string pName; + + /// The width and height of the form in thousandths of millimeters. + public SIZE Size; + + /// The width and height, in thousandths of millimeters, of the area of the page on which the printer can print. + public RECT ImageableArea; + + /// + /// A pointer to a non-localizable string identifier of the form. When passed to AddForm or SetForm, this gives + /// the caller a means of identifying the form in all locales. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pKeyword; + + /// + /// + /// Specifies how a localized display name for the form is obtained at runtime. The following values are defined. Only one can + /// be set in any given call to AddForm or SetForm. Both STRING_MUIDLL and STRING_LANGPAIR can be set in the + /// FORM_INFO_2 (s) returned by GetForm or EnumForms. See Remarks. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// STRING_NONE + /// There is no localized display name. + /// + /// + /// STRING_MUIDLL + /// + /// The display name is extracted from the Multilingual User Interface localized resources DLL specified in pMuiDll. The ID is + /// in the dwResourceId member. + /// + /// + /// + /// STRING_LANGPAIR + /// The display name and language ID are provided directly by pDisplayName and the language is specified by wLangId. + /// + /// + /// + public FormStringType StringType; + + /// The Multilingual User Interface localized resource DLL that contains the localized display name. + [MarshalAs(UnmanagedType.LPTStr)] + public string pMuiDll; + + /// The resource ID of the form's display name in pMuiDll. + public uint dwResourceId; + + /// The form's display name in the language specified by wLangId. + [MarshalAs(UnmanagedType.LPTStr)] + public string pDisplayName; + + /// The language of the pDisplayName. + public ushort wLangId; + } + + /// Provides a handle to a printer. + [StructLayout(LayoutKind.Sequential)] + public struct HPRINTER : IHandle + { + private readonly IntPtr handle; + + /// Initializes a new instance of the struct. + /// An object that represents the pre-existing handle to use. + public HPRINTER(IntPtr preexistingHandle) => handle = preexistingHandle; + + /// Returns an invalid handle by instantiating a object with . + public static HPRINTER NULL => new HPRINTER(IntPtr.Zero); + + /// Gets a value indicating whether this instance is a null handle. + public bool IsNull => handle == IntPtr.Zero; + + /// Performs an explicit conversion from to . + /// The handle. + /// The result of the conversion. + public static explicit operator IntPtr(HPRINTER h) => h.handle; + + /// Performs an implicit conversion from to . + /// The pointer to a handle. + /// The result of the conversion. + public static implicit operator HPRINTER(IntPtr h) => new HPRINTER(h); + + /// Implements the operator !=. + /// The first handle. + /// The second handle. + /// The result of the operator. + public static bool operator !=(HPRINTER h1, HPRINTER h2) => !(h1 == h2); + + /// Implements the operator ==. + /// The first handle. + /// The second handle. + /// The result of the operator. + public static bool operator ==(HPRINTER h1, HPRINTER h2) => h1.Equals(h2); + + /// + public override bool Equals(object obj) => obj is HPRINTER h ? handle == h.handle : false; + + /// + public override int GetHashCode() => handle.GetHashCode(); + + /// + public IntPtr DangerousGetHandle() => handle; + } + + /// Provides a handle to a printer change notification. + [StructLayout(LayoutKind.Sequential)] + public struct HPRINTERCHANGENOTIFICATION : IHandle + { + private IntPtr handle; + + /// Initializes a new instance of the struct. + /// An object that represents the pre-existing handle to use. + public HPRINTERCHANGENOTIFICATION(IntPtr preexistingHandle) => handle = preexistingHandle; + + /// Returns an invalid handle by instantiating a object with . + public static HPRINTERCHANGENOTIFICATION NULL => new HPRINTERCHANGENOTIFICATION(IntPtr.Zero); + + /// Gets a value indicating whether this instance is a null handle. + public bool IsNull => handle == IntPtr.Zero; + + /// Performs an explicit conversion from to . + /// The handle. + /// The result of the conversion. + public static explicit operator IntPtr(HPRINTERCHANGENOTIFICATION h) => h.handle; + + /// Performs an implicit conversion from to . + /// The pointer to a handle. + /// The result of the conversion. + public static implicit operator HPRINTERCHANGENOTIFICATION(IntPtr h) => new HPRINTERCHANGENOTIFICATION(h); + + /// Implements the operator !=. + /// The first handle. + /// The second handle. + /// The result of the operator. + public static bool operator !=(HPRINTERCHANGENOTIFICATION h1, HPRINTERCHANGENOTIFICATION h2) => !(h1 == h2); + + /// Implements the operator ==. + /// The first handle. + /// The second handle. + /// The result of the operator. + public static bool operator ==(HPRINTERCHANGENOTIFICATION h1, HPRINTERCHANGENOTIFICATION h2) => h1.Equals(h2); + + /// + public override bool Equals(object obj) => obj is HPRINTERCHANGENOTIFICATION h ? handle == h.handle : false; + + /// + public override int GetHashCode() => handle.GetHashCode(); + + /// + public IntPtr DangerousGetHandle() => handle; + } + + /// Provides a handle to a spool file. + [StructLayout(LayoutKind.Sequential)] + public struct HSPOOLFILE : IHandle + { + private readonly IntPtr handle; + + /// Initializes a new instance of the struct. + /// An object that represents the pre-existing handle to use. + public HSPOOLFILE(IntPtr preexistingHandle) => handle = preexistingHandle; + + /// Returns an invalid handle by instantiating a object with . + public static HSPOOLFILE NULL => new HSPOOLFILE(IntPtr.Zero); + + /// Gets a value indicating whether this instance is a null handle. + public bool IsNull => handle == IntPtr.Zero; + + /// Performs an explicit conversion from to . + /// The handle. + /// The result of the conversion. + public static explicit operator IntPtr(HSPOOLFILE h) => h.handle; + + /// Performs an implicit conversion from to . + /// The pointer to a handle. + /// The result of the conversion. + public static implicit operator HSPOOLFILE(IntPtr h) => new HSPOOLFILE(h); + + /// Implements the operator !=. + /// The first handle. + /// The second handle. + /// The result of the operator. + public static bool operator !=(HSPOOLFILE h1, HSPOOLFILE h2) => !(h1 == h2); + + /// Implements the operator ==. + /// The first handle. + /// The second handle. + /// The result of the operator. + public static bool operator ==(HSPOOLFILE h1, HSPOOLFILE h2) => h1.Equals(h2); + + /// + public override bool Equals(object obj) => obj is HSPOOLFILE h ? handle == h.handle : false; + + /// + public override int GetHashCode() => handle.GetHashCode(); + + /// + public IntPtr DangerousGetHandle() => handle; + } + + /// + /// The JOB_INFO_1 structure specifies print-job information such as the job-identifier value, the name of the printer for + /// which the job is spooled, the name of the machine that created the print job, the name of the user that owns the print job, and + /// so on. + /// + /// + /// Port monitors that do not support TrueEndOfJob will set the job as JOB_STATUS_PRINTED right after the job is submitted to the printer. + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/job-info-1 typedef struct _JOB_INFO_1 { DWORD JobId; LPTSTR + // pPrinterName; LPTSTR pMachineName; LPTSTR pUserName; LPTSTR pDocument; LPTSTR pDatatype; LPTSTR pStatus; DWORD Status; DWORD + // Priority; DWORD Position; DWORD TotalPages; DWORD PagesPrinted; SYSTEMTIME Submitted; } JOB_INFO_1, *PJOB_INFO_1; + [PInvokeData("winspool.h", MSDNShortId = "d42ada89-6bc7-4006-81d9-dbcc0347edd3")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct JOB_INFO_1 + { + /// A job identifier. + public uint JobId; + + /// A pointer to a null-terminated string that specifies the name of the printer for which the job is spooled. + [MarshalAs(UnmanagedType.LPTStr)] + public string pPrinterName; + + /// A pointer to a null-terminated string that specifies the name of the machine that created the print job. + [MarshalAs(UnmanagedType.LPTStr)] + public string pMachineName; + + /// A pointer to a null-terminated string that specifies the name of the user that owns the print job. + [MarshalAs(UnmanagedType.LPTStr)] + public string pUserName; + + /// A pointer to a null-terminated string that specifies the name of the print job (for example, "MS-WORD: Review.doc"). + [MarshalAs(UnmanagedType.LPTStr)] + public string pDocument; + + /// A pointer to a null-terminated string that specifies the type of data used to record the print job. + [MarshalAs(UnmanagedType.LPTStr)] + public string pDatatype; + + /// + /// A pointer to a null-terminated string that specifies the status of the print job. This member should be checked prior to + /// Status and, if pStatus is NULL, the status is defined by the contents of the Status member. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pStatus; + + /// + /// + /// The job status. The value of this member can be zero or a combination of one or more of the following values. A value of + /// zero indicates that the print queue was paused after the document finished spooling. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// JOB_STATUS_BLOCKED_DEVQ + /// The driver cannot print the job. + /// + /// + /// JOB_STATUS_COMPLETE + /// Windows XP and later: Job is sent to the printer, but the job may not be printed yet. See Remarks for more information. + /// + /// + /// JOB_STATUS_DELETED + /// Job has been deleted. + /// + /// + /// JOB_STATUS_DELETING + /// Job is being deleted. + /// + /// + /// JOB_STATUS_ERROR + /// An error is associated with the job. + /// + /// + /// JOB_STATUS_OFFLINE + /// Printer is offline. + /// + /// + /// JOB_STATUS_PAPEROUT + /// Printer is out of paper. + /// + /// + /// JOB_STATUS_PAUSED + /// Job is paused. + /// + /// + /// JOB_STATUS_PRINTED + /// Job has printed. + /// + /// + /// JOB_STATUS_PRINTING + /// Job is printing. + /// + /// + /// JOB_STATUS_RESTART + /// Job has been restarted. + /// + /// + /// JOB_STATUS_RETAINED + /// + /// Windows Vista and later: Job has been retained in the print queue and cannot be deleted. This can be caused by the + /// following: 1) The job was manually retained by a call to SetJob and the spooler is waiting for the job to be released. 2) + /// The job has not finished printing and must finish printing before it can be automatically deleted. See SetJob for more + /// information about print job commands. + /// + /// + /// + /// JOB_STATUS_SPOOLING + /// Job is spooling. + /// + /// + /// JOB_STATUS_USER_INTERVENTION + /// Printer has an error that requires the user to do something. + /// + /// + /// + public JOB_STATUS Status; + + /// + /// + /// The job priority. This member can be one of the following values or in the range between 1 through 99 (MIN_PRIORITY through MAX_PRIORITY). + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// MIN_PRIORITY + /// Minimum priority. + /// + /// + /// MAX_PRIORITY + /// Maximum priority. + /// + /// + /// DEF_PRIORITY + /// Default priority. + /// + /// + /// + public JOB_PRIORITY Priority; + + /// The job's position in the print queue. + public uint Position; + + /// + /// The total number of pages that the document contains. This value may be zero if the print job does not contain page + /// delimiting information. + /// + public uint TotalPages; + + /// + /// The number of pages that have printed. This value may be zero if the print job does not contain page delimiting information. + /// + public uint PagesPrinted; + + /// + /// A SYSTEMTIME structure that specifies the time that this document was spooled. + /// + /// This time value is in Universal Time Coordinate (UTC) format. You should convert it to a local time value before displaying + /// it. You can use the FileTimeToLocalFileTime function to perform the conversion. + /// + /// + public SYSTEMTIME Submitted; + } + + /// The JOB_INFO_2 structure describes a full set of values associated with a job. + /// + /// Port monitors that do not support TrueEndOfJob will set the job as JOB_STATUS_PRINTED right after the job is submitted to the printer. + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/job-info-2 typedef struct _JOB_INFO_2 { DWORD JobId; LPTSTR + // pPrinterName; LPTSTR pMachineName; LPTSTR pUserName; LPTSTR pDocument; LPTSTR pNotifyName; LPTSTR pDatatype; LPTSTR + // pPrintProcessor; LPTSTR pParameters; LPTSTR pDriverName; LPDEVMODE pDevMode; LPTSTR pStatus; PSECURITY_DESCRIPTOR + // pSecurityDescriptor; DWORD Status; DWORD Priority; DWORD Position; DWORD StartTime; DWORD UntilTime; DWORD TotalPages; DWORD + // Size; SYSTEMTIME Submitted; DWORD Time; DWORD PagesPrinted; } JOB_INFO_2, *PJOB_INFO_2; + [PInvokeData("winspool.h", MSDNShortId = "0cc61e35-4ac9-47bd-bb0d-ff43854bdee5")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct JOB_INFO_2 + { + /// A job identifier value. + public uint JobId; + + /// A pointer to a null-terminated string that specifies the name of the printer for which the job is spooled. + [MarshalAs(UnmanagedType.LPTStr)] + public string pPrinterName; + + /// A pointer to a null-terminated string that specifies the name of the machine that created the print job. + [MarshalAs(UnmanagedType.LPTStr)] + public string pMachineName; + + /// A pointer to a null-terminated string that specifies the name of the user who owns the print job. + [MarshalAs(UnmanagedType.LPTStr)] + public string pUserName; + + /// A pointer to a null-terminated string that specifies the name of the print job (for example, "MS-WORD: Review.doc"). + [MarshalAs(UnmanagedType.LPTStr)] + public string pDocument; + + /// + /// A pointer to a null-terminated string that specifies the name of the user who should be notified when the job has been + /// printed or when an error occurs while printing the job. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pNotifyName; + + /// A pointer to a null-terminated string that specifies the type of data used to record the print job. + [MarshalAs(UnmanagedType.LPTStr)] + public string pDatatype; + + /// + /// A pointer to a null-terminated string that specifies the name of the print processor that should be used to print the job. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pPrintProcessor; + + /// A pointer to a null-terminated string that specifies print-processor parameters. + [MarshalAs(UnmanagedType.LPTStr)] + public string pParameters; + + /// + /// A pointer to a null-terminated string that specifies the name of the printer driver that should be used to process the print job. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pDriverName; + + /// + /// A pointer to a DEVMODE structure that contains device-initialization and environment data for the printer driver. + /// + public IntPtr pDevMode; + + /// + /// A pointer to a null-terminated string that specifies the status of the print job. This member should be checked prior to + /// Status and, if pStatus is NULL, the status is defined by the contents of the Status member. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pStatus; + + /// + /// The value of this member is NULL. Retrieval and setting of document security descriptors is not supported in this release. + /// + public PSECURITY_DESCRIPTOR pSecurityDescriptor; + + /// + /// The job status. This member can be one or more of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// JOB_STATUS_BLOCKED_DEVQ + /// The driver cannot print the job. + /// + /// + /// JOB_STATUS_DELETED + /// Job has been deleted. + /// + /// + /// JOB_STATUS_DELETING + /// Job is being deleted. + /// + /// + /// JOB_STATUS_ERROR + /// An error is associated with the job. + /// + /// + /// JOB_STATUS_OFFLINE + /// Printer is offline. + /// + /// + /// JOB_STATUS_PAPEROUT + /// Printer is out of paper. + /// + /// + /// JOB_STATUS_PAUSED + /// Job is paused. + /// + /// + /// JOB_STATUS_PRINTED + /// Job has printed. + /// + /// + /// JOB_STATUS_PRINTING + /// Job is printing. + /// + /// + /// JOB_STATUS_RESTART + /// Job has been restarted. + /// + /// + /// JOB_STATUS_SPOOLING + /// Job is spooling. + /// + /// + /// JOB_STATUS_USER_INTERVENTION + /// Printer has an error that requires the user to do something. + /// + /// + /// In Windows XP and later versions of Windows, the following values can also be used: + /// + /// + /// Value + /// Meaning + /// + /// + /// JOB_STATUS_COMPLETE + /// The job is sent to the printer, but may not be printed yet. See Remarks for more information. + /// + /// + /// JOB_STATUS_RETAINED + /// The job has been retained in the print queue following printing. + /// + /// + /// + public JOB_STATUS Status; + + /// + /// + /// The job priority. This member can be one of the following values or in the range between 1 through 99 (MIN_PRIORITY through MAX_PRIORITY). + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// MIN_PRIORITY + /// Minimum priority. + /// + /// + /// MAX_PRIORITY + /// Maximum priority. + /// + /// + /// DEF_PRIORITY + /// Default priority. + /// + /// + /// + public JOB_PRIORITY Priority; + + /// The job's position in the print queue. + public uint Position; + + /// The earliest time that the job can be printed. + public uint StartTime; + + /// The latest time that the job can be printed. + public uint UntilTime; + + /// + /// The number of pages required for the job. This value may be zero if the print job does not contain page delimiting information. + /// + public uint TotalPages; + + /// The size, in bytes, of the job. + public uint Size; + + /// + /// A SYSTEMTIME structure that specifies the time when the job was submitted. + /// + /// This time value is in Universal Time Coordinate (UTC) format. You should convert it to a local time value before displaying + /// it. You can use the FileTimeToLocalFileTime function to perform the conversion. + /// + /// + public SYSTEMTIME Submitted; + + /// The total time, in milliseconds, that has elapsed since the job began printing. + public uint Time; + + /// + /// The number of pages that have printed. This value may be zero if the print job does not contain page delimiting information. + /// + public uint PagesPrinted; + + /// A DEVMODE structure that contains device-initialization and environment data for the printer driver. + public DEVMODE DevMode => pDevMode.ToStructure(); + } + + /// The JOB_INFO_3 structure is used to link together a set of print jobs. + // https://docs.microsoft.com/en-us/windows/win32/printdocs/job-info-3 typedef struct _JOB_INFO_3 { DWORD JobId; DWORD NextJobId; + // DWORD Reserved; } JOB_INFO_3, *PJOB_INFO_3; + [PInvokeData("winspool.h", MSDNShortId = "a110f555-dc33-450c-ae77-ea26f0f69448")] + [StructLayout(LayoutKind.Sequential)] + public struct JOB_INFO_3 + { + /// The print job identifier. + public uint JobId; + + /// The print job identifier for the next print job in the linked set of print jobs. + public uint NextJobId; + + /// This value is reserved for future use. You must set it to zero. + public uint Reserved; + } + + /// + /// Describes a full set of values associated with a job and supports large spool files with sizes expressed with 64 bits. + /// + /// + /// Port monitors that do not support TrueEndOfJob will set the job as JOB_STATUS_PRINTED immediately after the job is submitted to + /// the printer. + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/job-info-4 typedef struct _JOB_INFO_4 { DWORD JobId; LPTSTR + // pPrinterName; LPTSTR pMachineName; LPTSTR pUserName; LPTSTR pDocument; LPTSTR pNotifyName; LPTSTR pDatatype; LPTSTR + // pPrintProcessor; LPTSTR pParameters; LPTSTR pDriverName; LPDEVMODE pDevMode; LPTSTR pStatus; PSECURITY_DESCRIPTOR + // pSecurityDescriptor; DWORD Status; DWORD Priority; DWORD Position; DWORD StartTime; DWORD UntilTime; DWORD TotalPages; DWORD + // Size; SYSTEMTIME Submitted; DWORD Time; DWORD PagesPrinted; LONG SizeHigh; } JOB_INFO_4, *PJOB_INFO_4; + [PInvokeData("winspool.h", MSDNShortId = "90932ae2-ea9e-43bc-9a1d-c68223f6d0ee")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct JOB_INFO_4 + { + /// A job identifier value. + public uint JobId; + + /// A pointer to a null-terminated string that specifies the name of the printer for which the job is spooled. + [MarshalAs(UnmanagedType.LPTStr)] + public string pPrinterName; + + /// A pointer to a null-terminated string that specifies the name of the machine that created the print job. + [MarshalAs(UnmanagedType.LPTStr)] + public string pMachineName; + + /// A pointer to a null-terminated string that specifies the name of the user who owns the print job. + [MarshalAs(UnmanagedType.LPTStr)] + public string pUserName; + + /// A pointer to a null-terminated string that specifies the name of the print job (for example, "MS-WORD: Review.doc"). + [MarshalAs(UnmanagedType.LPTStr)] + public string pDocument; + + /// + /// A pointer to a null-terminated string that specifies the name of the user who should be notified when the job has been + /// printed, or when an error occurs while printing the job. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pNotifyName; + + /// A pointer to a null-terminated string that specifies the type of data used to record the print job. + [MarshalAs(UnmanagedType.LPTStr)] + public string pDatatype; + + /// + /// A pointer to a null-terminated string that specifies the name of the print processor that should be used to print the job. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pPrintProcessor; + + /// A pointer to a null-terminated string that specifies print-processor parameters. + [MarshalAs(UnmanagedType.LPTStr)] + public string pParameters; + + /// + /// A pointer to a null-terminated string that specifies the name of the printer driver that should be used to process the print job. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pDriverName; + + /// + /// A pointer to a DEVMODE structure that contains device-initialization and environment data for the printer driver. + /// + public IntPtr pDevMode; + + /// + /// A pointer to a null-terminated string that specifies the status of the print job. This member should be checked prior to + /// Status and, if pStatus is NULL, the status is defined by the contents of the Status member. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pStatus; + + /// + /// The value of this member is NULL. Retrieval and setting of document security descriptors is not supported in this release. + /// + public PSECURITY_DESCRIPTOR pSecurityDescriptor; + + /// + /// The job status. This member can be one or more of the following values: + /// + /// + /// Value + /// Meaning + /// + /// + /// JOB_STATUS_BLOCKED_DEVQ + /// The driver cannot print the job. + /// + /// + /// JOB_STATUS_DELETED + /// Job has been deleted. + /// + /// + /// JOB_STATUS_DELETING + /// Job is being deleted. + /// + /// + /// JOB_STATUS_ERROR + /// An error is associated with the job. + /// + /// + /// JOB_STATUS_OFFLINE + /// Printer is offline. + /// + /// + /// JOB_STATUS_PAPEROUT + /// Printer is out of paper. + /// + /// + /// JOB_STATUS_PAUSED + /// Job is paused. + /// + /// + /// JOB_STATUS_PRINTED + /// Job has printed. + /// + /// + /// JOB_STATUS_PRINTING + /// Job is printing. + /// + /// + /// JOB_STATUS_RESTART + /// Job has been restarted. + /// + /// + /// JOB_STATUS_SPOOLING + /// Job is spooling. + /// + /// + /// JOB_STATUS_USER_INTERVENTION + /// Printer has an error that requires the user to do something. + /// + /// + /// In Windows XP and later versions of Windows, the following values can also be used: + /// + /// + /// Value + /// Meaning + /// + /// + /// JOB_STATUS_COMPLETE + /// The job is sent to the printer, but may not be printed yet. See Remarks for more information. + /// + /// + /// JOB_STATUS_RETAINED + /// The job has been retained in the print queue following printing. + /// + /// + /// + public JOB_STATUS Status; + + /// + /// + /// The job priority. This member can be one of the following values, or in the range between 1 through 99 (MIN_PRIORITY through MAX_PRIORITY). + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// MIN_PRIORITY + /// Minimum priority. + /// + /// + /// MAX_PRIORITY + /// Maximum priority. + /// + /// + /// DEF_PRIORITY + /// Default priority. + /// + /// + /// + public JOB_PRIORITY Priority; + + /// The job's position in the print queue. + public uint Position; + + /// The earliest time that the job can be printed. + public uint StartTime; + + /// The latest time that the job can be printed. + public uint UntilTime; + + /// + /// The number of pages required for the job. This value may be zero if the print job does not contain page delimiting information. + /// + public uint TotalPages; + + /// The lower four bytes of the size, in bytes, of the job. See also the SizeHigh member below. + public uint Size; + + /// + /// A SYSTEMTIME structure that specifies the time when the job was submitted. + /// + /// This time value is in Universal Time Coordinate (UTC) format. You should convert it to a local time value before displaying + /// it. You can use the FileTimeToLocalFileTime function to perform the conversion. + /// + /// + public SYSTEMTIME Submitted; + + /// The total time, in milliseconds, that has elapsed since the job began printing. + public uint Time; + + /// + /// The number of pages that have printed. This value may be zero if the print job does not contain page delimiting information. + /// + public uint PagesPrinted; + + /// The higher four bytes of the size, in bytes, of the job. See also the Size member above. + public int SizeHigh; + + /// A DEVMODE structure that contains device-initialization and environment data for the printer driver. + public DEVMODE DevMode => pDevMode.ToStructure(); + } + + /// The MONITOR_INFO_1 structure identifies an installed monitor. + // https://docs.microsoft.com/en-us/windows/win32/printdocs/monitor-info-1 typedef struct _MONITOR_INFO_1 { LPTSTR pName; } + // MONITOR_INFO_1, *PMONITOR_INFO_1; + [PInvokeData("winspool.h", MSDNShortId = "7a4660bd-5df8-49dd-92f6-9574f451f10d")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct MONITOR_INFO_1 + { + /// A pointer to a null-terminated string that identifies an installed monitor. + [MarshalAs(UnmanagedType.LPTStr)] + public string pName; + } + + /// The MONITOR_INFO_2 structure identifies a monitor. + // https://docs.microsoft.com/en-us/windows/win32/printdocs/monitor-info-2 typedef struct _MONITOR_INFO_2 { LPTSTR pName; LPTSTR + // pEnvironment; LPTSTR pDLLName; } MONITOR_INFO_2, *PMONITOR_INFO_2; + [PInvokeData("winspool.h", MSDNShortId = "4dd1ca15-6983-403e-8159-1a6d35a88162")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct MONITOR_INFO_2 + { + /// A pointer to a null-terminated string that is the name of the monitor. + [MarshalAs(UnmanagedType.LPTStr)] + public string pName; + + /// + /// A pointer to a null-terminated string that specifies the environment for which the monitor was written (for example, Windows + /// NT x86, Windows IA64, Windows x64). + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pEnvironment; + + /// A pointer to a null-terminated string that is the name of the monitor DLL. + [MarshalAs(UnmanagedType.LPTStr)] + public string pDLLName; + } + + /// The PORT_INFO_1 structure identifies a supported printer port. + // https://docs.microsoft.com/en-us/windows/win32/printdocs/port-info-1 typedef struct _PORT_INFO_1 { LPTSTR pName; } PORT_INFO_1, *PPORT_INFO_1; + [PInvokeData("winspool.h", MSDNShortId = "e474fe9c-e554-406a-a5bf-de07f9a72b32")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct PORT_INFO_1 + { + /// Pointer to a null-terminated string that identifies a supported printer port (for example, "LPT1:"). + [MarshalAs(UnmanagedType.LPTStr)] + public string pName; + } + + /// The PORT_INFO_2 structure identifies a supported printer port. + /// + /// + /// Use the PORT_INFO_2 structure when calling EnumPorts if there are multiple monitors installed that support the + /// same ports. + /// + /// + /// The fPortType member can be queried to determine information about the port. Note that port settings do not influence + /// printer attributes (as returned by the Attributes member of PRINTER_INFO_2). + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/port-info-2 typedef struct _PORT_INFO_2 { LPTSTR pPortName; LPTSTR + // pMonitorName; LPTSTR pDescription; DWORD fPortType; DWORD Reserved; } PORT_INFO_2, *PPORT_INFO_2; + [PInvokeData("winspool.h", MSDNShortId = "93675294-61d4-40e4-b84c-f252978e0285")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct PORT_INFO_2 + { + /// Pointer to a null-terminated string that identifies a supported printer port (for example, "LPT1:"). + [MarshalAs(UnmanagedType.LPTStr)] + public string pPortName; + + /// + /// Pointer to a null-terminated string that identifies an installed monitor (for example, "PJL monitor"). This can be NULL. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pMonitorName; + + /// + /// Pointer to a null-terminated string that describes the port in more detail (for example, if pPortName is "LPT1:", + /// pDescription is "printer port"). This can be NULL. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pDescription; + + /// Bitmask describing the type of port. This member can be a combination of the following values: + public PORT_TYPE fPortType; + + /// Reserved; must be zero. + public uint Reserved; + } + + /// The PORT_INFO_3 structure specifies the status value of a printer port. + /// + /// When you set a printer port status value with the severity value PORT_STATUS_TYPE_ERROR, the print spooler stops sending jobs to + /// the port. The print spooler does not resume sending jobs to the port until another SetPort call is made to clear the status. + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/port-info-3 typedef struct _PORT_INFO_3 { DWORD dwStatus; LPTSTR + // pszStatus; DWORD dwSeverity; } PORT_INFO_3, *PPORT_INFO_3; + [PInvokeData("winspool.h", MSDNShortId = "0939353f-284b-4dbb-89a2-04918c934430")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct PORT_INFO_3 + { + /// + /// The new port status value. This value is used only if the pszStatus member is NULL. + /// This member can be one of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// 0 + /// Clears the printer port status. + /// + /// + /// PORT_STATUS_OFFLINE + /// The port's printer is offline. + /// + /// + /// PORT_STATUS_PAPER_JAM + /// The port's printer has a paper jam. + /// + /// + /// PORT_STATUS_PAPER_OUT + /// The port's printer is out of paper. + /// + /// + /// PORT_STATUS_OUTPUT_BIN_FULL + /// The port's printer's output bin is full. + /// + /// + /// PORT_STATUS_PAPER_PROBLEM + /// The port's printer has a paper problem. + /// + /// + /// PORT_STATUS_NO_TONER + /// The port's printer is out of toner. + /// + /// + /// PORT_STATUS_DOOR_OPEN + /// The door of the port's printer is open. + /// + /// + /// PORT_STATUS_USER_INTERVENTION + /// The port's printer requires user intervention. + /// + /// + /// PORT_STATUS_OUT_OF_MEMORY + /// The port's printer is out of memory. + /// + /// + /// PORT_STATUS_TONER_LOW + /// The port's printer is low on toner. + /// + /// + /// PORT_STATUS_WARMING_UP + /// The port's printer is warming up. + /// + /// + /// PORT_STATUS_POWER_SAVE + /// The port's printer is in a power-conservation mode. + /// + /// + /// + public PORT_STATUS dwStatus; + + /// + /// Pointer to a new printer port status value string to set. Use this member if there is no suitable status value among those + /// listed for dwStatus. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pszStatus; + + /// + /// The severity of the port status value. + /// This member can be one of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// PORT_STATUS_TYPE_ERROR + /// The port status value indicates an error. + /// + /// + /// PORT_STATUS_TYPE_WARNING + /// The port status value is a warning. + /// + /// + /// PORT_STATUS_TYPE_INFO + /// The port status value is informational. + /// + /// + /// + public PORT_STATUS_TYPE dwSeverity; + } + + /// Contains the execution context of the printer driver that calls GetPrintExecutionData. + // https://docs.microsoft.com/en-us/windows/win32/printdocs/print-execution-data typedef struct _PRINT_EXECUTION_DATA { + // PRINT_EXECUTION_CONTEXT context; DWORD clientAppPID; } PRINT_EXECUTION_DATA; + [PInvokeData("winspool.h", MSDNShortId = "1fd25ed9-6f28-48f9-8132-d48fffc956ec")] + [StructLayout(LayoutKind.Sequential)] + public struct PRINT_EXECUTION_DATA + { + /// The PRINT_EXECUTION_CONTEXT value that represents the current execution context of the printer driver. + public PRINT_EXECUTION_CONTEXT context; + + /// + /// If the value of context is PRINT_EXECUTION_CONTEXT_WOW64, clientAppPID identifies the client + /// application on whose behalf the splwow64.exe process loaded the printer driver. If the value of context is not + /// PRINT_EXECUTION_CONTEXT_WOW64, clientAppPID is zero. + /// + public uint clientAppPID; + } + + /// Represents information about a connection to a printer. + // https://docs.microsoft.com/en-us/windows/win32/printdocs/printer-connection-info-1 typedef struct _PRINTER_CONNECTION_INFO_1 { + // DWORD dwFlags; LPTSTR pszDriverName; } PRINTER_CONNECTION_INFO_1, *PPRINTER_CONNECTION_INFO_1; + [PInvokeData("winspool.h", MSDNShortId = "afac3f91-74eb-46f7-94b4-d37b2b8a32a4")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct PRINTER_CONNECTION_INFO_1 + { + /// + /// The following values are defined: + /// + /// + /// Value + /// Meaning + /// + /// + /// PRINTER_CONNECTION_MISMATCH (0x00000020) + /// + /// If this bit-flag is set, the printer connection is mismatched. The user can supply a local print driver as pszDriverName and + /// use it to do the rendering instead of using the driver installed on the server printer to which the user is connected. + /// + /// + /// + /// PRINTER_CONNECTION_NO_UI (0x00000040) + /// + /// If this bit-flag is set then this call cannot display a dialog box. If a dialog box must be displayed to install a printer + /// driver from the server and this bit-flag is set, the printer driver will not be installed, the printer connection will not + /// be added, and the call will fail. Windows 7: In Windows 7 and later versions of Windows, if this flag is set and the user is + /// running in elevated mode, the Do you trust this printer? dialog will not be shown. + /// + /// + /// + /// + public PRINTER_CONNECTION_FLAGS dwFlags; + + /// A pointer to the name of the driver. + [MarshalAs(UnmanagedType.LPTStr)] + public string pszDriverName; + } + + /// + /// The PRINTER_DEFAULTS structure specifies the default data type, environment, initialization data, and access rights for a printer. + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/printer-defaults typedef struct _PRINTER_DEFAULTS { LPTSTR pDatatype; + // LPDEVMODE pDevMode; ACCESS_MASK DesiredAccess; } PRINTER_DEFAULTS, *PPRINTER_DEFAULTS; + [PInvokeData("winspool.h", MSDNShortId = "df29c3a6-b1d1-4d40-887d-5ffc032a5871")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct PRINTER_DEFAULTS + { + /// Pointer to a null-terminated string that specifies the default data type for a printer. + [MarshalAs(UnmanagedType.LPTStr)] + public string pDatatype; + + /// + /// Pointer to a DEVMODE structure that identifies the default environment and initialization data for a printer. + /// + public IntPtr pDevMode; + + /// + /// + /// Specifies desired access rights for a printer. The OpenPrinter function uses this member to set access rights to the + /// printer. These rights can affect the operation of the SetPrinter and DeletePrinter functions. The access + /// rights can be one of the following. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// PRINTER_ACCESS_ADMINISTER + /// To perform administrative tasks, such as those provided by SetPrinter. + /// + /// + /// PRINTER_ACCESS_USE + /// To perform basic printing operations. + /// + /// + /// PRINTER_ACCESS_MANAGE_LIMITED + /// + /// To perform administrative tasks, such as those provided by SetPrinter and SetPrinterData. This value is available starting + /// from Windows 8.1. + /// + /// + /// + /// PRINTER_ALL_ACCESS + /// + /// To perform all administrative tasks and basic printing operations except for SYNCHRONIZE (see Standard Access Rights ). + /// + /// + /// + /// generic security values, such as WRITE_DAC + /// To allow specific control access rights. See Standard Access Rights. + /// + /// + /// + public ACCESS_MASK DesiredAccess; + + /// A DEVMODE structure that contains device-initialization and environment data for the printer driver. + public DEVMODE DevMode => pDevMode.ToStructure(); + } + + /// + /// The PRINTER_ENUM_VALUES structure specifies the value name, type, and data for a printer configuration value returned by + /// the EnumPrinterDataEx function. + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/printer-enum-values typedef struct _PRINTER_ENUM_VALUES { LPTSTR + // pValueName; DWORD cbValueName; DWORD dwType; LPBYTE pData; DWORD cbData; } PRINTER_ENUM_VALUES, *PPRINTER_ENUM_VALUES; + [PInvokeData("winspool.h", MSDNShortId = "87eb1452-0d9d-46bd-8af8-0542a11a929b")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct PRINTER_ENUM_VALUES + { + /// Pointer to a null-terminated string that specifies the name of the retrieved value. + [MarshalAs(UnmanagedType.LPTStr)] + public string pValueName; + + /// The number of bytes in the pValueName member, including the terminating NULL character. + public uint cbValueName; + + /// + /// A code indicating the type of data pointed to by the pData member. For a list of the possible type codes, see Registry Value Types. + /// + public REG_VALUE_TYPE dwType; + + /// Pointer to a buffer containing the data for the retrieved value. + public IntPtr pData; + + /// The number of bytes retrieved in the pData buffer. + public uint cbData; + } + + /// The PRINTER_INFO_1 structure specifies general printer information. + // https://docs.microsoft.com/en-us/windows/win32/printdocs/printer-info-1 typedef struct _PRINTER_INFO_1 { DWORD Flags; LPTSTR + // pDescription; LPTSTR pName; LPTSTR pComment; } PRINTER_INFO_1, *PPRINTER_INFO_1; + [PInvokeData("winspool.h", MSDNShortId = "0b0e2d0e-2625-4cab-a8f9-536185479443")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct PRINTER_INFO_1 + { + /// + /// Specifies information about the returned data. Following are the values for this member. + /// + /// + /// Value + /// Meaning + /// + /// + /// PRINTER_ENUM_EXPAND + /// + /// A print provider can set this flag as a hint to a calling application to enumerate this object further if default expansion + /// is enabled. For example, when domains are enumerated, a print provider might indicate the user's domain by setting this flag. + /// + /// + /// + /// PRINTER_ENUM_CONTAINER + /// + /// If this flag is set, the printer object may contain enumerable objects. For example, the object may be a print server that + /// contains printers. + /// + /// + /// + /// PRINTER_ENUM_ICON1 + /// + /// Indicates that, where appropriate, an application should display an icon identifying the object as a top-level network name, + /// such as Microsoft Windows Network. + /// + /// + /// + /// PRINTER_ENUM_ICON2 + /// Indicates that, where appropriate, an application should display an icon that identifies the object as a network domain. + /// + /// + /// PRINTER_ENUM_ICON3 + /// Indicates that, where appropriate, an application should display an icon that identifies the object as a print server. + /// + /// + /// PRINTER_ENUM_ICON4 + /// Reserved. + /// + /// + /// PRINTER_ENUM_ICON5 + /// Reserved. + /// + /// + /// PRINTER_ENUM_ICON6 + /// Reserved. + /// + /// + /// PRINTER_ENUM_ICON7 + /// Reserved. + /// + /// + /// PRINTER_ENUM_ICON8 + /// Indicates that, where appropriate, an application should display an icon that identifies the object as a printer. + /// + /// + /// + public PRINTER_ENUM Flags; + + /// Pointer to a null-terminated string that describes the contents of the structure. + [MarshalAs(UnmanagedType.LPTStr)] + public string pDescription; + + /// Pointer to a null-terminated string that names the contents of the structure. + [MarshalAs(UnmanagedType.LPTStr)] + public string pName; + + /// Pointer to a null-terminated string that contains additional data describing the structure. + [MarshalAs(UnmanagedType.LPTStr)] + public string pComment; + } + + /// The PRINTER_INFO_2 structure specifies detailed printer information. + // https://docs.microsoft.com/en-us/windows/win32/printdocs/printer-info-2 typedef struct _PRINTER_INFO_2 { LPTSTR pServerName; + // LPTSTR pPrinterName; LPTSTR pShareName; LPTSTR pPortName; LPTSTR pDriverName; LPTSTR pComment; LPTSTR pLocation; LPDEVMODE + // pDevMode; LPTSTR pSepFile; LPTSTR pPrintProcessor; LPTSTR pDatatype; LPTSTR pParameters; PSECURITY_DESCRIPTOR + // pSecurityDescriptor; DWORD Attributes; DWORD Priority; DWORD DefaultPriority; DWORD StartTime; DWORD UntilTime; DWORD Status; + // DWORD cJobs; DWORD AveragePPM; } PRINTER_INFO_2, *PPRINTER_INFO_2; + [PInvokeData("winspool.h", MSDNShortId = "944cbfcd-9edf-4b60-a45c-9bb1839f8141")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct PRINTER_INFO_2 + { + /// + /// A pointer to a null-terminated string identifying the server that controls the printer. If this string is NULL, the + /// printer is controlled locally. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pServerName; + + /// A pointer to a null-terminated string that specifies the name of the printer. + [MarshalAs(UnmanagedType.LPTStr)] + public string pPrinterName; + + /// + /// A pointer to a null-terminated string that identifies the share point for the printer. (This string is used only if the + /// PRINTER_ATTRIBUTE_SHARED constant was set for the Attributes member.) + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pShareName; + + /// + /// A pointer to a null-terminated string that identifies the port(s) used to transmit data to the printer. If a printer is + /// connected to more than one port, the names of each port must be separated by commas (for example, "LPT1:,LPT2:,LPT3:"). + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pPortName; + + /// A pointer to a null-terminated string that specifies the name of the printer driver. + [MarshalAs(UnmanagedType.LPTStr)] + public string pDriverName; + + /// A pointer to a null-terminated string that provides a brief description of the printer. + [MarshalAs(UnmanagedType.LPTStr)] + public string pComment; + + /// + /// A pointer to a null-terminated string that specifies the physical location of the printer (for example, "Bldg. 38, Room 1164"). + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pLocation; + + /// + /// A pointer to a DEVMODE structure that defines default printer data such as the paper orientation and the resolution. + /// + public IntPtr pDevMode; + + /// + /// A pointer to a null-terminated string that specifies the name of the file used to create the separator page. This page is + /// used to separate print jobs sent to the printer. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pSepFile; + + /// + /// A pointer to a null-terminated string that specifies the name of the print processor used by the printer. You can use the + /// EnumPrintProcessors function to obtain a list of print processors installed on a server. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pPrintProcessor; + + /// + /// A pointer to a null-terminated string that specifies the data type used to record the print job. You can use the + /// EnumPrintProcessorDatatypes function to obtain a list of data types supported by a specific print processor. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pDatatype; + + /// A pointer to a null-terminated string that specifies the default print-processor parameters. + [MarshalAs(UnmanagedType.LPTStr)] + public string pParameters; + + /// A pointer to a SECURITY_DESCRIPTOR structure for the printer. This member may be NULL. + public PSECURITY_DESCRIPTOR pSecurityDescriptor; + + /// + /// The printer attributes. This member can be any reasonable combination of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// PRINTER_ATTRIBUTE_DIRECT + /// Job is sent directly to the printer (it is not spooled). + /// + /// + /// PRINTER_ATTRIBUTE_DO_COMPLETE_FIRST + /// + /// If set and printer is set for print-while-spooling, any jobs that have completed spooling are scheduled to print before jobs + /// that have not completed spooling. + /// + /// + /// + /// PRINTER_ATTRIBUTE_ENABLE_DEVQ + /// + /// If set, DevQueryPrint is called. DevQueryPrint may fail if the document and printer setups do not match. Setting this flag + /// causes mismatched documents to be held in the queue. + /// + /// + /// + /// PRINTER_ATTRIBUTE_HIDDEN + /// Reserved. + /// + /// + /// PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS + /// If set, jobs are kept after they are printed. If unset, jobs are deleted. + /// + /// + /// PRINTER_ATTRIBUTE_LOCAL + /// Printer is a local printer. + /// + /// + /// PRINTER_ATTRIBUTE_NETWORK + /// Printer is a network printer connection. + /// + /// + /// PRINTER_ATTRIBUTE_PUBLISHED + /// Indicates whether the printer is published in the directory service. + /// + /// + /// PRINTER_ATTRIBUTE_QUEUED + /// + /// If set, the printer spools and starts printing after the last page is spooled. If not set and PRINTER_ATTRIBUTE_DIRECT is + /// not set, the printer spools and prints while spooling. + /// + /// + /// + /// PRINTER_ATTRIBUTE_RAW_ONLY + /// Indicates that only raw data type print jobs can be spooled. + /// + /// + /// PRINTER_ATTRIBUTE_SHARED + /// Printer is shared. + /// + /// + /// In Windows XP and later versions of Windows, the following value can also be used. + /// + /// + /// Value + /// Meaning + /// + /// + /// PRINTER_ATTRIBUTE_FAX + /// + /// If set, printer is a fax printer. This can only be set by AddPrinter, but it can be retrieved by EnumPrinters and GetPrinter. + /// + /// + /// + /// In Windows Vista and later versions of Windows, the following values can also be used. + /// + /// + /// Value + /// Meaning + /// + /// + /// PRINTER_ATTRIBUTE_FRIENDLY_NAME + /// A computer has connected to this printer and given it a friendly name. + /// + /// + /// PRINTER_ATTRIBUTE_MACHINE + /// Printer is a per-machine connection. + /// + /// + /// PRINTER_ATTRIBUTE_PUSHED_USER + /// The printer was installed by using the Push Printer Connections user policy. + /// + /// + /// PRINTER_ATTRIBUTE_PUSHED_MACHINE + /// The printer was installed by using the Push Printer Connections computer policy. + /// + /// + /// In Windows Server 2003, the following value can also be used. + /// + /// + /// Value + /// Meaning + /// + /// + /// PRINTER_ATTRIBUTE_TS + /// Indicates the printer is currently connected through a terminal server. + /// + /// + /// + public PRINTER_ATTRIBUTE Attributes; + + /// A priority value that the spooler uses to route print jobs. + public uint Priority; + + /// The default priority value assigned to each print job. + public uint DefaultPriority; + + /// + /// The earliest time at which the printer will print a job. This value is expressed as minutes elapsed since 12:00 AM GMT + /// (Greenwich Mean Time). + /// + public uint StartTime; + + /// + /// The latest time at which the printer will print a job. This value is expressed as minutes elapsed since 12:00 AM GMT + /// (Greenwich Mean Time). + /// + public uint UntilTime; + + /// + /// The printer status. This member can be any reasonable combination of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// PRINTER_STATUS_BUSY + /// The printer is busy. + /// + /// + /// PRINTER_STATUS_DOOR_OPEN + /// The printer door is open. + /// + /// + /// PRINTER_STATUS_ERROR + /// The printer is in an error state. + /// + /// + /// PRINTER_STATUS_INITIALIZING + /// The printer is initializing. + /// + /// + /// PRINTER_STATUS_IO_ACTIVE + /// The printer is in an active input/output state + /// + /// + /// PRINTER_STATUS_MANUAL_FEED + /// The printer is in a manual feed state. + /// + /// + /// PRINTER_STATUS_NO_TONER + /// The printer is out of toner. + /// + /// + /// PRINTER_STATUS_NOT_AVAILABLE + /// The printer is not available for printing. + /// + /// + /// PRINTER_STATUS_OFFLINE + /// The printer is offline. + /// + /// + /// PRINTER_STATUS_OUT_OF_MEMORY + /// The printer has run out of memory. + /// + /// + /// PRINTER_STATUS_OUTPUT_BIN_FULL + /// The printer's output bin is full. + /// + /// + /// PRINTER_STATUS_PAGE_PUNT + /// The printer cannot print the current page. + /// + /// + /// PRINTER_STATUS_PAPER_JAM + /// Paper is jammed in the printer + /// + /// + /// PRINTER_STATUS_PAPER_OUT + /// The printer is out of paper. + /// + /// + /// PRINTER_STATUS_PAPER_PROBLEM + /// The printer has a paper problem. + /// + /// + /// PRINTER_STATUS_PAUSED + /// The printer is paused. + /// + /// + /// PRINTER_STATUS_PENDING_DELETION + /// The printer is being deleted. + /// + /// + /// PRINTER_STATUS_POWER_SAVE + /// The printer is in power save mode. + /// + /// + /// PRINTER_STATUS_PRINTING + /// The printer is printing. + /// + /// + /// PRINTER_STATUS_PROCESSING + /// The printer is processing a print job. + /// + /// + /// PRINTER_STATUS_SERVER_UNKNOWN + /// The printer status is unknown. + /// + /// + /// PRINTER_STATUS_TONER_LOW + /// The printer is low on toner. + /// + /// + /// PRINTER_STATUS_USER_INTERVENTION + /// The printer has an error that requires the user to do something. + /// + /// + /// PRINTER_STATUS_WAITING + /// The printer is waiting. + /// + /// + /// PRINTER_STATUS_WARMING_UP + /// The printer is warming up. + /// + /// + /// + public PRINTER_STATUS Status; + + /// The number of print jobs that have been queued for the printer. + public uint cJobs; + + /// The average number of pages per minute that have been printed on the printer. + public uint AveragePPM; + + /// A DEVMODE structure that contains device-initialization and environment data for the printer driver. + public DEVMODE DevMode => pDevMode.ToStructure(); + } + + /// The PRINTER_INFO_3 structure specifies printer security information. + /// + /// The PRINTER_INFO_3 structure lets an application get and set a printer's security descriptor. The caller may do so even + /// if it lacks specific printer permissions, as long as it has the standard rights described in SetPrinter and + /// GetPrinter. Thus, an application may temporarily deny all access to a printer, while allowing the owner of the printer to + /// have access to the printer's discretionary ACL. + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/printer-info-3 typedef struct _PRINTER_INFO_3 { PSECURITY_DESCRIPTOR + // pSecurityDescriptor; } PRINTER_INFO_3, *PPRINTER_INFO_3; + [PInvokeData("winspool.h", MSDNShortId = "527d635d-2d75-4b56-bab7-e95c9919a8fb")] + [StructLayout(LayoutKind.Sequential)] + public struct PRINTER_INFO_3 + { + /// Pointer to a SECURITY_DESCRIPTOR structure that specifies a printer's security information. + public PSECURITY_DESCRIPTOR pSecurityDescriptor; + } + + /// + /// The PRINTER_INFO_4 structure specifies general printer information. + /// + /// The structure can be used to retrieve minimal printer information on a call to EnumPrinters. Such a call is a fast and + /// easy way to retrieve the names and attributes of all locally installed printers on a system and all remote printer connections + /// that a user has established. + /// + /// + /// + /// + /// The PRINTER_INFO_4 structure provides an easy and extremely fast way to retrieve the names of the printers installed on a + /// local machine, as well as the remote connections that a user has established. When EnumPrinters is called with a + /// PRINTER_INFO_4 data structure, that function queries the registry for the specified information, then returns + /// immediately. This differs from the behavior of EnumPrinters when called with other levels of PRINTER_INFO_xxx data + /// structures. In particular, when EnumPrinters is called with a level 2 ( PRINTER_INFO_2 ) data structure, it + /// performs an OpenPrinter call on each remote connection. If a remote connection is down, if the remote server no longer + /// exists, or if the remote printer no longer exists, the function must wait for RPC to time out and consequently fail the + /// OpenPrinter call. This can take a while. Passing a PRINTER_INFO_4 structure lets an application retrieve a bare + /// minimum of required information; if more detailed information is desired, a subsequent EnumPrinter level 2 call can be made. + /// + /// Attributes can also contain values that are defined in the Attributes field of PRINTER_INFO_2. + /// + /// Some printer configurations, such as printer connections to some non-Windows-based print servers, might return both + /// PRINTER_ATTRIBUTE_LOCAL and PRINTER_ATTRIBUTE_NETWORK. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/printer-info-4 typedef struct _PRINTER_INFO_4 { LPTSTR pPrinterName; + // LPTSTR pServerName; DWORD Attributes; } PRINTER_INFO_4, *PPRINTER_INFO_4; + [PInvokeData("winspool.h", MSDNShortId = "81bd0eab-dc1e-4cf1-8f63-3686f1711c1f")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct PRINTER_INFO_4 + { + /// Pointer to a null-terminated string that specifies the name of the printer (local or remote). + [MarshalAs(UnmanagedType.LPTStr)] + public string pPrinterName; + + /// Pointer to a null-terminated string that is the name of the server. + [MarshalAs(UnmanagedType.LPTStr)] + public string pServerName; + + /// + /// Specifies information about the returned data. + /// + /// + /// Value + /// Meaning + /// + /// + /// PRINTER_ATTRIBUTE_LOCAL + /// The printer is a local printer. + /// + /// + /// PRINTER_ATTRIBUTE_NETWORK + /// The printer is a remote printer. + /// + /// + /// + public PRINTER_ATTRIBUTE Attributes; + } + + /// The PRINTER_INFO_5 structure specifies detailed printer information. + // https://docs.microsoft.com/en-us/windows/win32/printdocs/printer-info-5 typedef struct _PRINTER_INFO_5 { LPTSTR pPrinterName; + // LPTSTR pPortName; DWORD Attributes; DWORD DeviceNotSelectedTimeout; DWORD TransmissionRetryTimeout; } PRINTER_INFO_5, *PPRINTER_INFO_5; + [PInvokeData("winspool.h", MSDNShortId = "c8599f2e-3b7c-4fde-a340-ca7d3ddaa106")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct PRINTER_INFO_5 + { + /// A pointer to a null-terminated string that specifies the name of the printer. + [MarshalAs(UnmanagedType.LPTStr)] + public string pPrinterName; + + /// + /// A pointer to a null-terminated string that identifies the port(s) used to transmit data to the printer. If a printer is + /// connected to more than one port, the names of each port must be separated by commas (for example, "LPT1:,LPT2:,LPT3:"). + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pPortName; + + /// + /// The printer attributes. This member can be any reasonable combination of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// PRINTER_ATTRIBUTE_DIRECT + /// Job is sent directly to the printer (it is not spooled). + /// + /// + /// PRINTER_ATTRIBUTE_DO_COMPLETE_FIRST + /// + /// If set and printer is set for print-while-spooling, any jobs that have completed spooling are scheduled to print before jobs + /// that have not completed spooling. + /// + /// + /// + /// PRINTER_ATTRIBUTE_ENABLE_DEVQ + /// + /// If set, DevQueryPrint is called. DevQueryPrint may fail if the document and printer setups do not match. Setting this flag + /// causes mismatched documents to be held in the queue. + /// + /// + /// + /// PRINTER_ATTRIBUTE_HIDDEN + /// Reserved. + /// + /// + /// PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS + /// If set, jobs are kept after they are printed. If unset, jobs are deleted. + /// + /// + /// PRINTER_ATTRIBUTE_LOCAL + /// Printer is a local printer. + /// + /// + /// PRINTER_ATTRIBUTE_NETWORK + /// Printer is a network printer connection. + /// + /// + /// PRINTER_ATTRIBUTE_PUBLISHED + /// Indicates whether the printer is published in the directory service. + /// + /// + /// PRINTER_ATTRIBUTE_QUEUED + /// + /// If set, the printer spools and starts printing after the last page is spooled. If not set and PRINTER_ATTRIBUTE_DIRECT is + /// not set, the printer spools and prints while spooling. + /// + /// + /// + /// PRINTER_ATTRIBUTE_RAW_ONLY + /// Indicates that only raw data type print jobs can be spooled. + /// + /// + /// PRINTER_ATTRIBUTE_SHARED + /// Printer is shared. + /// + /// + /// In Windows XP and later versions of Windows, the following value can also be used. + /// + /// + /// Value + /// Meaning + /// + /// + /// PRINTER_ATTRIBUTE_FAX + /// + /// If set, printer is a fax printer. This can only be set by AddPrinter, but it can be retrieved by EnumPrinters and GetPrinter. + /// + /// + /// + /// In Windows Vista and later versions of Windows, the following values can also be used. + /// + /// + /// Value + /// Meaning + /// + /// + /// PRINTER_ATTRIBUTE_FRIENDLY_NAME + /// A computer has connected to this printer and given it a friendly name. + /// + /// + /// PRINTER_ATTRIBUTE_MACHINE + /// Printer is a per-machine connection. + /// + /// + /// PRINTER_ATTRIBUTE_PUSHED_USER + /// The printer was installed by using the Push Printer Connections user policy. + /// + /// + /// PRINTER_ATTRIBUTE_PUSHED_MACHINE + /// The printer was installed by using the Push Printer Connections computer policy. + /// + /// + /// + public PRINTER_ATTRIBUTE Attributes; + + /// This value is not used. + public uint DeviceNotSelectedTimeout; + + /// This value is not used. + public uint TransmissionRetryTimeout; + } + + /// The PRINTER_INFO_6 specifies the status value of a printer. + // https://docs.microsoft.com/en-us/windows/win32/printdocs/printer-info-6 typedef struct _PRINTER_INFO_6 { DWORD dwStatus; } + // PRINTER_INFO_6, *PPRINTER_INFO_6; + [PInvokeData("winspool.h", MSDNShortId = "f26fe75b-7c97-47ad-892f-d9e40331fa5d")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct PRINTER_INFO_6 + { + /// + /// The printer status. This member can be any reasonable combination of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// PRINTER_STATUS_BUSY + /// The printer is busy. + /// + /// + /// PRINTER_STATUS_DOOR_OPEN + /// The printer door is open. + /// + /// + /// PRINTER_STATUS_ERROR + /// Not used. + /// + /// + /// PRINTER_STATUS_INITIALIZING + /// The printer is initializing. + /// + /// + /// PRINTER_STATUS_IO_ACTIVE + /// The printer is in an active input/output state + /// + /// + /// PRINTER_STATUS_MANUAL_FEED + /// The printer is in a manual feed state. + /// + /// + /// PRINTER_STATUS_NO_TONER + /// The printer is out of toner. + /// + /// + /// PRINTER_STATUS_NOT_AVAILABLE + /// The printer is not available for printing. + /// + /// + /// PRINTER_STATUS_OFFLINE + /// The printer is offline. + /// + /// + /// PRINTER_STATUS_OUT_OF_MEMORY + /// The printer has run out of memory. + /// + /// + /// PRINTER_STATUS_OUTPUT_BIN_FULL + /// The printer's output bin is full. + /// + /// + /// PRINTER_STATUS_PAGE_PUNT + /// The printer cannot print the current page. + /// + /// + /// PRINTER_STATUS_PAPER_JAM + /// Paper is jammed in the printer + /// + /// + /// PRINTER_STATUS_PAPER_OUT + /// The printer is out of paper. + /// + /// + /// PRINTER_STATUS_PAPER_PROBLEM + /// The printer has a paper problem. + /// + /// + /// PRINTER_STATUS_PAUSED + /// The printer is paused. + /// + /// + /// PRINTER_STATUS_PENDING_DELETION + /// The printer is pending deletion as a result of a call to the DeletePrinter function. + /// + /// + /// PRINTER_STATUS_POWER_SAVE + /// The printer is in power save mode. + /// + /// + /// PRINTER_STATUS_PRINTING + /// The printer is printing. + /// + /// + /// PRINTER_STATUS_PROCESSING + /// The printer is processing a command from the SetPrinter function. + /// + /// + /// PRINTER_STATUS_SERVER_UNKNOWN + /// The printer status is unknown. + /// + /// + /// PRINTER_STATUS_TONER_LOW + /// The printer is low on toner. + /// + /// + /// PRINTER_STATUS_USER_INTERVENTION + /// The printer has an error that requires the user to do something. + /// + /// + /// PRINTER_STATUS_WAITING + /// The printer is waiting. + /// + /// + /// PRINTER_STATUS_WARMING_UP + /// The printer is warming up. + /// + /// + /// + public PRINTER_STATUS dwStatus; + } + + /// + /// The PRINTER_INFO_7 structure specifies directory services printer information. Use this structure with the + /// SetPrinter function to publish a printer's data in the directory service (DS), or to update or remove a printer's + /// published data from the DS. Use this structure with the GetPrinter function to determine whether a printer is published + /// in the DS. + /// + /// + /// + /// The PRINTER_INFO_7 structure is used in a SetPrinter call to publish printer information to the directory service. + /// The published data includes all values and data for the specified printer found under the SPLDS_SPOOLER_KEY, SPLDS_DRIVER_KEY, + /// or SPLDS_USER_KEY keys created by SetPrinterDataEx. + /// + /// + /// For SetPrinter, pszObjectGUID should be set to NULL. For GetPrinter, pszObjectGUID returns the GUID of the + /// directory services print queue object associated with a published printer. You can use this GUID with Active Directory Services + /// Interface (ADSI) methods to retrieve published data for the printer. However, the recommended method for retrieving published + /// data is to call the GetPrinterDataEx function. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/printer-info-7 typedef struct _PRINTER_INFO_7 { LPTSTR pszObjectGUID; + // DWORD dwAction; } PRINTER_INFO_7, *PPRINTER_INFO_7; + [PInvokeData("winspool.h", MSDNShortId = "9443855e-df7d-41a1-a0df-5649a97b2915")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct PRINTER_INFO_7 + { + /// + /// + /// A pointer to a null-terminated string containing the GUID of the directory service print queue object associated with a + /// published printer. Use the GetPrinter function to retrieve this GUID. + /// + /// Before calling SetPrinter, set pszObjectGUID to NULL. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pszObjectGUID; + + /// + /// + /// Indicates the action for the SetPrinter function to perform. For the GetPrinter function, this member + /// indicates whether the specified printer is published. This member can be a combination of the following values. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// DSPRINT_PENDING 0x80000000 + /// + /// GetPrinter: Indicates that the system is attempting to complete a publish or unpublish operation started by a SetPrinter + /// call. SetPrinter: This value is not valid. + /// + /// + /// + /// DSPRINT_PUBLISH 0x00000001 + /// SetPrinter: Publishes the printer's data in the DS. GetPrinter: Indicates the printer is published. + /// + /// + /// DSPRINT_REPUBLISH 0x00000008 + /// + /// SetPrinter: The DS data for the printer is unpublished and then published again, refreshing all properties in the published + /// printer. Re-publishing also changes the GUID of the published printer. GetPrinter: Never returns this value. + /// + /// + /// + /// DSPRINT_UNPUBLISH 0x00000004 + /// SetPrinter: Removes the printer's published data from the DS. GetPrinter: Indicates the printer is not published. + /// + /// + /// DSPRINT_UPDATE 0x00000002 + /// SetPrinter: Updates the printer's published data in the DS. GetPrinter: Never returns this value. + /// + /// + /// + public DSPRINT dwAction; + } + + /// The PRINTER_INFO_8 structure specifies the global default printer settings. + /// + /// The global defaults are set by the administrator of a printer that can be used by anyone. In contrast, the per-user defaults + /// will affect a particular user or anyone else who uses the profile. For per-user defaults, use PRINTER_INFO_9. + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/printer-info-8 typedef struct _PRINTER_INFO_8 { LPDEVMODE pDevMode; } + // PRINTER_INFO_8, *PPRINTER_INFO_8; + [PInvokeData("winspool.h", MSDNShortId = "98f26a45-5302-4358-bed6-691d9bc37554")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct PRINTER_INFO_8 + { + /// + /// A pointer to a DEVMODE structure that defines the global default printer data such as the paper orientation and the resolution. + /// + public IntPtr pDevMode; + + /// A DEVMODE structure that contains device-initialization and environment data for the printer driver. + public DEVMODE DevMode => pDevMode.ToStructure(); + } + + /// The PRINTER_INFO_9 structure specifies the per-user default printer settings. + /// + /// The per-user defaults will affect only a particular user or anyone who uses the profile. In contrast, the global defaults are + /// set by the administrator of a printer that can be used by anyone. For global defaults, use PRINTER_INFO_8. + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/printer-info-9 typedef struct _PRINTER_INFO_9 { LPDEVMODE pDevMode; } + // PRINTER_INFO_9, *PPRINTER_INFO_9; + [PInvokeData("winspool.h", MSDNShortId = "8bafb995-f31c-46e3-a950-45e240c678aa")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct PRINTER_INFO_9 + { + /// + /// A pointer to a DEVMODE structure that defines the per-user default printer data such as the paper orientation and the + /// resolution. The DEVMODE is stored in the user's registry. + /// + public IntPtr pDevMode; + + /// A DEVMODE structure that contains device-initialization and environment data for the printer driver. + public DEVMODE DevMode => pDevMode.ToStructure(); + } + + /// + /// The PRINTER_NOTIFY_INFO structure contains printer information returned by the FindNextPrinterChangeNotification + /// function. The function returns this information after a wait operation on a printer change notification object has been satisfied. + /// + /// + /// If the Flags member has the PRINTER_NOTIFY_INFO_DISCARDED bit set, this indicates that an overflow or error occurred, and + /// notifications may have been lost. In this case, you must call FindNextPrinterChangeNotification and specify the + /// PRINTER_NOTIFY_OPTIONS_REFRESH flag to retrieve all current information. Until you request this refresh operation, the system + /// will not send additional notifications for this change notification object. + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/printer-notify-info typedef struct _PRINTER_NOTIFY_INFO { DWORD Version; + // DWORD Flags; DWORD Count; PRINTER_NOTIFY_INFO_DATA aData[1]; } PRINTER_NOTIFY_INFO, *PPRINTER_NOTIFY_INFO; + [PInvokeData("winspool.h", MSDNShortId = "c104fabe-edf5-426e-859b-694811975623")] + [StructLayout(LayoutKind.Sequential)] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(Count))] + public struct PRINTER_NOTIFY_INFO + { + /// The version of this structure. Set this member to 2. + public uint Version; + + /// + /// A bit flag that indicates the state of the notification structure. If the PRINTER_NOTIFY_INFO_DISCARDED bit is set, it + /// indicates that some notifications had to be discarded. + /// + public uint Flags; + + /// The number of PRINTER_NOTIFY_INFO_DATA elements in the aData array. + public uint Count; + + /// + /// An array of PRINTER_NOTIFY_INFO_DATA structures. Each element of the array identifies a single job or printer + /// information field, and provides the current data for that field. + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public PRINTER_NOTIFY_INFO_DATA[] aData; + } + + /// + /// + /// The PRINTER_NOTIFY_INFO_DATA structure identifies a job or printer information field and provides the current data for + /// that field. + /// + /// + /// The FindNextPrinterChangeNotification function returns a PRINTER_NOTIFY_INFO structure, which contains an array of + /// PRINTER_NOTIFY_INFO_DATA structures. + /// + /// + /// + /// If the Type member specifies PRINTER_NOTIFY_TYPE, the Field member can be one of the following values. + /// + /// + /// Field + /// Type of data + /// Value + /// + /// + /// PRINTER_NOTIFY_FIELD_SERVER_NAME + /// Not supported. + /// 0x00 + /// + /// + /// PRINTER_NOTIFY_FIELD_PRINTER_NAME + /// pBuf is a pointer to a null-terminated string containing the name of the printer. + /// 0x01 + /// + /// + /// PRINTER_NOTIFY_FIELD_SHARE_NAME + /// pBuf is a pointer to a null-terminated string that identifies the share point for the printer. + /// 0x02 + /// + /// + /// PRINTER_NOTIFY_FIELD_PORT_NAME + /// + /// pBuf is a pointer to a null-terminated string containing the name of the port that the print jobs will be printed to. If + /// "Printer Pooling" is selected, this is a comma separated list of ports. + /// + /// 0x03 + /// + /// + /// PRINTER_NOTIFY_FIELD_DRIVER_NAME + /// pBuf is a pointer to a null-terminated string containing the name of the printer's driver. + /// 0x04 + /// + /// + /// PRINTER_NOTIFY_FIELD_COMMENT + /// + /// pBuf is a pointer to a null-terminated string containing the new comment string, which is typically a brief description of the printer. + /// + /// 0x05 + /// + /// + /// PRINTER_NOTIFY_FIELD_LOCATION + /// + /// pBuf is a pointer to a null-terminated string containing the new physical location of the printer (for example, "Bldg. 38, Room 1164"). + /// + /// 0x06 + /// + /// + /// PRINTER_NOTIFY_FIELD_DEVMODE + /// pBuf is a pointer to a DEVMODE structure that defines default printer data such as the paper orientation and the resolution. + /// 0x07 + /// + /// + /// PRINTER_NOTIFY_FIELD_SEPFILE + /// + /// pBuf is a pointer to a null-terminated string that specifies the name of the file used to create the separator page. This page + /// is used to separate print jobs sent to the printer. + /// + /// 0x08 + /// + /// + /// PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR + /// pBuf is a pointer to a null-terminated string that specifies the name of the print processor used by the printer. + /// 0x09 + /// + /// + /// PRINTER_NOTIFY_FIELD_PARAMETERS + /// pBuf is a pointer to a null-terminated string that specifies the default print-processor parameters. + /// 0x0A + /// + /// + /// PRINTER_NOTIFY_FIELD_DATATYPE + /// pBuf is a pointer to a null-terminated string that specifies the data type used to record the print job. + /// 0x0B + /// + /// + /// PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR + /// + /// pBuf is a pointer to a SECURITY_DESCRIPTOR structure for the printer. The pointer may be NULL if there is no security descriptor. + /// + /// 0x0C + /// + /// + /// PRINTER_NOTIFY_FIELD_ATTRIBUTES + /// + /// adwData [0] specifies the printer attributes, which can be one of the following values: PRINTER_ATTRIBUTE_QUEUED + /// PRINTER_ATTRIBUTE_DIRECT PRINTER_ATTRIBUTE_DEFAULT PRINTER_ATTRIBUTE_SHARED + /// + /// 0x0D + /// + /// + /// PRINTER_NOTIFY_FIELD_PRIORITY + /// adwData [0] specifies a priority value that the spooler uses to route print jobs. + /// 0x0E + /// + /// + /// PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY + /// adwData [0] specifies the default priority value assigned to each print job. + /// 0x0F + /// + /// + /// PRINTER_NOTIFY_FIELD_START_TIME + /// + /// adwData [0] specifies the earliest time at which the printer will print a job. (This value is specified in minutes elapsed since + /// 12:00 A.M.) + /// + /// 0x10 + /// + /// + /// PRINTER_NOTIFY_FIELD_UNTIL_TIME + /// + /// adwData [0] specifies the latest time at which the printer will print a job. (This value is specified in minutes elapsed since + /// 12:00 A.M.) + /// + /// 0x11 + /// + /// + /// PRINTER_NOTIFY_FIELD_STATUS + /// adwData [0] specifies the printer status. For a list of possible values, see the PRINTER_INFO_2 structure. + /// 0x12 + /// + /// + /// PRINTER_NOTIFY_FIELD_STATUS_STRING + /// Not supported. + /// 0x13 + /// + /// + /// PRINTER_NOTIFY_FIELD_CJOBS + /// adwData [0] specifies the number of print jobs that have been queued for the printer. + /// 0x14 + /// + /// + /// PRINTER_NOTIFY_FIELD_AVERAGE_PPM + /// adwData [0] specifies the average number of pages per minute that have been printed on the printer. + /// 0x15 + /// + /// + /// PRINTER_NOTIFY_FIELD_TOTAL_PAGES + /// Not supported. + /// 0x16 + /// + /// + /// PRINTER_NOTIFY_FIELD_PAGES_PRINTED + /// Not supported. + /// 0x17 + /// + /// + /// PRINTER_NOTIFY_FIELD_TOTAL_BYTES + /// Not supported. + /// 0x18 + /// + /// + /// PRINTER_NOTIFY_FIELD_BYTES_PRINTED + /// Not supported. + /// 0x19 + /// + /// + /// PRINTER_NOTIFY_FIELD_OBJECT_GUID + /// This is set if the object GUID changes. + /// 0x1A + /// + /// + /// PRINTER_NOTIFY_FIELD_FRIENDLY_NAME + /// This is set if the printer connection is renamed. + /// 0x1B + /// + /// + /// If the Type member specifies JOB_NOTIFY_TYPE, the Field member can be one of the following values. + /// + /// + /// Field + /// Type of data + /// Value + /// + /// + /// JOB_NOTIFY_FIELD_PRINTER_NAME + /// pBuf is a pointer to a null-terminated string containing the name of the printer for which the job is spooled. + /// 0x00 + /// + /// + /// JOB_NOTIFY_FIELD_MACHINE_NAME + /// pBuf is a pointer to a null-terminated string that specifies the name of the machine that created the print job. + /// 0x01 + /// + /// + /// JOB_NOTIFY_FIELD_PORT_NAME + /// + /// pBuf is a pointer to a null-terminated string that identifies the port(s) used to transmit data to the printer. If a printer is + /// connected to more than one port, the names of the ports are separated by commas (for example, "LPT1:,LPT2:,LPT3:"). + /// + /// 0x02 + /// + /// + /// JOB_NOTIFY_FIELD_USER_NAME + /// pBuf is a pointer to a null-terminated string that specifies the name of the user who sent the print job. + /// 0x03 + /// + /// + /// JOB_NOTIFY_FIELD_NOTIFY_NAME + /// + /// pBuf is a pointer to a null-terminated string that specifies the name of the user who should be notified when the job has been + /// printed or when an error occurs while printing the job. + /// + /// 0x04 + /// + /// + /// JOB_NOTIFY_FIELD_DATATYPE + /// pBuf is a pointer to a null-terminated string that specifies the type of data used to record the print job. + /// 0x05 + /// + /// + /// JOB_NOTIFY_FIELD_PRINT_PROCESSOR + /// pBuf is a pointer to a null-terminated string that specifies the name of the print processor to be used to print the job. + /// 0x06 + /// + /// + /// JOB_NOTIFY_FIELD_PARAMETERS + /// pBuf is a pointer to a null-terminated string that specifies print-processor parameters. + /// 0x07 + /// + /// + /// JOB_NOTIFY_FIELD_DRIVER_NAME + /// + /// pBuf is a pointer to a null-terminated string that specifies the name of the printer driver that should be used to process the + /// print job. + /// + /// 0x08 + /// + /// + /// JOB_NOTIFY_FIELD_DEVMODE + /// pBuf is a pointer to a DEVMODE structure that contains device-initialization and environment data for the printer driver. + /// 0x09 + /// + /// + /// JOB_NOTIFY_FIELD_STATUS + /// adwData [0] specifies the job status. For a list of possible values, see the JOB_INFO_2 structure. + /// 0x0A + /// + /// + /// JOB_NOTIFY_FIELD_STATUS_STRING + /// pBuf is a pointer to a null-terminated string that specifies the status of the print job. + /// 0x0B + /// + /// + /// JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR + /// Not supported. + /// 0x0C + /// + /// + /// JOB_NOTIFY_FIELD_DOCUMENT + /// pBuf is a pointer to a null-terminated string that specifies the name of the print job (for example, "MS-WORD: Review.doc"). + /// 0x0D + /// + /// + /// JOB_NOTIFY_FIELD_PRIORITY + /// adwData [0] specifies the job priority. + /// 0x0E + /// + /// + /// JOB_NOTIFY_FIELD_POSITION + /// adwData [0] specifies the job's position in the print queue. + /// 0x0F + /// + /// + /// JOB_NOTIFY_FIELD_SUBMITTED + /// pBuf is a pointer to a SYSTEMTIME structure that specifies the time when the job was submitted. + /// 0x10 + /// + /// + /// JOB_NOTIFY_FIELD_START_TIME + /// + /// adwData [0] specifies the earliest time that the job can be printed. (This value is specified in minutes elapsed since 12:00 A.M.) + /// + /// 0x11 + /// + /// + /// JOB_NOTIFY_FIELD_UNTIL_TIME + /// + /// adwData [0] specifies the latest time that the job can be printed. (This value is specified in minutes elapsed since 12:00 A.M.) + /// + /// 0x12 + /// + /// + /// JOB_NOTIFY_FIELD_TIME + /// adwData [0] specifies the total time, in seconds, that has elapsed since the job began printing. + /// 0x13 + /// + /// + /// JOB_NOTIFY_FIELD_TOTAL_PAGES + /// adwData [0] specifies the size, in pages, of the job. + /// 0x14 + /// + /// + /// JOB_NOTIFY_FIELD_PAGES_PRINTED + /// adwData [0] specifies the number of pages that have printed. + /// 0x15 + /// + /// + /// JOB_NOTIFY_FIELD_TOTAL_BYTES + /// adwData [0] specifies the size, in bytes, of the job. + /// 0x16 + /// + /// + /// JOB_NOTIFY_FIELD_BYTES_PRINTED + /// + /// adwData [0] specifies the number of bytes that have been printed on this job. For this field, the change notification object is + /// signaled when bytes are sent to the printer. + /// + /// 0x17 + /// + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/printer-notify-info-data typedef struct _PRINTER_NOTIFY_INFO_DATA { WORD + // Type; WORD Field; DWORD Reserved; DWORD Id; union { DWORD adwData[2]; struct { DWORD cbBuf; LPVOID pBuf; } Data; } NotifyData; } + // PRINTER_NOTIFY_INFO_DATA, *PPRINTER_NOTIFY_INFO_DATA; ; + [PInvokeData("winspool.h", MSDNShortId = "7a7b9e01-32e0-47f8-a5b1-5f7e6a663714")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct PRINTER_NOTIFY_INFO_DATA + { + /// + /// Indicates the type of information provided. This member can be one of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// JOB_NOTIFY_TYPE 0x01 + /// Indicates that the Field member specifies a JOB_NOTIFY_FIELD_* constant. + /// + /// + /// PRINTER_NOTIFY_TYPE 0x00 + /// Indicates that the Field member specifies a PRINTER_NOTIFY_FIELD_* constant. + /// + /// + /// + public NOTIFY_TYPE Type; + + /// Indicates the field that changed. For a list of possible values, see the Remarks section. + public ushort Field; + + /// Reserved. + public uint Reserved; + + /// + /// Indicates the job identifier if the Type member specifies JOB_NOTIFY_TYPE. If the Type member specifies + /// PRINTER_NOTIFY_TYPE, this member is undefined. + /// + public uint Id; + + /// + /// A union of data information based on the Type and Field members. For a description of the type of data + /// associated with each field, see the Remarks section. + /// + public NOTIFYDATA NotifyData; + + /// + /// A union of data information based on the Type and Field members. For a description of the type of data + /// associated with each field, see the Remarks section. + /// + [StructLayout(LayoutKind.Explicit)] + public struct NOTIFYDATA + { + /// + /// The first item in an array of two DWORD values. For information fields that use only a single DWORD, the data is in this field. + /// + [FieldOffset(0)] + public uint adwData0; + + /// The second item in an array of two DWORD values. + [FieldOffset(4)] + public uint adwData1; + + /// Contains variable length data. + [FieldOffset(0)] + public DATA Data; + + /// Contains variable length data. + [StructLayout(LayoutKind.Sequential)] + public struct DATA + { + /// Indicates the size, in bytes, of the buffer pointed to by pBuf. + public uint cbBuf; + + /// Pointer to a buffer that contains the field's current data. + public IntPtr pBuf; + } + } + } + + /// + /// The PRINTER_NOTIFY_OPTIONS structure specifies options for a change notification object that monitors a printer or print server. + /// + /// + /// + /// Use this structure with the FindFirstPrinterChangeNotification function to specify the set of printer or job information + /// fields to monitor for change. + /// + /// + /// Use this structure with the FindNextPrinterChangeNotification function to request the current data for all monitored + /// printer and job information fields. In this case, the Flags member specifies the PRINTER_NOTIFY_OPTIONS_REFRESH flag, and + /// the function ignores the other structure members. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/printer-notify-options typedef struct _PRINTER_NOTIFY_OPTIONS { DWORD + // Version; DWORD Flags; DWORD Count; PPRINTER_NOTIFY_OPTIONS_TYPE pTypes; } PRINTER_NOTIFY_OPTIONS, *PPRINTER_NOTIFY_OPTIONS; + [PInvokeData("", MSDNShortId = "712c546d-dbb3-4f78-b14e-fbb8619b57f9")] + [StructLayout(LayoutKind.Sequential)] + public struct PRINTER_NOTIFY_OPTIONS + { + /// The version of this structure. Set this member to 2. + public uint Version; + + /// + /// A bit flag. If you set the PRINTER_NOTIFY_OPTIONS_REFRESH flag in a call to the FindNextPrinterChangeNotification + /// function, the function provides current data for all monitored printer information fields. The + /// FindFirstPrinterChangeNotification function ignores the Flags member. + /// + public PRINTER_NOTIFY_OPTIONS_FLAG Flags; + + /// The number of elements in the pTypes array. + public uint Count; + + /// + /// A pointer to an array of PRINTER_NOTIFY_OPTIONS_TYPE structures. Use one element of this array to specify the printer + /// information fields to monitor, and one element to specify the job information fields to monitor. You can monitor either + /// printer information, job information, or both. + /// + public IntPtr pTypes; + } + + /// + /// + /// The PRINTER_NOTIFY_OPTIONS_TYPE structure specifies the set of printer or job information fields to be monitored by a + /// printer change notification object. + /// + /// + /// A call to the FindFirstPrinterChangeNotification function specifies a PRINTER_NOTIFY_OPTIONS structure, which + /// contains an array of PRINTER_NOTIFY_OPTIONS_TYPE structures. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/printer-notify-options-type typedef struct _PRINTER_NOTIFY_OPTIONS_TYPE + // { WORD Type; WORD Reserved0; DWORD Reserved1; DWORD Reserved2; DWORD Count; PWORD pFields; } PRINTER_NOTIFY_OPTIONS_TYPE, *PPRINTER_NOTIFY_OPTIONS_TYPE; + [PInvokeData("winspool.h", MSDNShortId = "1009f892-d3a8-4887-99b4-a35d1268eeb4")] + [StructLayout(LayoutKind.Sequential)] + public struct PRINTER_NOTIFY_OPTIONS_TYPE + { + /// + /// The type to be watched. This member can be one of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// JOB_NOTIFY_TYPE 0x01 + /// Indicates that the fields specified in the pFields array are JOB_NOTIFY_FIELD_* constants. + /// + /// + /// PRINTER_NOTIFY_TYPE 0x00 + /// Indicates that the fields specified in the pFields array are PRINTER_NOTIFY_FIELD_* constants. + /// + /// + /// + public NOTIFY_TYPE Type; + + /// Reserved. + public ushort Reserved0; + + /// Reserved. + public uint Reserved1; + + /// Reserved. + public uint Reserved2; + + /// The number of elements in the pFields array. + public uint Count; + + /// + /// A pointer to an array of values. Each element of the array specifies a job or printer information field of interest. For a + /// list of supported printer and job information fields, see the PRINTER_NOTIFY_INFO_DATA structure. + /// + public IntPtr pFields; + } + + /// Represents printer options. + // https://docs.microsoft.com/en-us/windows/win32/printdocs/printer-options typedef struct _PRINTER_OPTIONS { UINT cbSize; DWORD + // dwFlags; } PRINTER_OPTIONS, *PPRINTER_OPTIONS; + [PInvokeData("winspool.h", MSDNShortId = "7cc3d10c-8bc2-4899-b083-63d802ee16e7")] + [StructLayout(LayoutKind.Sequential)] + public struct PRINTER_OPTIONS + { + /// The size of the PRINTER_OPTIONS structure. + public uint cbSize; + + /// + /// A set of PRINTER_OPTION_FLAGS that specifies how the handle to a printer returned by OpenPrinter2 will be used + /// by other functions. + /// + public PRINTER_OPTION_FLAGS dwFlags; + } + + /// + /// The PRINTPROCESSOR_CAPS_1 structure is the format for the printer capability information that is returned by the + /// GetPrinterData function in the buffer specified by the pData variable. + /// + /// + /// + /// Values for all structure members are supplied by the GetPrintProcessorCapabilities function, which is documented in the + /// Windows Driver Kit (WDK). + /// + /// + /// The spooler calls a print processor's GetPrintProcessorCapabilities function when an application calls + /// GetPrinterData, specifying a value name with a format of PrintProcCaps_datatype, where datatype is the name of an input + /// data type. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/printprocessor-caps-1 typedef struct _PRINTPROCESSOR_CAPS_1 { DWORD + // dwLevel; DWORD dwNupOptions; DWORD dwPageOrderFlags; DWORD dwNumberOfCopies; } PRINTPROCESSOR_CAPS_1, *PPRINTPROCESSOR_CAPS_1; + [PInvokeData("winspool.h", MSDNShortId = "43c568ff-ccc9-4873-b159-ede09b4a7e51")] + [StructLayout(LayoutKind.Sequential)] + public struct PRINTPROCESSOR_CAPS_1 + { + /// The structure's version number. This value must be 1. + public uint dwLevel; + + /// + /// A bit mask representing the various numbers of document pages the printer can print on a physical page. The least + /// significant bit represents 1 document page per page, the next bit represents 2 document pages per page, and so on. For + /// example, 0x0000810B indicates the printer supports 1, 2, 4, 9, and 16 document pages per physical page. + /// + public uint dwNupOptions; + + /// The order in which pages will be printed. This value can be NORMAL_PRINT, REVERSE_PRINT, or BOOKLET_PRINT. + public uint dwPageOrderFlags; + + /// The maximum number of copies the printer can handle. + public uint dwNumberOfCopies; + } + + /// Represents printer capability information. + /// + /// + /// Values for all structure members are supplied by the GetPrintProcessorCapabilities function which is documented in the + /// Windows Driver Kit. + /// + /// + /// When an application calls GetPrinterData, the spooler calls a print processor's GetPrintProcessorCapabilities + /// function and specifies a value name that has a format of **PrintProcCaps_**datatype, where datatype is the name of an input data type. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/printprocessor-caps-2 typedef struct _PRINTPROCESSOR_CAPS_2 { DWORD + // dwLevel; DWORD dwNupOptions; DWORD dwPageOrderFlags; DWORD dwNumberOfCopies; DWORD dwNupDirectionCaps; DWORD dwNupBorderCaps; + // DWORD dwBookletHandlingCaps; DWORD dwDuplexHandlingCaps; DWORD dwScalingCaps; } PRINTPROCESSOR_CAPS_2, *PPRINTPROCESSOR_CAPS_2; + [PInvokeData("winspool.h", MSDNShortId = "70120739-a4e0-4b87-ac7a-40a42fb509ee")] + [StructLayout(LayoutKind.Sequential)] + public struct PRINTPROCESSOR_CAPS_2 + { + /// A value that indicates the structure's version number. + public uint dwLevel; + + /// + /// A bit mask representing the various numbers of document pages the printer can print on a single side of a physical sheet. + /// The least significant bit represents one document page per side, the next bit represents 2 document pages per side, and so + /// on. For example, 0x0000810B indicates the printer supports 1, 2, 4, 9, and 16 document pages per physical side. + /// + public uint dwNupOptions; + + /// + /// A flag value that indicates the order in which pages will be printed. It can be NORMAL_PRINT, REVERSE_PRINT, + /// or BOOKLET_PRINT. + /// + public uint dwPageOrderFlags; + + /// The maximum number of copies the printer can handle. + public uint dwNumberOfCopies; + + /// + /// + /// The available patterns when multiple document pages are printed on the same side of a sheet of paper. The possible flags are + /// the following: + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// PPCAPS_RIGHT_THEN_DOWN + /// Pages appear in rows from right to left, each subsequent row below its predecessor. + /// + /// + /// PPCAPS_DOWN_THEN_RIGHT + /// Pages appear in columns from top to bottom, each subsequent column to the right of its predecessor. + /// + /// + /// PPCAPS_LEFT_THEN_DOWN + /// Pages appear in rows from left to right, each subsequent row below its predecessor. + /// + /// + /// PPCAPS_DOWN_THEN_LEFT + /// Pages appear in columns from top to bottom, each subsequent column to the left of its predecessor. + /// + /// + /// + public PPCAPS_DIRECTION dwNupDirectionCaps; + + /// + /// Can be only PPCAPS_BORDER_PRINT, indicating that, when multiple document pages are being printed on a single side of a + /// physical sheet, the printer can be told whether or not to print a border around the imageable area of each document page. + /// + public PPCAPS_BORDER dwNupBorderCaps; + + /// Can only be PPCAPS_BOOKLET_EDGE, indicating that the printer can print booklet style. + public PPCAPS_EDGE dwBookletHandlingCaps; + + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// PPCAPS_REVERSE_PAGES_FOR_REVERSE_DUPLEX + /// + /// When printing in reverse order and duplexing, the processor can print swap the order of each pair of pages, so instead of + /// printing in order 4,3,2,1, they will print in the order 3,4,1,2. + /// + /// + /// + /// PPCAPS_DONT_SEND_EXTRA_PAGES_FOR_DUPLEX + /// + /// When duplexing, the Print Processor can be told not to send an extra page when there is an odd number of document pages. The + /// processor will honor the value as best as it can, but in cases where preventing an extra blank page would cause improper + /// output, the extra pages may still be sent. + /// + /// + /// + /// + public PPCAPS_DUPLEX dwDuplexHandlingCaps; + + /// Can only be PPCAPS_SQUARE_SCALING, indicating that the printer can scale the page image. + public PPCAPS_SCALING dwScalingCaps; + } + + /// The PRINTPROCESSOR_INFO_1 structure specifies the name of an installed print processor. + // https://docs.microsoft.com/en-us/windows/win32/printdocs/printprocessor-info-1 typedef struct _PRINTPROCESSOR_INFO_1 { LPTSTR + // pName; } PRINTPROCESSOR_INFO_1, *PPRINTPROCESSOR_INFO_1; + [PInvokeData("winspool.h", MSDNShortId = "49b272c8-156b-4996-b3fd-92cde831f4ae")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct PRINTPROCESSOR_INFO_1 + { + /// Pointer to a null-terminated string that specifies the name of an installed print processor. + [MarshalAs(UnmanagedType.LPTStr)] + public string pName; + } + + /// The PROVIDOR_INFO_1 structure identifies a print provider. + // https://docs.microsoft.com/en-us/windows/win32/printdocs/providor-info-1 typedef struct _PROVIDOR_INFO_1 { LPTSTR pName; LPTSTR + // pEnvironment; LPTSTR pDLLName; } PROVIDOR_INFO_1, *PPROVIDOR_INFO_1; + [PInvokeData("winspool.h", MSDNShortId = "0eff115a-b3d2-4c8f-b820-46e7f62dd295")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct PROVIDOR_INFO_1 + { + /// Pointer to a null-terminated string that is the name of the print provider. + [MarshalAs(UnmanagedType.LPTStr)] + public string pName; + + /// + /// Pointer to a null-terminated environment string specifying the environment the provider dynamic-link library (DLL) is + /// designed to run in. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pEnvironment; + + /// Pointer to a null-terminated string that is the name of the provider .dll. + [MarshalAs(UnmanagedType.LPTStr)] + public string pDLLName; + } + + /// The PROVIDOR_INFO_2 structure appends a print provider to the print provider order list. + /// + /// This structure is used when calling AddPrintProvidor, level 2, to add the specified print provider to the end of the + /// print provider order list. The provider is immediately used for routing if the call succeeds. + /// + // https://docs.microsoft.com/en-us/windows/win32/printdocs/providor-info-2 typedef struct _PROVIDOR_INFO_2 { LPTSTR pOrder; } + // PROVIDOR_INFO_2, *PPROVIDOR_INFO_2; + [PInvokeData("winspool.h", MSDNShortId = "840523ca-22d0-460f-81fb-e0a9e2d4f5d6")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct PROVIDOR_INFO_2 + { + /// Pointer to a null-terminated string that specifies the name of the print provider. + [MarshalAs(UnmanagedType.LPTStr)] + public string pOrder; + } + + /// Provides a for that is disposed using . + public class SafeHPRINTER : SafeHANDLE + { + /// Initializes a new instance of the class and assigns an existing handle. + /// An object that represents the pre-existing handle to use. + /// + /// to reliably release the handle during the finalization phase; otherwise, (not recommended). + /// + public SafeHPRINTER(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { } + + /// Initializes a new instance of the class. + private SafeHPRINTER() : base() { } + + /// Performs an implicit conversion from to . + /// The safe handle instance. + /// The result of the conversion. + public static implicit operator HPRINTER(SafeHPRINTER h) => h.handle; + + /// + protected override bool InternalReleaseHandle() => ClosePrinter(handle); + } + + /// Provides a for that is disposed using . + public class SafeHPRINTERCHANGENOTIFICATION : SafeHANDLE + { + /// + /// Initializes a new instance of the class and assigns an existing handle. + /// + /// An object that represents the pre-existing handle to use. + /// + /// to reliably release the handle during the finalization phase; otherwise, (not recommended). + /// + public SafeHPRINTERCHANGENOTIFICATION(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { } + + /// Initializes a new instance of the class. + private SafeHPRINTERCHANGENOTIFICATION() : base() { } + + /// Performs an implicit conversion from to . + /// The safe handle instance. + /// The result of the conversion. + public static implicit operator HPRINTERCHANGENOTIFICATION(SafeHPRINTERCHANGENOTIFICATION h) => h.handle; + + /// + protected override bool InternalReleaseHandle() => FindClosePrinterChangeNotification(handle); + } + + /// Provides a for that is disposed using . + public class SafeHSPOOLFILE : SafeHANDLE + { + private readonly HPRINTER hPrinter; + + /// Initializes a new instance of the class and assigns an existing handle. + /// The open printer handle. + /// An object that represents the pre-existing handle to use. + /// + /// to reliably release the handle during the finalization phase; otherwise, (not recommended). + /// + public SafeHSPOOLFILE(HPRINTER hPrinter, IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) => this.hPrinter = hPrinter; + + /// Initializes a new instance of the class. + private SafeHSPOOLFILE() : base() { } + + /// Performs an implicit conversion from to . + /// The safe handle instance. + /// The result of the conversion. + public static implicit operator HSPOOLFILE(SafeHSPOOLFILE h) => h.handle; + + /// Performs an implicit conversion from to . + /// The safe handle instance. + /// The result of the conversion. + public static implicit operator HFILE(SafeHSPOOLFILE h) => h.handle; + + /// + protected override bool InternalReleaseHandle() => CloseSpoolFileHandle(hPrinter, handle); + } + + /// + /// Represents the system allocated pointer to created by the + /// function. + /// + /// + public class SafePRINTER_NOTIFY_INFO : SafeHANDLE + { + private SafePRINTER_NOTIFY_INFO() : base() + { + } + + /// Performs an implicit conversion from to . + /// The h. + /// The result of the conversion. + public static implicit operator PRINTER_NOTIFY_INFO(SafePRINTER_NOTIFY_INFO h) => h.IsInvalid ? default : h.handle.ToStructure(); + + /// + /// Internal method that actually releases the handle. This is called by + /// for valid handles and afterwards zeros the handle. + /// + /// true to indicate successful release of the handle; false otherwise. + protected override bool InternalReleaseHandle() => FreePrinterNotifyInfo(handle); + } + + /* + DOCEVENT_CREATEDPRE + DOCEVENT_ESCAPE + DOCEVENT_CREATEDPRE + DOCEVENT_FILTER + */ + } +} \ No newline at end of file diff --git a/PInvoke/Shared/Lib.cs b/PInvoke/Shared/Lib.cs index 0f18193b..9167a273 100644 --- a/PInvoke/Shared/Lib.cs +++ b/PInvoke/Shared/Lib.cs @@ -81,6 +81,9 @@ /// The power profiling DLL. public const string PowrProf = "powrprof.dll"; + /// The prntvpt.dll + public const string PrntvPt = "prntvpt.dll"; + /// The property system public const string PropSys = "propsys.dll"; @@ -120,6 +123,9 @@ /// The win inet public const string WinInet = "wininet.dll"; + /// The winspool.dll + public const string Winspool = "winspool.drv"; + /// The wintrust.dll public const string Wintrust = "wintrust.dll"; diff --git a/UnitTests/PInvoke/Printing/Printing.csproj b/UnitTests/PInvoke/Printing/Printing.csproj new file mode 100644 index 00000000..79e290fc --- /dev/null +++ b/UnitTests/PInvoke/Printing/Printing.csproj @@ -0,0 +1,78 @@ + + + + + Debug + AnyCPU + {D2A4FD48-FCED-4E45-BBA0-C2D5CC536428} + Library + Properties + Vanara.PInvoke.Tests + UnitTest.PInvoke.Printing + v4.7.2 + 512 + latest + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + {241f73ee-9298-45c9-b869-a045dff94c03} + Vanara.Core + + + {842d436f-598c-47d7-b5aa-12399f8ccfe9} + Vanara.PInvoke.Kernel32 + + + {d3e1f2b8-d475-4922-b334-919795b858cb} + Vanara.PInvoke.Printing + + + {a5e519e9-feba-4fe3-93a5-b8269bef72f4} + Vanara.PInvoke.Shared + + + {a96cff10-0967-429a-8700-4a86c97c5603} + Shared + + + + + 3.12.0 + + + 3.15.1 + + + + + \ No newline at end of file diff --git a/UnitTests/PInvoke/Printing/PrintingTests.cs b/UnitTests/PInvoke/Printing/PrintingTests.cs new file mode 100644 index 00000000..fab036cf --- /dev/null +++ b/UnitTests/PInvoke/Printing/PrintingTests.cs @@ -0,0 +1,248 @@ +using NUnit.Framework; +using NUnit.Framework.Constraints; +using System; +using System.Collections; +using System.Linq; +using Vanara.Extensions; +using static Vanara.PInvoke.WinSpool; + +namespace Vanara.PInvoke.Tests +{ + [TestFixture] + public class PrintingTests + { + private const string connPtrName = "Foobar"; + private const string defKey = "PrinterDriverData"; + private static readonly string defaultPrinterName = new System.Drawing.Printing.PrinterSettings().PrinterName; + private SafeHPRINTER hprnt; + + [OneTimeSetUp] + public void _Setup() => Assert.That(OpenPrinter(defaultPrinterName, out hprnt), ResultIs.Successful); + + [OneTimeTearDown] + public void _TearDown() => hprnt?.Dispose(); + + [Test] + public void AddPrinterTest() + { + const string key = "TestOnly"; + const string name = "TestOnlyPrinter"; + var pi = GetPrinter(hprnt); + var pi2 = new PRINTER_INFO_2 + { + pPrinterName = name, + pPortName = "LPT1:", + pDriverName = pi.pDriverName, + pPrintProcessor = pi.pPrintProcessor, + Attributes = PRINTER_ATTRIBUTE.PRINTER_ATTRIBUTE_LOCAL + }; + var p2 = new SafeHPRINTER(default, false); + try + { + Assert.That(p2 = AddPrinter(null, 2, pi2), ResultIs.ValidHandle); + GetSet("Test", 123, 123U); + GetSet("Test", 123L, 123UL); + GetSet("Test", "123"); + GetSet("Test", new byte[] { 1, 2, 3 }); + GetSet("Test", new[] { "1", "2", "3" }); + GetSet("Test", 123, 123U, REG_VALUE_TYPE.REG_DWORD_BIG_ENDIAN); + // Test serializable + var sz = new System.Drawing.Size(4, 4); + GetSet("Test", sz, new byte[] { 4, 0, 0, 0, 4, 0, 0, 0 }); + + Assert.That(() => SetPrinterData(p2, "Test8", 1, REG_VALUE_TYPE.REG_LINK), Throws.Exception); + Assert.That(() => SetPrinterData(p2, "Test8", 1, REG_VALUE_TYPE.REG_RESOURCE_LIST), Throws.Exception); + Assert.That(ResetPrinter(p2, new PRINTER_DEFAULTS { pDatatype = pi.pDatatype }), ResultIs.Successful); + } + finally + { + Assert.That(DeletePrinter(p2), ResultIs.Successful); + } + + void GetSet(string vn, object v, object r = null, REG_VALUE_TYPE t = REG_VALUE_TYPE.REG_NONE) + { + if (r is null) r = v; + Assert.That(SetPrinterData(p2, vn, v, t), ResultIs.Successful); + Assert.That(GetPrinterData(p2, vn), v.GetType().IsArray ? (IResolveConstraint)Is.EquivalentTo((IEnumerable)r) : Is.EqualTo(r)); + Assert.That(DeletePrinterData(p2, vn), ResultIs.Successful); + Assert.That(SetPrinterDataEx(p2, key, vn, v, t), ResultIs.Successful); + Assert.That(GetPrinterDataEx(p2, key, vn), v.GetType().IsArray ? (IResolveConstraint)Is.EquivalentTo((IEnumerable)r) : Is.EqualTo(r)); + Assert.That(DeletePrinterDataEx(p2, key, vn), ResultIs.Successful); + Assert.That(DeletePrinterKey(p2, key), ResultIs.Successful); + } + } + + [Test] + public void AddPrinterConnectionTest() + { + Assert.That(AddPrinterConnection(connPtrName), ResultIs.Successful); + Assert.That(DeletePrinterConnection(connPtrName), ResultIs.Successful); + } + + [Test] + public void AddPrinterConnection2Test() + { + var drv = GetPrinter(hprnt).pDriverName; + Assert.That(AddPrinterConnection2(default, connPtrName, PRINTER_CONNECTION_FLAGS.PRINTER_CONNECTION_MISMATCH, drv), ResultIs.Successful); + Assert.That(DeletePrinterConnection(connPtrName), ResultIs.Successful); + } + + [Test] + public void AdvancedDocumentPropertiesTest() + { + var devmodeOut = DEVMODE.Default; + Assert.That(AdvancedDocumentProperties(HWND.NULL, hprnt, defaultPrinterName, ref devmodeOut, DEVMODE.Default), ResultIs.Successful); + Assert.That(AdvancedDocumentProperties(HWND.NULL, hprnt, defaultPrinterName), ResultIs.Successful); + } + + [Test] + public void ConnectToPrinterDlgTest() + { + SafeHPRINTER p; + Assert.That(p = ConnectToPrinterDlg(HWND.NULL), ResultIs.ValidHandle); + p.Dispose(); + } + + [Test] + public void EnumFormsTest() + { + FORM_INFO_1[] res1; + Assert.That(res1 = EnumForms(hprnt).ToArray(), Is.Not.Empty); + TestContext.WriteLine(string.Join(",", res1.Select(v => v.pName))); + FORM_INFO_2[] res2; + Assert.That(res2 = EnumForms(hprnt).ToArray(), Is.Not.Empty); + TestContext.WriteLine(string.Join(",", res2.Select(v => v.Flags))); + } + + [Test] + public void EnumJobsTest() + { + Assert.That(EnumJobs(hprnt), Is.Empty); + Assert.That(EnumJobs(hprnt), Is.Empty); + Assert.That(EnumJobs(hprnt), Is.Empty); + Assert.That(EnumJobs(hprnt), Is.Empty); + } + + [Test] + public void EnumPrinterDataExTest() + { + var res1 = EnumPrinterDataEx(hprnt, defKey); + Assert.That(res1, Is.Not.Empty); + TestContext.WriteLine(string.Join(",", res1.Select(v => $"{v.valueName}={v.value} ({v.valueType})"))); + } + + [Test] + public void EnumPrinterDataTest() + { + var res1 = EnumPrinterData(hprnt); + Assert.That(res1, Is.Not.Empty); + TestContext.WriteLine(string.Join(",", res1.Select(v => $"{v.valueName}={v.value} ({v.valueType})"))); + } + + [Test] + public void EnumPrinterKeyTest() + { + string[] res1; + Assert.That(res1 = EnumPrinterKey(hprnt, "").ToArray(), Is.Not.Empty); + TestContext.WriteLine(string.Join(",", res1)); + } + + [Test] + public void EnumPrintersTest() + { + PRINTER_INFO_1[] res1; + Assert.That(res1 = EnumPrinters().ToArray(), Is.Not.Empty); + TestContext.WriteLine(string.Join(",", res1.Select(v => v.pName))); + PRINTER_INFO_2[] res2; + Assert.That(res2 = EnumPrinters().ToArray(), Is.Not.Empty); + TestContext.WriteLine(string.Join(",", res2.Select(v => v.Status))); + //PRINTER_INFO_3[] res3; + //Assert.That(res3 = EnumPrinters().ToArray(), Is.Not.Empty); + PRINTER_INFO_4[] res4; + Assert.That(res4 = EnumPrinters().ToArray(), Is.Not.Empty); + TestContext.WriteLine(string.Join(",", res4.Select(v => v.Attributes))); + PRINTER_INFO_5[] res5; + Assert.That(res5 = EnumPrinters().ToArray(), Is.Not.Empty); + TestContext.WriteLine(string.Join(",", res5.Select(v => v.pPortName))); + //PRINTER_INFO_6[] res6; + //Assert.That(res6 = EnumPrinters().ToArray(), Is.Not.Empty); + //PRINTER_INFO_7[] res7; + //Assert.That(res7 = EnumPrinters().ToArray(), Is.Not.Empty); + //PRINTER_INFO_8[] res8; + //Assert.That(res8 = EnumPrinters().ToArray(), Is.Not.Empty); + //PRINTER_INFO_9[] res9; + //Assert.That(res9 = EnumPrinters().ToArray(), Is.Not.Empty); + } + + [Test] + public void FormTest() + { + const string name = "TestOnlyForm"; + var form1 = EnumForms(hprnt).First(); + form1.pName = name; + form1.Flags = FormFlags.FORM_USER; + Assert.That(AddForm(hprnt, form1), ResultIs.Successful); + try + { + FORM_INFO_2 fi2 = default; + Assert.That(() => fi2 = GetForm(hprnt, name), Throws.Nothing); + Assert.That(fi2.Flags, Is.EqualTo(FormFlags.FORM_USER)); + TestHelper.WriteValues(fi2); + + form1.Size = new SIZE(form1.Size.cx / 2, form1.Size.cy / 2); + Assert.That(SetForm(hprnt, name, form1), ResultIs.Successful); + } + finally + { + Assert.That(DeleteForm(hprnt, name), ResultIs.Successful); + } + } + + [Test] + public void JobTest() + { + Assert.That(AddJob(hprnt, out var path, out var id), ResultIs.Successful); + try + { + System.IO.File.WriteAllText(path, "Test page."); + + JOB_INFO_2 ji2 = default; + Assert.That(() => ji2 = GetJob(hprnt, id), Throws.Nothing); + Assert.That(ji2.JobId, Is.EqualTo(id)); + TestHelper.WriteValues(ji2); + + var jobInfo = new JOB_INFO_1 { JobId = id, Priority = JOB_PRIORITY.MAX_PRIORITY, Status = ji2.Status, pDatatype = ji2.pDatatype }; + Assert.That(SetJob(hprnt, id, jobInfo), ResultIs.Successful); + + Assert.That(ScheduleJob(hprnt, id), ResultIs.Successful); + } + finally + { + Assert.That(SetJob(hprnt, id, JOB_CONTROL.JOB_CONTROL_DELETE), ResultIs.Successful); + } + } + + [Test] + public void PortTest() + { + var port = GetPrinter(hprnt).pPortName; + + Assert.That(ConfigurePort(null, HWND.NULL, port), ResultIs.Successful); + + Assert.That(SetPort(null, port, PORT_STATUS.PORT_STATUS_OFFLINE, PORT_STATUS_TYPE.PORT_STATUS_TYPE_ERROR), ResultIs.Successful); + Assert.That(SetPort(null, port, "Off-line", PORT_STATUS_TYPE.PORT_STATUS_TYPE_ERROR), ResultIs.Successful); + Assert.That(SetPort(null, port, 0, 0), ResultIs.Successful); + } + + [Test] + public void SpoolFileTest() + { + var hspf = GetSpoolFileHandle(hprnt); + Assert.That(hspf, ResultIs.ValidHandle); + var bytes = new byte[] { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 }; + Kernel32.WriteFile(hspf, bytes, (uint)bytes.Length, out _); + Assert.That(CommitSpoolData(hprnt, hspf, (uint)bytes.Length), ResultIs.Successful); + Assert.That(() => hspf.Dispose(), Throws.Nothing); + } + } +} \ No newline at end of file diff --git a/Vanara.sln b/Vanara.sln index e498c14b..0d897105 100644 --- a/Vanara.sln +++ b/Vanara.sln @@ -181,6 +181,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExplorerBrowserDemo", "Unit EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Windows.Forms.App", "UnitTests\Windows.Forms.App\Windows.Forms.App.csproj", "{9520EC8B-9C63-47E6-A7BD-1CCF9BBB5BFA}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vanara.PInvoke.Printing", "PInvoke\Printing\Vanara.PInvoke.Printing.csproj", "{D3E1F2B8-D475-4922-B334-919795B858CB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Printing", "UnitTests\PInvoke\Printing\Printing.csproj", "{D2A4FD48-FCED-4E45-BBA0-C2D5CC536428}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug (no Unit Tests)|Any CPU = Debug (no Unit Tests)|Any CPU @@ -597,6 +601,18 @@ Global {9520EC8B-9C63-47E6-A7BD-1CCF9BBB5BFA}.Debug|Any CPU.Build.0 = Debug|Any CPU {9520EC8B-9C63-47E6-A7BD-1CCF9BBB5BFA}.Release|Any CPU.ActiveCfg = Release|Any CPU {9520EC8B-9C63-47E6-A7BD-1CCF9BBB5BFA}.Release|Any CPU.Build.0 = Release|Any CPU + {D3E1F2B8-D475-4922-B334-919795B858CB}.Debug (no Unit Tests)|Any CPU.ActiveCfg = Debug|Any CPU + {D3E1F2B8-D475-4922-B334-919795B858CB}.Debug (no Unit Tests)|Any CPU.Build.0 = Debug|Any CPU + {D3E1F2B8-D475-4922-B334-919795B858CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D3E1F2B8-D475-4922-B334-919795B858CB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D3E1F2B8-D475-4922-B334-919795B858CB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D3E1F2B8-D475-4922-B334-919795B858CB}.Release|Any CPU.Build.0 = Release|Any CPU + {D2A4FD48-FCED-4E45-BBA0-C2D5CC536428}.Debug (no Unit Tests)|Any CPU.ActiveCfg = Debug|Any CPU + {D2A4FD48-FCED-4E45-BBA0-C2D5CC536428}.Debug (no Unit Tests)|Any CPU.Build.0 = Debug|Any CPU + {D2A4FD48-FCED-4E45-BBA0-C2D5CC536428}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D2A4FD48-FCED-4E45-BBA0-C2D5CC536428}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D2A4FD48-FCED-4E45-BBA0-C2D5CC536428}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D2A4FD48-FCED-4E45-BBA0-C2D5CC536428}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -675,6 +691,8 @@ Global {687F9162-8CA0-4277-B868-4E7F2EC614F8} = {3EC6B40D-71D3-4E59-A0E0-544EC605FE11} {2AACFF7E-F4B1-44F6-92C6-20ACBB647A4D} = {3EC6B40D-71D3-4E59-A0E0-544EC605FE11} {9520EC8B-9C63-47E6-A7BD-1CCF9BBB5BFA} = {3EC6B40D-71D3-4E59-A0E0-544EC605FE11} + {D3E1F2B8-D475-4922-B334-919795B858CB} = {212ABBD0-B724-4CFA-9D6D-E3891547FA90} + {D2A4FD48-FCED-4E45-BBA0-C2D5CC536428} = {385CAD2D-0A5E-4F80-927B-D5499D126B90} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {543FAC75-2AF1-4EF1-9609-B242B63FEED4}