Guida alla progettazione dell'API Print Support Application v3
Questo articolo fornisce indicazioni ed esempi per gli OEM e i produttori di hardware indipendenti (IHV) che implementano un'applicazione v3 di supporto alla stampa (PSA) per il loro dispositivo.
Terminologia
Termine | Definizione |
---|---|
PSA | Applicazione di Supporto per la Stampa App UWP che utilizza l'API presente in questo documento. |
IPP | Protocollo di stampa Internet. Utilizzato da un dispositivo client per interagire con la stampante per recuperare e impostare le preferenze di stampa e inviare il documento da stampare. |
Stampa supporto stampante associato | Stampante IPP fisica collegata a PSA. |
Stampante IPP | Stampante che supporta il protocollo IPP. |
PDL | Lingua della descrizione della pagina. Formato in cui un documento viene inviato alla stampante. |
Stampante PSA associata | Stampante IPP fisica associata a un'applicazione PSA. |
Capacità Dispositivo di Stampa | Formato documento XML per la definizione delle funzionalità della stampante. |
PrintSupportExtension | Attività in background PSA responsabile della fornitura di funzionalità di estensione dei vincoli della stampante. |
API di supporto per la stampa v3
Questo articolo contiene le estensioni v3 per l'API pubblica dell'applicazione di supporto alla stampa esistente descritta nella Guida alla progettazione dell'applicazione di supporto alla stampa e Windows.Graphics.Printing.PrintSupport Spazio dei nomi. L'API PSA consente ai produttori di stampanti di sviluppare applicazioni di supporto hardware in grado di migliorare l'esperienza di stampa di un utente Windows durante l'uso del driver di classe Microsoft IPP integrato senza la necessità di sviluppare un driver personalizzato. I componenti di stampa comunicano con l'app PSA tramite un processo broker PSA.
Per altre informazioni, vedere gli articoli seguenti:
Argomento | Descrizione |
---|---|
Guida alla Progettazione dell'App di Supporto per la Stampa | Fornisce indicazioni ed esempi per gli OEM e i fornitori indipendenti di hardware che implementano un'app di supporto per la stampa (PSA) per il loro dispositivo. |
Guida alla progettazione dell'API di Supporto Stampa v4 | Fornisce indicazioni ed esempi per gli OEM e i fornitori indipendenti di hardware (IHVs) che implementano un'app di supporto per la stampa v4 (PSA) per i loro dispositivi. |
specifica del manifesto MSIX per la stampante virtuale di supporto di stampa | Fornisce una guida al manifesto MSIX ed esempi per i produttori OEM e IHV di stampanti che implementano una stampante virtuale di supporto alla stampa. |
l'associazione dell'app di supporto di stampa | Fornisce indicazioni ed esempi per l'associazione di un'app di supporto di stampa (PSA) a una stampante. |
Le estensioni significative per l'API sono le seguenti:
di compressione IPP : l'API PSA v3 aggiunge una funzionalità per migliorare la stampa IPP aggiungendo una funzionalità di compressione IPP in un processo di stampa per stampanti IPP che supportano questa funzionalità. Alcuni PSA potrebbero avere una compressione personalizzata, il che significa che il processo IPP ha una doppia compressione che influisce sulle prestazioni. Per attenuare questo problema, l'API PSA v3 introduce una proprietà IsIppCompressionEnabled e una funzione DisableIppCompressionForJob (per disabilitare la compressione per il processo corrente, se necessario) nella classe di runtime PrintWorkflowJobStartingEventArgs (API PSA v1).
gestione degli errori del processo IPP e notifica di errore - L'API PSA v3 introduce un evento JobIssueDetected in PrintWorkflowJobBackgroundSession (API PSA v1). L'evento viene generato ogni volta che PSA rileva un errore o un avviso nel processo di stampa. PSA è quindi responsabile della visualizzazione del messaggio di errore all'utente. Quando PSA esegue la registrazione per questo evento e imposta proprietà SkipSystemErrorToast su true in PrintWorkflowJobIssueDetectedEventArgs, indica al sistema di stampa di non visualizzare l'avviso popup del sistema di stampa Windows. L'API PSA v3 fornisce anche un meccanismo per PSA per avviare l'interfaccia utente quando l'utente interagisce con la notifica popup.
timeout di comunicazione IPP personalizzati - PSA v3 API fornisce un'API con cui un PSA può eseguire l'override dei timeout IPP. Inoltre, la classe di runtime
PrintSupportIppCommunicationConfiguration viene aggiunta a per modificare i timeout di comunicazione IPP. Inoltre, l'API PSA v3 introduce un evento, che viene generato quando si verifica un errore con la comunicazione IPP. L'evento è stato introdotto in modo che IHV possa analizzare l'errore e regolare i valori di timeout di conseguenza.PrintSupportPrintDeviceCapabilitiesChangedEventArgs Supporto IPPFaxOut - L'API PSA v3 aggiunge una funzionalità al sistema di stampa per supportare le stampanti IPPFaxOut. Per supportare Fax, PSA supporta un filtro di rendering per convertire XPS in Tiff. Poiché PSA potrebbe modificare il contenuto XPS prima della conversione in TIFF, fornisce il valore dell'enumerazione XpsToTiff in PrintWorkflowPdlConversionType in modo che PSA possa avere accesso al convertitore da XPS a TIFF. Fornisce inoltre la proprietà
IsIPPFaxOutPrinter per in modo che PSA possa distinguere tra le stampanti standard e le stampanti IPPFaxOut.classe di runtime IppPrintDevice
Disabilitazione della compressione IPP
La compressione IPP è illustrata nell'esempio di codice seguente.
public sealed class PrintSupportWorkflowBackgroundTask : IBackgroundTask
{
public BackgroundTaskDeferral TaskInstanceDeferral { get; set; }
private PrintWorkflowJobBackgroundSession session;
public void Run(IBackgroundTaskInstance taskInstance)
{
TaskInstanceDeferral = taskInstance.GetDeferral();
if (taskInstance.TriggerDetails is PrintWorkflowJobTriggerDetails jobDetails)
{
session = jobDetails.PrintWorkflowJobSession;
session.JobStarting += OnJobStarting;
session.PdlModificationRequested += OnPdlModificationRequested;
session.JobIssueDetected += OnJobIssueDetected;
// Make sure to register all the event handlers before PrintWorkflowJobBackgroundSession.Start is called.
session.Start();
}
}
private void OnJobStarting(PrintWorkflowJobBackgroundSession sender, PrintWorkflowJobStartingEventArgs args)
{
using (args.GetDeferral())
{
// Skip system rendering.
args.SetSkipSystemRendering();
// If Ipp compression is enabled by the system, check to see if PSA does custom compression for the printer
// and disable system compression if required.
if (args.IsIppCompressionEnabled)
{
if (this.HasCustomCompression(args.Printer))
{
args.DisableIppCompressionForJob();
}
}
}
}
bool HasCustomCompression(IppPrintDevice device)
{
bool hasCustomCompression = false;
// Check if the PSA does custom compression for the printer
return hasCustomCompression;
}
}
Gestione degli errori delle attività IPP
Questo esempio illustra come l'app PSA può registrarsi per gli errori del lavoro, visualizzare le notifiche toast per gli errori del lavoro e avviare l'interfaccia utente quando l'utente attiva le notifiche toast.
public sealed class PrintSupportWorkflowBackgroundTask : IBackgroundTask
{
public BackgroundTaskDeferral TaskInstanceDeferral { get; set; }
private PrintWorkflowJobBackgroundSession session;
public void Run(IBackgroundTaskInstance taskInstance)
{
TaskInstanceDeferral = taskInstance.GetDeferral();
if (taskInstance.TriggerDetails is PrintWorkflowJobTriggerDetails jobDetails)
{
session = jobDetails.PrintWorkflowJobSession;
session.JobStarting += OnJobStarting;
session.PdlModificationRequested += OnPdlModificationRequested;
session.JobIssueDetected += OnJobIssueDetected;
// Make sure to register all the event handlers before PrintWorkflowJobBackgroundSession.Start is called.
session.Start();
}
}
private void OnJobIssueDetected (PrintWorkflowJobBackgroundSession sender, PrintWorkflowJobIssueDetectedEventArgs args)
{
// Using a deferral to exclude the background process from being suspended while PSA displays UI.
Deferral deferral = args.GetDeferral();
var toast = new ToastNotification(GetErrorToastXml(args.ExtendedError,
args.JobIssueKind, args.PrinterJob, args.Configuration));
toast.Activated += async (toastSender, e) =>
{
// PSA UI application
PrintWorkflowUICompletionStatus uiStatus = await args.UILauncher.LaunchAndCompleteUIAsync();
// Complete deferral
deferral.Complete();
};
toast.Dismissed += async (toastSender, e) => { deferral.Complete(); };
toast.Failed += async (toastSender, e) => { deferral.Complete(); };
ToastNotificationManager.CreateToastNotifier().Show(toast);
args.SkipSystemErrorToast = true;
}
private XmlDocument GetErrorToastXml(Exception jobError, PrintWorkflowJobIssueKind issueKind,
PrintWorkflowPrinterJob printerJob, PrintWorkflowConfiguration workflowConfig )
{
var errorToastXml = new XmlDocument();
// Generate Toast Xml based on error information from Exception and PrintWorkflowPrinterJob.
return errorToastXml;
}
}
Impostazione del timeout delle comunicazioni IPP
Questo esempio illustra come impostare il timeout di comunicazione IPP.
public sealed class PrintSupportExtensionBackGroundTask : IBackgroundTask
{
public BackgroundTaskDeferral TaskInstanceDeferral { get; set; }
private PrintSupportExtensionSession session;
public void Run(IBackgroundTaskInstance taskInstance)
{
taskInstance.Canceled += OnTaskInstanceCanceled;
TaskInstanceDeferral = taskInstance.GetDeferral();
if (taskInstance.TriggerDetails is PrintSupportExtensionTriggerDetails extensionDetails)
{
session = extensionDetails.Session;
session.PrintTicketValidationRequested += OnSessionPrintTicketValidationRequested;
session.PrintDeviceCapabilitiesChanged += OnSessionPrintDeviceCapabilitiesChanged;
session.CommunicationErrorDetected += OnCommunicationErrorDetected;
// Make sure to register all the event handlers before PrintSupportExtensionSession.Start is called.
session.Start();
}
}
private void OnTaskInstanceCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
{
session = null;
TaskInstanceDeferral.Complete();
}
private void OnSessionPrintDeviceCapabilitiesChanged(PrintSupportExtensionSession sender, PrintSupportPrintDeviceCapabilitiesChangedEventArgs args)
{
// Using deferral to exclude the background process from being suspended while PSA updates the printer PDC and other configurations.
using (args.GetDeferral())
{
if (args.CommunicationConfiguration.CanModifyTimeouts)
{
this.UpdateAttributeTimeouts(args.CommunicationConfiguration, sender.Printer);
this.UpdateJobTimeouts(args.CommunicationConfiguration, sender.Printer);
}
// Do other operations, such as Updating PDC, PDR, and so on here.
}
}
void UpdateAttributeTimeouts(PrintSupportIppCommunicationConfiguration config, IppPrintDevice device)
{
IppPrinterCommunicationKind communicationKind = config.CommunicationKind;
PrintSupportIppCommunicationTimeouts currentTimeouts = config.IppAttributeTimeouts;
// Adjust attribute timeouts based on the printer
switch (communicationKind)
{
case IppPrinterCommunicationKind.Network:
currentTimeouts.ConnectTimeout = TimeSpan.FromSeconds(10);
currentTimeouts.SendTimeout = TimeSpan.FromSeconds(10);
currentTimeouts.ReceiveTimeout = TimeSpan.FromSeconds(10);
break;
case IppPrinterCommunicationKind.UniversalPrint:
// adjust timeout for universal printer
break;
}
}
void UpdateJobTimeouts(
PrintSupportIppCommunicationConfiguration config, IppPrintDevice device)
{
IppPrinterCommunicationKind communicationKind = config.CommunicationKind;
PrintSupportIppCommunicationTimeouts currentTimeouts = config.IppJobTimeouts;
// Adjust job timeouts based on the printer and communication type
switch (communicationKind)
{
case IppPrinterCommunicationKind.Network:
currentTimeouts.ConnectTimeout = TimeSpan.FromSeconds(30);
currentTimeouts.SendTimeout = TimeSpan.FromSeconds(30);
currentTimeouts.ReceiveTimeout = TimeSpan.FromSeconds(30);
break;
case IppPrinterCommunicationKind.UniversalPrint:
// adjust timeout for universal printer
break;
}
}
}
Gestione degli errori di comunicazione IPP
Questo esempio illustra come gestire gli errori di comunicazione IPP.
public sealed class PrintSupportExtensionBackGroundTask : IBackgroundTask
{
public BackgroundTaskDeferral TaskInstanceDeferral { get; set; }
private PrintSupportExtensionSession session;
public void Run(IBackgroundTaskInstance taskInstance)
{
taskInstance.Canceled += OnTaskInstanceCanceled;
TaskInstanceDeferral = taskInstance.GetDeferral();
if (taskInstance.TriggerDetails is PrintSupportExtensionTriggerDetails extensionDetails)
{
session = extensionDetails.Session;
session.PrintTicketValidationRequested += OnSessionPrintTicketValidationRequested;
session.PrintDeviceCapabilitiesChanged += OnSessionPrintDeviceCapabilitiesChanged;
session.CommunicationErrorDetected += OnCommunicationErrorDetected ;
// Make sure to register all the event handlers before PrintSupportExtensionSession.Start is called.
session.Start();
}
}
private void OnTaskInstanceCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
{
session = null;
TaskInstanceDeferral.Complete();
}
private void OnCommunicationErrorDetected(PrintSupportExtensionSession sender, PrintSupportCommunicationErrorDetectedEventArgs args)
{
// Using deferral to exclude the background process from being suspended while PSA updates the timeouts.
using (args.GetDeferral())
{
if (args.ErrorKind == IppCommunicationErrorKind.Timeout)
{
PrintSupportIppCommunicationConfiguration ippConfig = args.CommunicationConfiguration;
IppPrintDevice device = sender.Printer;
// Update timeout based on the communication error
}
}
}
}
Stampa su stampante fax IPP in PSA
Questo esempio illustra come stampare su una stampante IPPFaxOut in un ambiente PSA.
public sealed class PrintSupportWorkflowBackgroundTask : IBackgroundTask
{
public BackgroundTaskDeferral TaskInstanceDeferral { get; set; }
private PrintWorkflowJobBackgroundSession session;
public void Run(IBackgroundTaskInstance taskInstance)
{
TaskInstanceDeferral = taskInstance.GetDeferral();
if (taskInstance.TriggerDetails is PrintWorkflowJobTriggerDetails jobDetails)
{
session = jobDetails.PrintWorkflowJobSession;
session.JobStarting += OnJobStarting;
session.PdlModificationRequested += OnPdlModificationRequested;
session.JobIssueDetected += OnJobIssueDetected;
// Make sure to register all the event handlers before PrintWorkflowJobBackgroundSession.Start is called.
session.Start();
}
}
private async void OnPdlModificationRequested(PrintWorkflowJobBackgroundSession sender, PrintWorkflowPdlModificationRequestedEventArgs args)
{
using (args.GetDeferral())
{
IppPrintDevice printer = args.PrinterJob.Printer;
IInputStream xpsContent = args.SourceContent.GetInputStream();
WorkflowPrintTicket printTicket = args.PrinterJob.GetJobPrintTicket();
string documentFormat = this.GetPrinterDocumentFormat(printer);
PrintWorkflowPdlTargetStream targetStream = args.CreateJobOnPrinter(documentFormat);
IInputStream xpsSourceContent = xpsContent;
if (printer.IsIPPFaxOutPrinter)
{
// Add cover page to XPS source document
xpsSourceContent = this.AddCoverPageToXpsContent(xpsContent);
}
PrintWorkflowPdlConverter pdlConverter;
switch (documentFormat.ToLowerInvariant())
{
case "image/pwg-raster":
pdlConverter = args.GetPdlConverter(PrintWorkflowPdlConversionType.XpsToPwgr);
break;
case "application/pclm":
pdlConverter = args.GetPdlConverter(PrintWorkflowPdlConversionType.XpsToPclm);
break;
case "application/pdf":
pdlConverter = args.GetPdlConverter(PrintWorkflowPdlConversionType.XpsToPdf);
break;
case "image/tiff":
pdlConverter = args.GetPdlConverter(PrintWorkflowPdlConversionType.XpsToTiff);
break;
default:
// This should not happen, aborting workflow if PSA does not identify the supported PDLs
args.Configuration.AbortPrintFlow(PrintWorkflowJobAbortReason.JobFailed);
return;
}
// Use pdlConverter to convert the source XPS stream to printer's document format and send it to the printer using targetStream.
await pdlConverter.ConvertPdlAsync(printTicket, xpsSourceContent, targetStream.GetOutputStream());
targetStream.CompleteStreamSubmission(PrintWorkflowSubmittedStatus.Succeeded);
}
}
private IInputStream AddCoverPageToXpsContent(IInputStream xpsStream)
{
var coverPageXps = new InMemoryRandomAccessStream();
// Add cover page to XPS content and write to coverPageXps stream
return coverPageXps;
}
}
Disabilitazione dell'interfaccia utente fax per il numero di telefono proveniente da PSA
Con il supporto della stampante fax IPP, questo esempio mostra un'interfaccia utente per richiedere all'utente di immettere il numero fax durante la stampa sulla stampante Fax. Ma il PSA potrebbe voler mostrare la propria interfaccia utente con altre informazioni e opzioni. È fonte di confusione per l'utente se sono presenti due interfacce utente per fax; questo esempio illustra un'opzione per un PSA per disabilitare l'interfaccia utente del sistema quando vogliono mostrare la loro interfaccia utente fax.
L'esempio seguente illustra l'utilizzo dell'API.
public sealed class PrintSupportWorkflowBackgroundTask : IBackgroundTask
{
private void OnJobStarting(PrintWorkflowJobBackgroundSession sender, PrintWorkflowJobStartingEventArgs args)
{
using (args.GetDeferral())
{
// If the job is printing to an Ipp fax printer,
// check whether PSA has a custom UI and disable system UI for getting the fax number.
if (args.IsIPPFaxOutPrinter)
{
if (this.HasCustomUIForFax(args.Printer))
{
args.SkipSystemFaxUI = true;
}
}
}
}
bool HasCustomUIForFax(IppPrintDevice device)
{
bool hasCustomUIForFax = false;
// Check if the PSA does custom UI for the given fax printer.
return hasCustomUIForFax;
}
}
Osservazioni
Gli esempi in questo articolo sono basati sugli esempi delle API PSA v1 e v2 nella guida alla progettazione dell'app di supporto di stampa presupponendo che lo sviluppatore abbia familiarità con il flusso di lavoro dell'API PSA.
Questo articolo contiene le estensioni per l'API di supporto di stampa pubblica esistente descritta nella Guida alla progettazione dell'app di supporto di stampa e spazio dei nomi Windows.Graphics.Printing.PrintSupport. L'API PSA consente ai produttori di stampanti di sviluppare app UWP in grado di migliorare l'esperienza di stampa degli utenti di Windows durante l'uso del driver di classe Microsoft IPP, senza la necessità di sviluppare un driver personalizzato.
I componenti di stampa comunicano con l'app PSA tramite un processo broker PSA.
Articoli correlati
Piano di fine supporto per i driver di stampante di terze parti su Windows
PrintSupportIppCommunicationConfiguration
PrintSupportPrintDeviceCapabilitiesChangedEventArgs
PrintWorkflowJobBackgroundSession
PrintWorkflowJobIssueDetectedEventArgs
PrintWorkflowJobStartingEventArgs