Come gestire i processi di stampa in un'app per dispositivi UWP

In Windows 8.1 le app per dispositivi UWP per le stampanti possono gestire i processi di stampa. In questo argomento viene usata la versione C# dell'esempio di gestione dei processi di stampa e manutenzione della stampante per illustrare come creare una visualizzazione dei processi di stampa, monitorare tali processi e, se necessario, annullare un processo. Per altre informazioni sulle app per dispositivi UWP in generale, vedi Soddisfare le app per dispositivi UWP.

La versione C# dell'esempio di gestione dei processi di stampa e manutenzione della stampante illustra la manutenzione della stampante con il file DeviceMaintenance.xaml.cs nel progetto DeviceAppForPrinters2 . Per lavorare con Bidi, l'esempio usa la libreria di estensioni della stampante nel progetto PrinterExtensionLibrary . La libreria di estensioni della stampante offre un modo pratico per accedere alle interfacce di estensione della stampante del driver di stampa v4. Per altre info, vedi Panoramica della libreria di estensioni della stampante.

Gli esempi di codice illustrati in questo argomento si basano sulla versione C# dell'esempio di gestione dei processi di stampa e manutenzione della stampante. Questo esempio è disponibile anche in JavaScript e C++. Si noti che poiché C++ può accedere direttamente a COM, la versione C++ dell'esempio non include progetti di libreria di codice. Scaricare gli esempi per visualizzare le versioni più recenti del codice.

Gestione dei processi di stampa

Windows 8.1 introduce nuove interfacce di estensione della stampante nel driver della stampante v4 che è possibile usare per gestire i processi di stampa: IPrinterQueue2, IPrinterQueueView, IPrinterQueueViewEvent, IPrintJob e IPrintJobCollection. Queste interfacce consentono di monitorare e annullare i processi di stampa. Per altre info, vedi Print job management (v4 Printer Driver).

Le app C# e JavaScript non possono funzionare direttamente con le API COM. Se stai scrivendo un'app per dispositivi UWP C# o JavaScript, usa la libreria di estensioni della stampante per accedere a queste interfacce (come illustrato in questo argomento).

Prerequisiti

Prima di iniziare:

  1. Assicurarsi che la stampante sia installata usando un driver di stampa v4. Per altre informazioni, vedi Sviluppo di driver di stampa v4.

  2. Configurare il PC di sviluppo. Vedi Introduzione per informazioni sul download degli strumenti e sulla creazione di un account per sviluppatore.

  3. Associare l'app allo Store. Per informazioni su questo, vedi Creare un'app per dispositivi UWP.

  4. Creare i metadati del dispositivo per la stampante che la associa all'app. Per altre informazioni, vedere Creare metadati del dispositivo.

  5. Compilare l'interfaccia utente per la pagina principale dell'app. Tutte le app per dispositivi UWP possono essere avviate dalla schermata Start, in cui verranno visualizzate a schermo intero. Usa l'esperienza Start per evidenziare il tuo prodotto o i tuoi servizi in modo che corrisponda alla personalizzazione e alle funzionalità specifiche dei tuoi dispositivi. Non esistono restrizioni speciali per il tipo di controlli dell'interfaccia utente che può usare. Per iniziare a usare la progettazione dell'esperienza a schermo intero, vedere i principi di progettazione di Microsoft Store.

  6. Se stai scrivendo la tua app con C# o JavaScript, aggiungi il progetto PrinterExtensionLibrary alla soluzione di app per dispositivi UWP. È possibile trovare questo progetto nell'esempio di gestione dei processi di stampa e manutenzione della stampante.

Poiché C++ può accedere direttamente a COM, le app C++ non richiedono una libreria separata per funzionare con il contesto di dispositivo della stampante basato su COM.

Passaggio 1: Trovare la stampante

Prima che l'app possa gestire i processi di stampa, deve prima individuare la stampante con i processi di stampa. A tale scopo, l'esempio di gestione dei processi di stampa e manutenzione della stampante include una classe utile denominata PrinterEnumeration (nel file PrinterEnumeration.cs ). Questa classe trova tutte le stampanti associate all'app tramite i metadati del dispositivo e restituisce un elenco di PrinterInfo oggetti, che contiene i nomi e gli ID dispositivo per ogni stampante.

In questo esempio viene illustrato il EnumeratePrinters_Click metodo nel file PrintJobManagement.xaml.cs . Mostra come l'esempio usa la PrinterEnumeration classe per ottenere un elenco di stampanti associate.

private async void EnumeratePrinters_Click(object sender, RoutedEventArgs e)
{
    try
    {
        rootPage.NotifyUser("Enumerating printers. Please wait", NotifyType.StatusMessage);

        // Retrieve the running app's package family name, and enumerate associated printers.
        string currentPackageFamilyName = Windows.ApplicationModel.Package.Current.Id.FamilyName;

        // Enumerate associated printers.
        PrinterEnumeration pe = new PrinterEnumeration(currentPackageFamilyName);
        List<PrinterInfo> associatedPrinters = await pe.EnumeratePrintersAsync();

        // Update the data binding source on the combo box that displays the list of printers.
        PrinterComboBox.ItemsSource = associatedPrinters;
        if (associatedPrinters.Count > 0)
        {
            PrinterComboBox.SelectedIndex = 0;
            rootPage.NotifyUser(associatedPrinters.Count + " printers enumerated", NotifyType.StatusMessage);
        }
        else
        {
            rootPage.NotifyUser(DisplayStrings.NoPrintersEnumerated, NotifyType.ErrorMessage);
        }
    }
    catch (Exception exception)
    {
        rootPage.NotifyUser("Caught an exception: " + exception.Message, NotifyType.ErrorMessage);
    }
}

Per altre info sulle PrinterEnumeration classi e PrinterInfo , vedi il file PrinterEnumeration.cs .

Passaggio 2: Ottenere la coda della stampante

Dopo aver identificato la stampante con i processi di stampa da gestire, creare una visualizzazione dei processi di stampa, con oggetto basato sull'interfaccia IPrinterQueueView (definita nel file PrinterExtensionTypes.cs del progetto PrinterExtensionLibrary ). Nell'esempio di gestione dei processi di stampa e manutenzione della stampante, questo oggetto viene denominato e viene ricreato currentPrinterQueueView ogni volta che cambia la selezione della stampante.

Printer_SelectionChanged Nel metodo , l'esempio usa innanzitutto un oggetto per creare un PrinterInfo oggetto contesto di estensione della stampante denominato context. Usa quindi il GetPrinterQueueView metodo su context per creare l'oggetto currentPrinterQueueView . Infine, viene aggiunto un gestore eventi per gestire l'evento currentPrinterQueueViewdell'oggetto OnChanged .

In questo esempio viene illustrato il Printer_SelectionChanged metodo nel file PrintJobManagement.xaml.cs . Viene illustrato come creare un oggetto visualizzazione coda della stampante basato su IPrinterQueueView.

private void Printer_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    try
    {
        // Remove the current printer queue view (if any) before displaying the new view.
        if (currentPrinterQueueView != null)
        {
            currentPrinterQueueView.OnChanged -= OnPrinterQueueViewChanged;
            currentPrinterQueueView = null;
        }

        // Retrieve a COM IPrinterExtensionContext object, using the static WinRT factory.
        // Then instantiate one "PrinterExtensionContext" object that allows operations on the COM object.
        PrinterInfo queue = (PrinterInfo)PrinterComboBox.SelectedItem;
        Object comContext = Windows.Devices.Printers.Extensions.PrintExtensionContext.FromDeviceId(queue.DeviceId);
        PrinterExtensionContext context = new PrinterExtensionContext(comContext);

        // Display the printer queue view.
        const int FirstPrintJobEnumerated = 0;
        const int LastPrintJobEnumerated = 10;

        currentPrinterQueueView = context.Queue.GetPrinterQueueView(FirstPrintJobEnumerated, LastPrintJobEnumerated);
        currentPrinterQueueView.OnChanged += OnPrinterQueueViewChanged;
    }
    catch (Exception exception)
    {
        rootPage.NotifyUser("Caught an exception: " + exception.Message, NotifyType.ErrorMessage);
    }
}

Inoltre, ogni volta che viene apportata una modifica alla visualizzazione dei processi di stampa, un gestore eventi chiama il OnPrinterQueueViewChanged metodo . Questo metodo è responsabile del ri binding dell'oggetto PrintJobListBox con una raccolta IEnumerable di IPrintJob oggetti. La raccolta viene passata al metodo tramite l'oggetto PrinterQueueViewEventArgs , definito nel file PrinterExtensionTypes.cs .

In questo esempio viene illustrato il OnPrinterQueueViewChanged metodo nel file PrintJobManagement.xaml.cs .

private async void OnPrinterQueueViewChanged(object sender, PrinterQueueViewEventArgs e)
{
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
    {
        // Update the data binding on the ListBox that displays print jobs.
        PrintJobListBox.ItemsSource = e.Collection;
        if (PrintJobListBox.Items.Count > 0)
        {
            // If there are print jobs in the current view, mark the first job as selected.
            PrintJobListBox.SelectedIndex = 0;
        }
    });
}

Passaggio 3: Visualizzare lo stato del processo di stampa

PrintJobListBox Poiché è associato a una raccolta di IPrintJob oggetti, la visualizzazione dello stato di un processo è piuttosto semplice. Il processo di stampa selezionato viene eseguito come IPrintJob oggetto e quindi le proprietà di tale oggetto vengono utilizzate per riempire il PrintJobDetails controllo TextBox.

Nell'esempio di gestione dei processi di stampa e manutenzione della stampante, lo stato del processo di stampa viene visualizzato ogni volta che viene selezionato un processo di stampa diverso. Questo aggiornamento viene eseguito dal PrintJob_SelectionChanged metodo .

In questo esempio viene illustrato il PrintJob_SelectionChanged metodo nel file PrintJobManagement.xaml.cs . Mostra come visualizzare lo stato di un processo di stampa, in base a un IPrintJob oggetto .

private void PrintJob_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    try
    {
        // Display details of the selected print job.
        IPrintJob job = (IPrintJob)PrintJobListBox.SelectedItem;
        if (job != null)
        {
            PrintJobDetails.Text =
                "Details of print job: " + job.Name + "\r\n" +
                "Pages printed: " + job.PrintedPages + "/" + job.TotalPages + "\r\n" +
                "Submission time: " + job.SubmissionTime + "\r\n" +
                "Job status: " + DisplayablePrintJobStatus.ToString(job.Status);
        }
        else
        {
            PrintJobDetails.Text = "Please select a print job";
        }
    }
    catch (Exception exception)
    {
        rootPage.NotifyUser("Caught an exception: " + exception.Message, NotifyType.ErrorMessage);
    }
}

Per visualizzare la descrizione dello stato del processo di stampa, il PrintJob_SelectionChanged metodo usa un dizionario statico, denominato printJobStatusDisplayNames, per visualizzare le descrizioni dello stato dei processi in un formato di testo descrittivo.

Questo esempio mostra la DisplayablePrintJobStatus classe nel file PrintJobManagement.xaml.cs . Questa classe contiene i membri statici utilizzati da PrintJob_SelectionChanged.

internal class DisplayablePrintJobStatus
{
    /// <summary>
    /// Converts the PrintJobStatus bit fields to a display string.
    /// </summary>
    internal static string ToString(PrintJobStatus printJobStatus)
    {
        StringBuilder statusString = new StringBuilder();

        // Iterate through each of the PrintJobStatus bits that are set and convert it to a display string.
        foreach (var printJobStatusDisplayName in printJobStatusDisplayNames)
        {
            if ((printJobStatusDisplayName.Key & printJobStatus) != 0)
            {
                statusString.Append(printJobStatusDisplayName.Value);
            }
        }

        int stringlen = statusString.Length;
        if (stringlen > 0)
        {
            // Trim the trailing comma from the string.
            return statusString.ToString(0, stringlen - 1);
        }
        else
        {
            // If no print job status field was set, display "Not available".
            return "Not available";
        }
    }

    /// <summary>
    /// Static constructor that initializes the display name for the PrintJobStatus field.
    /// </summary>
    static DisplayablePrintJobStatus()
    {
        printJobStatusDisplayNames = new Dictionary<PrintJobStatus, string>();

        printJobStatusDisplayNames.Add(PrintJobStatus.Paused, "Paused,");
        printJobStatusDisplayNames.Add(PrintJobStatus.Error, "Error,");
        printJobStatusDisplayNames.Add(PrintJobStatus.Deleting, "Deleting,");
        printJobStatusDisplayNames.Add(PrintJobStatus.Spooling, "Spooling,");
        printJobStatusDisplayNames.Add(PrintJobStatus.Printing, "Printing,");
        printJobStatusDisplayNames.Add(PrintJobStatus.Offline, "Offline,");
        printJobStatusDisplayNames.Add(PrintJobStatus.PaperOut, "Out of paper,");
        printJobStatusDisplayNames.Add(PrintJobStatus.Printed, "Printed,");
        printJobStatusDisplayNames.Add(PrintJobStatus.Deleted, "Deleted,");
        printJobStatusDisplayNames.Add(PrintJobStatus.BlockedDeviceQueue, "Blocked device queue,");
        printJobStatusDisplayNames.Add(PrintJobStatus.UserIntervention, "User intervention required,");
        printJobStatusDisplayNames.Add(PrintJobStatus.Restarted, "Restarted,");
        printJobStatusDisplayNames.Add(PrintJobStatus.Complete, "Complete,");
        printJobStatusDisplayNames.Add(PrintJobStatus.Retained, "Retained,");
    }
    
    /// <summary>
    /// Private constructor to prevent default instantiation.
    /// </summary>
    private DisplayablePrintJobStatus() { }

    /// <summary>
    /// Contains the mapping between PrintJobStatus fields and display strings.
    /// </summary>
    private static Dictionary<PrintJobStatus, string> printJobStatusDisplayNames;
}

Passaggio 4: Annullare il processo di stampa

Analogamente alla visualizzazione dello stato del processo di stampa, l'annullamento di un processo di stampa è piuttosto semplice quando si dispone di un IPrintJob oggetto . La IPrintJob classe fornisce un RequestCancel metodo che avvia l'annullamento del processo di stampa corrispondente. Questo è dimostrato nel metodo dell'esempio CancelPrintJob_Click .

In questo esempio viene illustrato il CancelPrintJob_Click metodo nel file PrintJobManagement.xaml.cs .

private void CancelPrintJob_Click(object sender, RoutedEventArgs e)
{
    try
    {
        IPrintJob job = (IPrintJob)PrintJobListBox.SelectedItem;
        job.RequestCancel();
    }
    catch (Exception exception)
    {
        rootPage.NotifyUser("Caught an exception: " + exception.Message, NotifyType.ErrorMessage);
    }
}

Test in corso

Prima di poter testare l'app per dispositivi UWP, deve essere collegata alla stampante usando i metadati del dispositivo.

È necessaria una copia del pacchetto di metadati del dispositivo per la stampante per aggiungere le informazioni sull'app del dispositivo. Se non hai metadati del dispositivo, puoi compilarlo usando la Creazione guidata metadati dispositivo come descritto nell'argomento Creare metadati del dispositivo per l'app per dispositivi UWP.

Per usare la Creazione guidata metadati dispositivo, è necessario installare Microsoft Visual Studio Professional, Microsoft Visual Studio Ultimate o l'SDK autonomo per Windows 8.1, prima di completare i passaggi descritti in questo argomento. L'installazione di Microsoft Visual Studio Express per Windows installa una versione dell'SDK che non include la procedura guidata.

La procedura seguente consente di compilare l'app e installare i metadati del dispositivo.

  1. Abilitare la firma di test.

    1. Avviare la Creazione guidata metadati dispositivo da %ProgramFiles(x86)%\Windows Kits\8.1\bin\x86 facendo doppio clic su DeviceMetadataWizard.exe

    2. Scegliere Abilita firma test dal menu Strumenti.

  2. Riavviare il computer

  3. Compilare la soluzione aprendo il file della soluzione (.sln). Premere F7 o passare a Compila soluzione> dal menu in alto dopo il caricamento dell'esempio.

  4. Disconnettere e disinstallare la stampante. Questo passaggio è obbligatorio in modo che Windows leggerà i metadati aggiornati del dispositivo alla successiva individuazione del dispositivo.

  5. Modificare e salvare i metadati del dispositivo. Per collegare l'app del dispositivo al dispositivo, devi associare l'app per dispositivo al dispositivo.

    Se non hai ancora creato i metadati del dispositivo, vedi Creare metadati del dispositivo per l'app per dispositivi UWP.

    1. Se la Creazione guidata metadati dispositivo non è ancora aperta, avviarla da %ProgramFiles(x86)%\Windows Kits\8.1\bin\x86 facendo doppio clic su DeviceMetadataWizard.exe.

    2. Fare clic su Modifica metadati dispositivo. In questo modo sarà possibile modificare il pacchetto di metadati del dispositivo esistente.

    3. Nella finestra di dialogo Apri individuare il pacchetto di metadati del dispositivo associato all'app per dispositivi UWP. Ha un'estensione di file devicemetadata-ms .

    4. Nella pagina Specificare le informazioni sull'app per dispositivi UWP immettere le informazioni sull'app di Microsoft Store nella casella app per dispositivi UWP. Fare clic su Importa file manifesto dell'app UWP per immettere automaticamente il nome del pacchetto, il nome dell'editore e l'ID app UWP.

    5. Se l'app sta registrando per le notifiche della stampante, compilare la casella Gestori di notifica. In ID evento immettere il nome del gestore eventi di stampa. In Asset evento immettere il nome del file in cui risiede il codice.

    6. Al termine, fare clic su Avanti finché non si arriva alla pagina Fine .

    7. Nella pagina Rivedi il pacchetto di metadati del dispositivo verificare che tutte le impostazioni siano corrette e selezionare la casella di controllo Copia il pacchetto di metadati del dispositivo nell'archivio metadati nel computer locale. Fare clic su Save (Salva).

  6. Riconnettere la stampante in modo che Windows legga i metadati aggiornati del dispositivo quando il dispositivo è connesso.

Gestione processi (driver della stampante v4)

Sviluppo di driver di stampa v4

Comunicazioni bidirezionali

Introduzione alle app UWP

Creare un'app per dispositivi UWP (guida dettagliata)

Creare metadati del dispositivo per un'app per dispositivi UWP (guida dettagliata)