Поделиться через


Управление заданиями печати в приложении устройства UWP

В Windows 8.1 приложения устройств UWP для принтеров могут управлять заданиями печати. В этом разделе используется версия C# примера управления заданиями печати и обслуживания принтера для демонстрации создания представления заданий печати, мониторинга этих заданий и при необходимости отмены задания. Дополнительные сведения о приложениях устройств UWP см. в статье "Знакомство с приложениями устройств UWP".

Версия C# примера управления заданиями печати и обслуживания принтера демонстрирует обслуживание принтера с файлом DeviceMaintenance.xaml.cs в проекте DeviceAppForPrinters2 . Для работы с Bidi в примере используется библиотека расширений принтера в проекте PrinterExtensionLibrary . Библиотека расширений принтера предоставляет удобный способ доступа к интерфейсам расширения принтера драйвера печати версии 4. Дополнительные сведения см. в обзоре библиотеки расширений принтера.

Примеры кода, показанные в этом разделе, основаны на версии C# примера управления заданиями печати и обслуживания принтера. Этот пример также доступен в JavaScript и C++. Обратите внимание, что поскольку C++ может напрямую получить доступ к COM, версия C++ примера не включает проекты библиотеки кода. Скачайте примеры, чтобы просмотреть последние версии кода.

Управление заданиями печати

В Windows 8.1 представлены новые интерфейсы расширения принтера в драйвере принтера версии 4, который можно использовать для управления заданиями печати: IPrinterQueue2, IPrinterQueueView, IPrinterQueueViewEvent, IPrintJob и IPrintJobCollection. Эти интерфейсы позволяют отслеживать и отменять задания печати. Дополнительные сведения см. в разделе "Управление заданиями печати" (драйвер принтера версии 4).

Приложения C# и JavaScript не могут работать напрямую с COM-API. Если вы пишете приложение устройства C# или JavaScript UWP, используйте библиотеку расширений принтера для доступа к этим интерфейсам (как показано в этом разделе).

Необходимые компоненты

Необходимые условия:

  1. Убедитесь, что принтер установлен с помощью драйвера печати версии 4. Дополнительные сведения см. в статье "Разработка драйверов печати версии 4".

  2. Настройте компьютер разработки. Сведения о скачивании средств и создании учетной записи разработчика см. в статье "Начало работы ".

  3. Свяжите приложение с магазином. Сведения об этом см. в статье "Создание приложения устройства UWP".

  4. Создайте метаданные устройства для принтера, который связывает его с приложением. Дополнительные сведения см. в статье "Создание метаданных устройства".

  5. Создайте пользовательский интерфейс для главной страницы приложения. Все приложения устройств UWP можно запустить с начального экрана, где они будут отображаться в полноэкранном режиме. Используйте интерфейс "Пуск", чтобы выделить продукт или службы таким образом, чтобы соответствовать определенным фирменной символике и функциям ваших устройств. Существуют специальные ограничения на тип элементов управления пользовательским интерфейсом, которые он может использовать. Чтобы приступить к разработке полноэкранного интерфейса, ознакомьтесь с принципами проектирования в Microsoft Store.

  6. Если вы пишете приложение с помощью C# или JavaScript, добавьте проект PrinterExtensionLibrary в решение приложения устройства UWP. Этот проект можно найти в примере управления заданиями печати и обслуживания принтера.

Так как C++ может получить доступ к COM напрямую, приложения C++ не требуют отдельной библиотеки для работы с контекстом устройства принтера на основе COM.

Шаг 1. Поиск принтера

Прежде чем приложение сможет управлять заданиями печати, он должен сначала найти принтер с заданиями печати. Для этого пример управления заданиями печати и обслуживания принтера включает удобный класс PrinterEnumerationфайле PrinterEnumeration.cs ). Этот класс находит все принтеры, связанные с приложением с помощью метаданных устройства, и возвращает список PrinterInfo объектов, содержащий имена и идентификаторы устройств для каждого принтера.

В этом примере показан EnumeratePrinters_Click метод в файле PrintJobManagement.xaml.cs . В нем показано, как в примере PrinterEnumeration используется класс для получения списка связанных принтеров.

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

Дополнительные сведения о файлах PrinterEnumeration и PrinterInfo классах см . в файле PrinterEnumeration.cs .

Шаг 2. Получение очереди принтера

После определения принтера задания печати, которым требуется управлять, создайте представление заданий печати с объектом на IPrinterQueueView основе интерфейса (определенного в файле PrinterExtensionTypes.cs проекта PrinterExtensionLibrary). В примере управления заданиями печати и обслуживания принтера этот объект называется currentPrinterQueueView и создается повторно при каждом изменении выбора принтера.

Printer_SelectionChanged В этом примере сначала используется PrinterInfo объект для создания объекта контекста расширения принтера с именемcontext. Затем он использует GetPrinterQueueView метод для context создания currentPrinterQueueView объекта. Наконец, обработчик событий добавляется для обработки currentPrinterQueueViewOnChanged события.

В этом примере показан Printer_SelectionChanged метод в файле PrintJobManagement.xaml.cs . В нем показано, как создать объект представления очереди принтера на 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);
    }
}

Кроме того, при изменении представления заданий печати обработчик событий вызывает OnPrinterQueueViewChanged метод. Этот метод отвечает за повторную привязку PrintJobListBox к коллекции IPrintJob объектов IEnumerable. Коллекция передается методу через PrinterQueueViewEventArgs объект, который определен в файле PrinterExtensionTypes.cs .

В этом примере показан OnPrinterQueueViewChanged метод в файле 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;
        }
    });
}

Шаг 3. Отображение состояния задания печати

Так как объект PrintJobListBox привязан к коллекции IPrintJob объектов, отображение состояния задания довольно просто. Выбранное задание печати приведение в качестве IPrintJob объекта, а затем свойства этого объекта используются для заполнения PrintJobDetails TextBox.

В примере управления заданиями печати и обслуживания принтера состояние задания печати отображается при каждом выборе другого задания печати. Это обновление заботится о методе PrintJob_SelectionChanged .

В этом примере показан PrintJob_SelectionChanged метод в файле PrintJobManagement.xaml.cs . В нем показано, как отобразить состояние задания печати на IPrintJob основе объекта.

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

Чтобы отобразить описание состояния задания печати, PrintJob_SelectionChanged метод использует статический словарь с именем printJobStatusDisplayNames, чтобы отобразить описания состояния задания, которые находятся в понятном текстовом формате.

В этом примере показан DisplayablePrintJobStatus класс в файле PrintJobManagement.xaml.cs . Этот класс содержит статические элементы, используемые параметром 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;
}

Шаг 4. Отмена задания печати

Как и при отображении состояния задания печати, отмена задания печати довольно проста при наличии IPrintJob объекта. Класс IPrintJob предоставляет RequestCancel метод, инициирующий отмену соответствующего задания печати. Это демонстрируется в методе примера CancelPrintJob_Click .

В этом примере показан CancelPrintJob_Click метод в файле 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);
    }
}

Тестирование

Прежде чем протестировать приложение устройства UWP, его необходимо связать с принтером с помощью метаданных устройства.

Для добавления в него сведений о приложении устройства требуется копия пакета метаданных устройства. Если у вас нет метаданных устройства, его можно создать с помощью мастера создания метаданных устройств, как описано в разделе "Создание метаданных устройства для приложения устройства UWP".

Чтобы использовать мастер разработки метаданных устройств, необходимо установить Microsoft Visual Studio Professional, Microsoft Visual Studio Ultimate или автономный пакет SDK для Windows 8.1, прежде чем выполнить действия, описанные в этом разделе. Установка Microsoft Visual Studio Express для Windows устанавливает версию пакета SDK, которая не включает мастер.

Следующие шаги по созданию приложения и установке метаданных устройства.

  1. Включите тестовую подпись.

    1. Запустите мастер разработки метаданных устройства из %ProgramFiles(x86)%\Windows Kits\8.1\bin\x86, дважды щелкнув DeviceMetadataWizard.exe

    2. В меню "Сервис" выберите "Включить подписывание тестов".

  2. Перезагрузите компьютер.

  3. Создайте решение, открыв файл решения (.sln). Нажмите клавишу F7 или перейдите к решению сборки> из верхнего меню после загрузки примера.

  4. Отключите и удалите принтер. Этот шаг необходим, чтобы Windows считывала обновленные метаданные устройства при следующем обнаружении устройства.

  5. Изменение и сохранение метаданных устройства. Чтобы связать приложение устройства с устройством, необходимо связать приложение устройства с устройством.

    Если вы еще не создали метаданные устройства, см. статью "Создание метаданных устройства" для приложения устройства UWP.

    1. Если мастер разработки метаданных устройства еще не открыт, запустите его с %ProgramFiles(x86)%\Windows Kits\8.1\bin\x86, дважды щелкнув DeviceMetadataWizard.exe.

    2. Нажмите кнопку "Изменить метаданные устройства". Это позволит изменить существующий пакет метаданных устройства.

    3. В диалоговом окне "Открыть" найдите пакет метаданных устройства, связанный с приложением устройства UWP. (Он имеет расширение файла devicemetadata-ms .)

    4. На странице сведений о приложении устройства UWP введите сведения о приложении Microsoft Store в поле приложения устройства UWP. Щелкните импорт файла манифеста приложения UWP, чтобы автоматически ввести имя пакета, имя издателя и идентификатор приложения UWP.

    5. Если приложение регистрируется для уведомлений принтера, заполните поле обработчиков уведомлений. Введите имя обработчика событий печати в идентификаторе события. В ресурсе событий введите имя файла, в котором находится этот код.

    6. По завершении нажмите кнопку "Далее ", пока не перейдете на страницу "Готово ".

    7. На странице "Проверка пакета метаданных устройства" убедитесь, что все параметры правильны и выберите пакет метаданных устройства в хранилище метаданных на локальном компьютере проверка. Нажмите кнопку Сохранить.

  6. Повторно подключите принтер, чтобы Windows считывала обновленные метаданные устройства при подключении устройства.

Управление заданиями (драйвер принтера версии 4)

Разработка драйверов печати версии 4

Двунаправленная связь

Начало работы с приложениями UWP

Создание приложения устройства UWP (пошаговое руководство)

Создание метаданных устройства для приложения устройства UWP (пошаговое руководство)