Compartir a través de


Cómo administrar trabajos de impresión en una aplicación de dispositivo para UWP

Important

Los metadatos de dispositivo están obsoletos y se eliminarán en una futura versión de Windows. Para obtener información sobre el reemplazo de esta funcionalidad, vea Driver Package Container Metadata.

En Windows 8.1, las aplicaciones de dispositivos para UWP para impresoras pueden administrar trabajos de impresión. En este tema se usa la versión de C# del ejemplo de administración de trabajos de impresión e mantenimiento de impresoras para mostrar cómo crear una vista de trabajos de impresión, supervisar esos trabajos y, si es necesario, cancelar un trabajo. Para obtener más información sobre las aplicaciones de dispositivos para UWP en general, consulta Meet UWP device apps (Conocer aplicaciones de dispositivos para UWP).

La versión de C# del ejemplo de administración de trabajos de impresión e mantenimiento de impresoras muestra el mantenimiento de la impresora con el archivo DeviceMaintenance.xaml.cs en el proyecto DeviceAppForPrinters2 . To work with Bidi, the sample uses the printer extension library in the PrinterExtensionLibrary project. La biblioteca de extensiones de impresora proporciona una manera cómoda de acceder a las interfaces de extensión de impresora del controlador de impresión v4. Para obtener más información, consulte la introducción a la biblioteca de extensiones de impresora.

Los ejemplos de código que se muestran en este tema se basan en la versión de C# del ejemplo de administración de trabajos de impresión e mantenimiento de impresoras . Este ejemplo también está disponible en JavaScript y C++. Tenga en cuenta que, dado que C++ puede acceder directamente a COM, la versión de C++ del ejemplo no incluye proyectos de biblioteca de código. Descargue los ejemplos para ver las versiones más recientes del código.

Administración de trabajos de impresión

Windows 8.1 introduces new printer extension interfaces in the v4 printer driver that you can use for managing print jobs: IPrinterQueue2, IPrinterQueueView, IPrinterQueueViewEvent, IPrintJob, and IPrintJobCollection. Estas interfaces permiten supervisar y cancelar trabajos de impresión. Para obtener más información, consulte Administración de trabajos de impresión (controlador de impresora v4) .

Las aplicaciones de C# y JavaScript no pueden trabajar directamente con las API COM. Si estás escribiendo una aplicación de dispositivo para UWP de C# o JavaScript, usa la biblioteca de extensiones de impresora para acceder a estas interfaces (como se muestra en este tema).

Prerequisites

Antes de comenzar:

  1. Asegúrese de que la impresora está instalada mediante un controlador de impresión v4. Para obtener más información, consulte Desarrollo de controladores de impresión v4.

  2. Configure tu PC de desarrollo. See Getting started for info about downloading the tools and creating a developer account.

  3. Asocie la aplicación a la tienda. Consulta Crear una aplicación de dispositivo para UWP para obtener información sobre eso.

  4. Cree metadatos de dispositivo para la impresora que la asocie a la aplicación. Consulte Creación de metadatos de dispositivo para obtener más información sobre eso.

  5. Compile la interfaz de usuario para la página principal de la aplicación. Todas las aplicaciones de dispositivos para UWP se pueden iniciar desde Inicio, donde se mostrarán en pantalla completa. Utiliza la experiencia de inicio para resaltar tus productos o servicios de una manera que coincida con la imagen de marca y las características específicas de tus dispositivos. No hay restricciones especiales en el tipo de controles de interfaz de usuario que puede usar. Para empezar a trabajar con el diseño de la experiencia de pantalla completa, consulta los principios de diseño de Microsoft Store.

  6. If you're writing your app with C# or JavaScript, add the PrinterExtensionLibrary project to your UWP device app solution. Puede encontrar este proyecto en el ejemplo de administración de trabajos de impresión e mantenimiento de impresoras .

Dado que C++ puede acceder directamente a COM, las aplicaciones de C++ no requieren una biblioteca independiente para trabajar con el contexto del dispositivo de impresora basado en COM.

Paso 1: Buscar impresora

Para que la aplicación pueda administrar trabajos de impresión, primero debe localizar la impresora que tiene los trabajos de impresión. Para ello, el ejemplo de administración de trabajos de impresión e mantenimiento de impresoras incluye una clase útil denominada PrinterEnumeration (en el archivo PrinterEnumeration.cs ). Esta clase busca todas las impresoras asociadas a la aplicación a través de metadatos del dispositivo y devuelve una lista de PrinterInfo objetos, que contiene los nombres y los identificadores de dispositivo de cada impresora.

This example shows the EnumeratePrinters_Click method in the PrintJobManagement.xaml.cs file. Muestra cómo el ejemplo usa la PrinterEnumeration clase para obtener una lista de impresoras asociadas.

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);
    }
}

For more info about the PrinterEnumeration and PrinterInfo classes, see the PrinterEnumeration.cs file.

Paso 2: Obtener la cola de impresoras

Once you've identified the printer having the print jobs that you want to manage, create a view of the print jobs, with object based on the IPrinterQueueView interface (defined in the PrinterExtensionTypes.cs file of the PrinterExtensionLibrary project). En el ejemplo De administración de trabajos de impresión e mantenimiento de impresoras , este objeto se denomina currentPrinterQueueView y se vuelve a crear cada vez que cambia la selección de la impresora.

En el Printer_SelectionChanged método , el ejemplo usa primero un PrinterInfo objeto para crear un objeto de contexto de extensión de impresora denominado context. A continuación, usa el GetPrinterQueueView método en para context crear el currentPrinterQueueView objeto . Por último, se agrega un controlador de eventos para controlar el currentPrinterQueueViewevento de OnChanged .

This example shows the Printer_SelectionChanged method in the PrintJobManagement.xaml.cs file. Muestra cómo crear un objeto de vista de cola de impresora basado en 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);
    }
}

Además, siempre que haya un cambio en la vista de los trabajos de impresión, un controlador de eventos llama al OnPrinterQueueViewChanged método . Este método es responsable de volver a enlazar con PrintJobListBox una colección IEnumerable de IPrintJob objetos. The collection is passed to the method via the PrinterQueueViewEventArgs object, which is defined in the PrinterExtensionTypes.cs file.

This example shows the OnPrinterQueueViewChanged method in the PrintJobManagement.xaml.cs file.

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;
        }
    });
}

Paso 3: Mostrar el estado del trabajo de impresión

PrintJobListBox Dado que está enlazado a una colección de IPrintJob objetos, mostrar el estado de un trabajo es bastante sencillo. El trabajo de impresión seleccionado se convierte como un IPrintJob objeto y, a continuación, las propiedades de ese objeto se usan para rellenar el PrintJobDetails TextBox.

En el ejemplo Administración de trabajos de impresión e mantenimiento de impresoras , el estado del trabajo de impresión se muestra cada vez que se selecciona un trabajo de impresión diferente. Esta actualización se encarga del PrintJob_SelectionChanged método .

This example shows the PrintJob_SelectionChanged method in the PrintJobManagement.xaml.cs file. Muestra cómo mostrar el estado de un trabajo de impresión, en función de un IPrintJob objeto .

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);
    }
}

Para ayudar a mostrar la descripción del estado del trabajo de impresión, el PrintJob_SelectionChanged método usa un diccionario estático, denominado printJobStatusDisplayNames, para ayudar a mostrar las descripciones de estado del trabajo que se encuentran en un formato de texto descriptivo.

This example shows the DisplayablePrintJobStatus class in the PrintJobManagement.xaml.cs file. Esta clase contiene los miembros estáticos usados por .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;
}

Paso 4: Cancelar el trabajo de impresión

De forma similar a mostrar el estado del trabajo de impresión, cancelar un trabajo de impresión es bastante sencillo cuando tiene un IPrintJob objeto . La IPrintJob clase proporciona un RequestCancel método que inicia la cancelación del trabajo de impresión correspondiente. Esto se muestra en el método del CancelPrintJob_Click ejemplo.

This example shows the CancelPrintJob_Click method in the PrintJobManagement.xaml.cs file.

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);
    }
}

Testing

Para poder probar la aplicación de dispositivo para UWP, debe estar vinculada a la impresora mediante metadatos del dispositivo.

Necesita una copia del paquete de metadatos del dispositivo para la impresora, para agregarle la información de la aplicación del dispositivo. Si no tiene metadatos de dispositivo, puede compilarlos mediante el Asistente para creación de metadatos de dispositivo, tal como se describe en el tema Crear metadatos de dispositivo para la aplicación de dispositivo para UWP.

Para usar el Asistente para creación de metadatos de dispositivo, debe instalar Microsoft Visual Studio Professional, Microsoft Visual Studio Ultimate o el SDK independiente para Windows 8.1, antes de completar los pasos de este tema. La instalación de Microsoft Visual Studio Express para Windows instala una versión del SDK que no incluye el asistente.

Los pasos siguientes compilan la aplicación e instalan los metadatos del dispositivo.

  1. Habilite la firma de prueba.

    1. Inicie el Asistente para creación de metadatos de dispositivo desde %ProgramFiles(x86)%\Windows Kits\8.1\bin\x86 haciendo doble clic enDeviceMetadataWizard.exe

    2. From the Tools menu, select Enable Test Signing.

  2. Reiniciar el equipo

  3. Compile la solución abriendo el archivo de solución (.sln). Pulse F7 o vaya a Crear->Crear solución en el menú superior después de cargar el ejemplo.

  4. Desconecte y desinstale la impresora. Este paso es necesario para que Windows lea los metadatos del dispositivo actualizado la próxima vez que se detecte el dispositivo.

  5. Edite y guarde los metadatos del dispositivo. Para conectar la aplicación al dispositivo, debe asociarla con su equipo.

    Si aún no has creado los metadatos del dispositivo, consulta Crear metadatos de dispositivo para tu aplicación de dispositivo para UWP.

    1. Si el Asistente para creación de metadatos de dispositivo aún no está abierto, inícielo desde %ProgramFiles(x86)%\Windows Kits\8.1\bin\x86, haciendo doble clic enDeviceMetadataWizard.exe.

    2. Haga clic en Editar metadatos del dispositivo. Esto le permitirá editar el paquete de metadatos del dispositivo existente.

    3. In the Open dialog box, locate the device metadata package associated with your UWP device app. (It has a devicemetadata-ms file extension.)

    4. En la página Especificar información de la aplicación de dispositivo para UWP , escriba la información de la aplicación de Microsoft Store en el cuadro aplicación de dispositivo para UWP . Haz clic en Importar archivo de manifiesto de aplicación para UWP para escribir automáticamente el nombre del paquete, el nombre del publicador y el identificador de la aplicación para UWP.

    5. If your app is registering for printer notifications, fill out the Notification handlers box. In Event ID, enter the name of the print event handler. In Event Asset, enter the name of the file where that code resides.

    6. When you're done, click Next until you get to the Finish page.

    7. En la página Revisar el paquete de metadatos del dispositivo , asegúrese de que toda la configuración es correcta y active la casilla Copiar el paquete de metadatos del dispositivo en el almacén de metadatos del equipo local . Then click Save.

  6. Vuelva a conectar la impresora para que Windows lea los metadatos del dispositivo actualizados cuando el dispositivo esté conectado.