Udostępnij przez


Dostosowywanie przepływu pracy drukowania

Tworzenie niestandardowych środowisk przepływu pracy drukowania za pomocą aplikacji przepływu pracy drukowania.

Przegląd

Aplikacje przepływu pracy drukowania to aplikacje platformy UNIWERSALNEJ systemu Windows, które rozszerzają funkcjonalność aplikacji aplikacji ze sklepu Microsoft Store (WSDA), dlatego warto zapoznać się z usługami WSDA przed kontynuowaniem.

Podobnie jak w przypadku usług WSDA, gdy użytkownik aplikacji źródłowej zdecyduje się wydrukować coś i przechodzi przez okno dialogowe drukowania, system sprawdza, czy aplikacja przepływu pracy jest skojarzona z tą drukarką. Jeśli tak jest, aplikacja do przepływu zadań drukowania zostanie uruchomiona (głównie jako proces w tle; więcej na ten temat poniżej). Aplikacja przepływu pracy może zmienić zarówno bilet wydruku (dokument XML, który konfiguruje ustawienia urządzenia drukarki dla bieżącego zadania drukowania) i rzeczywistą zawartość XPS do wydrukowania. Opcjonalnie może uwidocznić tę funkcję użytkownikowi, uruchamiając interfejs użytkownika w połowie procesu. Po wykonaniu swojej pracy przekazuje zawartość drukowaną oraz bilet drukowania do sterownika.

Ponieważ obejmuje ona składniki w tle i na pierwszym planie, a ponieważ jest ona funkcjonalnie połączona z innymi aplikacjami, aplikacja przepływu pracy drukowania może być bardziej skomplikowana do zaimplementowania niż inne kategorie aplikacji platformy UWP. Zaleca się sprawdzenie przykładowej aplikacji Workflow podczas czytania tego przewodnika, aby lepiej zrozumieć, jak można zaimplementować różne funkcje. Niektóre funkcje, takie jak różne kontrole błędów i zarządzanie interfejsem użytkownika, nie są dostępne w tym przewodniku dla uproszczenia.

Wprowadzenie

Aplikacja przepływu pracy musi wskazać punkt wejścia do systemu wydruku, aby można było go uruchomić w odpowiednim czasie. Jest to wykonywane przez wstawienie następującej deklaracji w Application/Extensions elementu pliku package.appxmani fest projektu platformy UWP.

<uap:Extension Category="windows.printWorkflowBackgroundTask"  
    EntryPoint="WFBackgroundTasks.WfBackgroundTask" />

Ważne

Istnieje wiele scenariuszy, w których dostosowywanie wydruku nie wymaga danych wejściowych użytkownika. Z tego powodu aplikacje do zarządzania drukowaniem domyślnie działają w tle jako zadania.

Jeśli aplikacja przepływu pracy jest skojarzona z aplikacją źródłową, która uruchomiła zadanie drukowania (zobacz sekcję później, aby uzyskać instrukcje na ten temat), system drukowania sprawdza swoje pliki manifestu dla punktów wejścia zadań w tle.

Praca w tle nad biletem wydruku

Pierwszą rzeczą, jaką system wydruku wykonuje w aplikacji przepływu pracy, jest aktywowanie zadania w tle (w tym przypadku klasa WfBackgroundTask w przestrzeni nazw WFBackgroundTasks). W metodzie Run zadania w tle należy rzutować szczegóły wyzwalacza zadania jako wystąpienie PrintWorkflowTriggerDetails. Zapewni to specjalną funkcjonalność dla zadania w tle przepływu pracy drukowania. Uwidacznia właściwość PrintWorkflowSession, która jest wystąpieniem PrintWorkFlowBackgroundSession. Klasy sesji przepływu pracy drukowania — zarówno odmiany tła, jak i pierwszego planu — będą kontrolować sekwencyjne kroki aplikacji przepływu pracy drukowania.

Następnie zarejestruj metody obsługi dla dwóch zdarzeń, które zostaną wywołane przez tę klasę sesji. Te metody zdefiniujesz później.

public void Run(IBackgroundTaskInstance taskInstance) {
    // Take out a deferral here and complete once all the callbacks are done
    runDeferral = taskInstance.GetDeferral();

    // Associate a cancellation handler with the background task.
    taskInstance.Canceled += new BackgroundTaskCanceledEventHandler(OnCanceled);

    // cast the task's trigger details as PrintWorkflowTriggerDetails
    PrintWorkflowTriggerDetails workflowTriggerDetails = taskInstance.TriggerDetails as PrintWorkflowTriggerDetails;

    // Get the session manager, which is unique to this print job
    PrintWorkflowBackgroundSession sessionManager = workflowTriggerDetails.PrintWorkflowSession;

    // add the event handler callback routines
    sessionManager.SetupRequested += OnSetupRequested;
    sessionManager.Submitted += OnXpsOMPrintSubmitted;

    // Allow the event source to start
    // This call blocks until all of the workflow callbacks complete
    sessionManager.Start();
}

Po wywołaniu metody Start, menedżer sesji zgłosi najpierw zdarzenie SetupRequested. To zdarzenie uwidacznia ogólne informacje o zadaniu drukowania, a także bilet wydruku. Na tym etapie dokument do druku można edytować w tle.

private void OnSetupRequested(PrintWorkflowBackgroundSession sessionManager, PrintWorkflowBackgroundSetupRequestedEventArgs printTaskSetupArgs) {
    // Take out a deferral here and complete once all the callbacks are done
    Deferral setupRequestedDeferral = printTaskSetupArgs.GetDeferral();

    // Get general information about the source application, print job title, and session ID
    string sourceApplicationName = printTaskSetupArgs.Configuration.SourceAppDisplayName;
    string jobTitle = printTaskSetupArgs.Configuration.JobTitle;
    string sessionId = printTaskSetupArgs.Configuration.SessionId;

    // edit the print ticket
    WorkflowPrintTicket printTicket = printTaskSetupArgs.GetUserPrintTicketAsync();

    // ...

Ważne jest, że aplikacja określi, czy uruchomić komponent pierwszego planu w obsłudze SetupRequested. Może to zależeć od ustawienia, które zostało wcześniej zapisane w magazynie lokalnym, lub zdarzenia, które wystąpiło podczas edycji zlecenia druku, lub może to być ustawienie statyczne Twojej konkretnej aplikacji.

// ...

if (UIrequested) {
    printTaskSetupArgs.SetRequiresUI();

    // Any data that is to be passed to the foreground task must be stored the app's local storage.
    // It should be prefixed with the sourceApplicationName string and the SessionId string, so that
    // it can be identified as pertaining to this workflow app session.
}

// Complete the deferral taken out at the start of OnSetupRequested
setupRequestedDeferral.Complete();

Wykonywanie zadań priorytetowych w zadaniu drukowania (opcjonalnie)

Jeśli wywołano metodę SetRequiresUI, system wydruku zbada plik manifestu pod kątem punktu wejścia do aplikacji pierwszego planu. Element Application/Extensions pliku package.appxmanifest musi zawierać następujące wiersze. Zastąp wartość EntryPoint nazwą aplikacji pierwszego planu.

<uap:Extension Category="windows.printWorkflowForegroundTask"  
    EntryPoint="MyWorkFlowForegroundApp.App" />

Następnie metoda OnActivated jest wywoływana przez system drukowania dla odpowiedniego punktu wejścia aplikacji. W metodzie OnActivated pliku App.xaml.cs aplikacja przepływu pracy powinna sprawdzić rodzaj aktywacji, żeby upewnić się, że jest to aktywacja przepływu pracy. Jeśli tak, aplikacja przepływu pracy może rzutować argumenty aktywacji na obiekt PrintWorkflowUIActivatedEventArgs, który uwidacznia obiekt PrintWorkflowForegroundSession jako właściwość. Ten obiekt, podobnie jak jego odpowiednik w tle w poprzedniej sekcji, zawiera zdarzenia wywoływane przez system wydruku i można przypisać do nich programy obsługi. W takim przypadku funkcjonalność obsługi zdarzeń zostanie zaimplementowana w oddzielnej klasie o nazwie WorkflowPage.

Najpierw w pliku App.xaml.cs:

protected override void OnActivated(IActivatedEventArgs args){

    if (args.Kind == ActivationKind.PrintWorkflowForegroundTask) {

        // the app should instantiate a new UI view so that it can properly handle the case when
        // several print jobs are active at the same time.
        Frame rootFrame = new Frame();
        if (null == Window.Current.Content)
        {
            rootFrame.Navigate(typeof(WorkflowPage));
            Window.Current.Content = rootFrame;
        }

        // Get the main page
        WorkflowPage workflowPage = (WorkflowPage)rootFrame.Content;

        // Make sure the page knows it's handling a foreground task activation
        workflowPage.LaunchType = WorkflowPage.WorkflowPageLaunchType.ForegroundTask;

        // Get the activation arguments
        PrintWorkflowUIActivatedEventArgs printTaskUIEventArgs = args as PrintWorkflowUIActivatedEventArgs;

        // Get the session manager
        PrintWorkflowForegroundSession taskSessionManager = printTaskUIEventArgs.PrintWorkflowSession;

        // Add the callback handlers - these methods are in the workflowPage class
        taskSessionManager.SetupRequested += workflowPage.OnSetupRequested;
        taskSessionManager.XpsDataAvailable += workflowPage.OnXpsDataAvailable;

        // start raising the print workflow events
        taskSessionManager.Start();
    }
}

Gdy interfejs użytkownika przypisze programy obsługi zdarzeń, a metoda OnActivated zostanie zakończona, system wydruku uruchomi zdarzenie SetupRequested, aby interfejs użytkownika mógł je obsłużyć. To zdarzenie dostarcza te same dane, które zawiera zdarzenie konfiguracji zadania w tle, w tym informacje o zadaniu wydruku i dokument dotyczący biletu wydrukowego, ale bez możliwości wnioskowania o uruchomienie dodatkowego interfejsu użytkownika. W pliku WorkflowPage.xaml.cs:

internal void OnSetupRequested(PrintWorkflowForegroundSession sessionManager, PrintWorkflowForegroundSetupRequestedEventArgs printTaskSetupArgs) {
    // If anything asynchronous is going to be done, you need to take out a deferral here,
    // since otherwise the next callback happens once this one exits, which may be premature
    Deferral setupRequestedDeferral = printTaskSetupArgs.GetDeferral();

    // Get information about the source application, print job title, and session ID
    string sourceApplicationName = printTaskSetupArgs.Configuration.SourceAppDisplayName;
    string jobTitle = printTaskSetupArgs.Configuration.JobTitle;
    string sessionId = printTaskSetupArgs.Configuration.SessionId;
    // the following string should be used when storing data that pertains to this workflow session
    // (such as user input data that is meant to change the print content later on)
    string localStorageVariablePrefix = string.Format("{0}::{1}::", sourceApplicationName, sessionID);

    try
    {
        // receive and store user input
        // ...
    }
    catch (Exception ex)
    {
        string errorMessage = ex.Message;
        Debug.WriteLine(errorMessage);
    }
    finally
    {
        // Complete the deferral taken out at the start of OnSetupRequested
        setupRequestedDeferral.Complete();
    }
}

Następnie system wydruku zgłosi zdarzenie dla interfejsu użytkownika XpsDataAvailable. W programie obsługi tego zdarzenia aplikacja przepływu pracy może uzyskać dostęp do wszystkich danych dostępnych dla zdarzenia konfiguracji i może dodatkowo bezpośrednio odczytywać dane XPS jako strumień nieprzetworzonych bajtów lub jako model obiektów. Dostęp do danych XPS umożliwia interfejsowi użytkownika udostępnianie usług podglądu wydruku oraz udostępnianie użytkownikowi dodatkowych informacji o operacjach wykonywanych przez aplikację przepływu pracy na danych.

W ramach tej procedury obsługi zdarzeń aplikacja przepływu pracy musi uzyskać obiekt odroczenia, jeśli będzie nadal współdziałać z użytkownikiem. Bez odroczenia system wydruku uzna zadanie interfejsu użytkownika za zakończone, gdy obsługa zdarzenia XpsDataAvailable zostanie zakończona lub gdy wywołuje metodę asynchroniczną. Gdy aplikacja zebrała wszystkie wymagane informacje z interakcji użytkownika z interfejsem użytkownika, powinna zakończyć odroczenie, aby system wydruku mógł następnie przejść dalej.

internal async void OnXpsDataAvailable(PrintWorkflowForegroundSession sessionManager, PrintWorkflowXpsDataAvailableEventArgs printTaskXpsAvailableEventArgs)
{
    // Take out a deferral
    Deferral xpsDataAvailableDeferral = printTaskXpsAvailableEventArgs.GetDeferral();

    SpoolStreamContent xpsStream = printTaskXpsAvailableEventArgs.Operation.XpsContent.GetSourceSpoolDataAsStreamContent();

    IInputStream inputStream = xpsStream.GetInputSpoolStream();

    using (var inputReader = new Windows.Storage.Streams.DataReader(inputStream))
    {
        // Read the XPS data from input stream
        byte[] xpsData = new byte[inputReader.UnconsumedBufferLength];
        while (inputReader.UnconsumedBufferLength > 0)
        {
            inputReader.ReadBytes(xpsData);
            // Do something with the XPS data, e.g. preview
            // ...
        }
    }

    // Complete the deferral taken out at the start of this method
    xpsDataAvailableDeferral.Complete();
}

Ponadto instancja PrintWorkflowSubmittedOperation uwidoczniona przez argumenty zdarzenia umożliwia anulowanie zadania drukowania lub wskazanie, że zadanie zakończyło się pomyślnie, ale nie będzie potrzeby na wyjściowe zadanie drukowania. Jest to wykonywane przez wywołanie metody Complete z wartością PrintWorkflowSubmittedStatus.

Uwaga / Notatka

Jeśli aplikacja przepływu pracy anuluje zadanie drukowania, zdecydowanie zaleca się zapewnienie powiadomienia typu toast wskazującego, dlaczego zadanie zostało anulowane.

Ostateczne prace w tle nad materiałami do druku

Po zakończeniu odroczenia w zdarzeniu PrintTaskXpsDataAvailable (lub jeśli krok interfejsu użytkownika został pominięty), system drukowania uruchomi zdarzenie Przesłane dla zadania w tle. W programie obsługi tego zdarzenia aplikacja przepływu pracy może uzyskać dostęp do wszystkich tych samych danych dostarczonych przez zdarzenie XpsDataAvailable. Jednak w przeciwieństwie do dowolnego z poprzednich zdarzeń Przesłane zapewnia również dostęp zapisu do końcowej zawartości zadania drukowania za pośrednictwem wystąpienia PrintWorkflowTarget.

Obiekt używany do buforowania danych na potrzeby drukowania końcowego zależy od tego, czy dostęp do danych źródłowych jest uzyskiwany jako nieprzetworzony strumień bajtów, czy model obiektów XPS. Gdy aplikacja przepływu pracy uzyskuje dostęp do danych źródłowych za pośrednictwem strumienia bajtów, przesyłany jest strumień bajtów wyjściowych w celu zapisania końcowych danych zadania. Gdy aplikacja przepływu pracy uzyskuje dostęp do danych źródłowych za pośrednictwem modelu obiektów, moduł zapisywania dokumentów jest udostępniany do zapisywania obiektów w zadaniu wyjściowym. W obu przypadkach aplikacja przepływu pracy powinna odczytywać wszystkie dane źródłowe, modyfikować wszystkie wymagane dane i zapisywać zmodyfikowane dane do miejsca docelowego danych wyjściowych.

Gdy zadanie w tle zakończy zapisywanie danych, powinno wywołać Complete w odpowiednim obiekcie PrintWorkflowSubmittedOperation. Gdy aplikacja przepływu pracy zakończy ten krok, a program obsługi zdarzeń przesłanych zostanie zamknięty, sesja przepływu pracy zostanie zamknięta i użytkownik będzie mógł monitorować stan końcowego zadania drukowania za pomocą standardowych okien dialogowych drukowania.

Ostatnie kroki

Zarejestruj aplikację do obsługi przepływu pracy drukowania w drukarce

Aplikacja przepływu pracy jest skojarzona z drukarką za pomocą takiego samego typu pliku metadanych, jak w przypadku WSDAs. W rzeczywistości jedna aplikacja platformy UWP może działać zarówno jako aplikacja przepływu pracy, jak i usługa WSDA, która zapewnia funkcje ustawień zadań drukowania. Wykonaj odpowiednie kroki WSDA dotyczące tworzenia skojarzenia metadanych.

Różnica polega na tym, że podczas gdy WSDA są automatycznie aktywowane dla użytkownika (aplikacja będzie zawsze uruchamiana, gdy ten użytkownik drukuje na powiązanym urządzeniu), aplikacje przepływu pracy nie są. Mają one oddzielne zasady, które należy ustawić.

Ustawianie zasad aplikacji przepływu pracy

Zasady aplikacji przepływu pracy są ustawiane przez polecenia programu PowerShell na urządzeniu, które ma uruchamiać aplikację przepływu pracy. Polecenia Set-Printer, Add-Printer (istniejący port) i Add-Printer (nowy port WSD) zostaną zmodyfikowane w celu umożliwienia ustawienia zasad przepływu pracy.

  • Disabled: aplikacje przepływu pracy nie zostaną aktywowane.
  • Uninitialized: Aplikacje przepływu pracy zostaną aktywowane, jeśli Workflow DCA jest zainstalowany w systemie. Jeśli aplikacja nie jest zainstalowana, drukowanie nadal będzie kontynuowane.
  • Enabled: Kontrakt przepływu pracy zostanie aktywowany, jeśli DCA przepływu pracy jest zainstalowane w systemie. Jeśli aplikacja nie jest zainstalowana, drukowanie zakończy się niepowodzeniem.

Następujące polecenie sprawia, że aplikacja przepływu pracy jest wymagana na określonej drukarce.

Set-Printer –Name "Microsoft XPS Document Writer" -WorkflowPolicy Enabled

Użytkownik lokalny może uruchomić te zasady na drukarce lokalnej lub w przypadku implementacji przedsiębiorstwa administrator drukarki może uruchomić te zasady na serwerze wydruku. Polityka zostanie następnie zsynchronizowana ze wszystkimi połączeniami klientów. Administrator drukarki może używać tych zasad za każdym razem, gdy zostanie dodana nowa drukarka.

Zobacz także

przykładowa aplikacja przepływu pracy

przestrzeni nazw Windows.Graphics.Printing.Workflow