Condividi tramite


Procedura: individuare se è possibile eseguire o meno un processo di stampa all'orario indicato

Aggiornamento: novembre 2007

Le code di stampa non sempre sono disponibili 24 ore al giorno. È possibile impostare le proprietà relative all'ora di inizio e di fine per renderle non disponibili in determinati orari del giorno. Questa funzione può essere utilizzata, ad esempio, per riservare l'uso esclusivo di una stampante per un determinato reparto dopo le 17.00. In tal modo, il reparto avrebbe una coda di stampa diversa rispetto a quella degli altri reparti. La coda per gli altri reparti sarebbe impostata come non disponibile dopo le 17.00 mentre quella per il reparto selezionato sarebbe impostata come disponibile per tutto il tempo.

Inoltre, gli stessi processi di stampa possono essere impostati come stampabili solo entro un intervallo di tempo specificato.

Le classi PrintQueue e PrintSystemJobInfo esposte nelle API di Microsoft .NET Framework consentono di controllare in remoto se un determinato processo di stampa può essere eseguito su una determinata coda all'ora corrente.

Esempio

L'esempio riportato di seguito è tratto da un'applicazione di esempio che riesce a diagnosticare i problemi di un processo di stampa. Per l'esempio completo, vedere Esempio di diagnosi di processi di stampa problematici.

Di seguito vengono riportati i due passaggi principali di questo tipo di funzione.

  1. Leggere le proprietà StartTimeOfDay e UntilTimeOfDay di PrintQueue per determinare se comprendono l'ora corrente.

  2. Leggere le proprietà StartTimeOfDay e UntilTimeOfDay di PrintSystemJobInfo per determinare se comprendono l'ora corrente.

Tuttavia, i problemi scaturiscono dal fatto che queste proprietà non sono oggetti DateTime ma oggetti Int32 che esprimono l'orario come numero di minuti a partire dalla mezzanotte. Inoltre, non si tratta della mezzanotte del fuso orario corrente ma della mezzanotte ora UTC (Coordinated Universal Time).

Il primo esempio di codice presenta il metodo statico ReportQueueAndJobAvailability a cui viene passato PrintSystemJobInfo e che chiama i metodi di supporto per stabilire se il processo può essere stampato all'ora corrente o, in caso contrario, quando può essere stampato. Si noti che PrintQueue non viene passato al metodo perché PrintSystemJobInfo include un riferimento alla coda nella relativa proprietà HostingPrintQueue.

I metodi subordinati includono il metodo di overload ReportAvailabilityAtThisTime che può utilizzare PrintQueue o PrintSystemJobInfo come parametro. È disponibile anche TimeConverter.ConvertToLocalHumanReadableTime. Tutti questi metodi vengono esaminati di seguito.

Il metodo ReportQueueAndJobAvailability verifica innanzitutto se la coda o il processo di stampa sono disponibili in quel preciso momento. Se uno dei due non è disponibile, viene verificata la disponibilità della coda. Se la coda non è disponibile, il metodo segnala questa situazione insieme all'ora in cui sarà nuovamente disponibile la coda. Quindi, il metodo verifica il processo di stampa e, nel caso in cui non fosse disponibile, segnala il successivo intervallo di tempo in cui può essere stampato. Infine, segnala il primo orario disponibile in cui il processo può essere stampato. Si tratta della seconda condizione riportata di seguito.

  • Il primo orario in cui è disponibile la coda di stampa.

  • Il primo orario in cui è disponibile il processo di stampa.

Per il report degli orari, viene chiamato anche il metodo ToShortTimeString che elimina gli anni, i mesi e i giorni dall'output. Non è possibile limitare la disponibilità di una coda o di un processo di stampa ad anni, mesi o giorni specifici.

internal static void ReportQueueAndJobAvailability(PrintSystemJobInfo theJob)
{
    if (!(ReportAvailabilityAtThisTime(theJob.HostingPrintQueue) && ReportAvailabilityAtThisTime(theJob)))
    {
        if (!ReportAvailabilityAtThisTime(theJob.HostingPrintQueue))
        {
            Console.WriteLine("\nThat queue is not available at this time of day." +
                "\nJobs in the queue will start printing again at {0}",
                 TimeConverter.ConvertToLocalHumanReadableTime(theJob.HostingPrintQueue.StartTimeOfDay).ToShortTimeString());
            // TimeConverter class is defined in the complete sample
        }

        if (!ReportAvailabilityAtThisTime(theJob))
        {
            Console.WriteLine("\nThat job is set to print only between {0} and {1}",
                TimeConverter.ConvertToLocalHumanReadableTime(theJob.StartTimeOfDay).ToShortTimeString(),
                TimeConverter.ConvertToLocalHumanReadableTime(theJob.UntilTimeOfDay).ToShortTimeString());
        }
        Console.WriteLine("\nThe job will begin printing as soon as it reaches the top of the queue after:");
        if (theJob.StartTimeOfDay > theJob.HostingPrintQueue.StartTimeOfDay)
        {
            Console.WriteLine(TimeConverter.ConvertToLocalHumanReadableTime(theJob.StartTimeOfDay).ToShortTimeString());
        }
        else
        {
            Console.WriteLine(TimeConverter.ConvertToLocalHumanReadableTime(theJob.HostingPrintQueue.StartTimeOfDay).ToShortTimeString());
        }

    }//end if at least one is not available

}//end ReportQueueAndJobAvailability
static void ReportQueueAndJobAvailability (PrintSystemJobInfo^ theJob) 
{
   if (!(ReportAvailabilityAtThisTime(theJob->HostingPrintQueue) && ReportAvailabilityAtThisTime(theJob)))
   {
      if (!ReportAvailabilityAtThisTime(theJob->HostingPrintQueue))
      {
         Console::WriteLine("\nThat queue is not available at this time of day." + "\nJobs in the queue will start printing again at {0}", TimeConverter::ConvertToLocalHumanReadableTime(theJob->HostingPrintQueue->StartTimeOfDay).ToShortTimeString());
         // TimeConverter class is defined in the complete sample
      }
      if (!ReportAvailabilityAtThisTime(theJob))
      {
         Console::WriteLine("\nThat job is set to print only between {0} and {1}", TimeConverter::ConvertToLocalHumanReadableTime(theJob->StartTimeOfDay).ToShortTimeString(), TimeConverter::ConvertToLocalHumanReadableTime(theJob->UntilTimeOfDay).ToShortTimeString());
      }
      Console::WriteLine("\nThe job will begin printing as soon as it reaches the top of the queue after:");
      if (theJob->StartTimeOfDay > theJob->HostingPrintQueue->StartTimeOfDay)
      {
         Console::WriteLine(TimeConverter::ConvertToLocalHumanReadableTime(theJob->StartTimeOfDay).ToShortTimeString());
      } else
      {
         Console::WriteLine(TimeConverter::ConvertToLocalHumanReadableTime(theJob->HostingPrintQueue->StartTimeOfDay).ToShortTimeString());
      }

   }
};

I due overload del metodo ReportAvailabilityAtThisTime sono identici ad eccezione del tipo ricevuto. Di seguito, viene quindi presentata solo la versione PrintQueue. Per l'esempio completo, vedere Esempio di diagnosi di processi di stampa problematici.

Nota

Il fatto che i metodi siano identici ad eccezione del tipo, pone la questione del perché l'esempio non crea un metodo ReportAvailabilityAtThisTime<T> generico. Il motivo è che questo metodo dovrebbe essere limitato a una classe con le proprietà StartTimeOfDay e UntilTimeOfDay chiamate dal metodo, ma un metodo generico può essere limitato a una sola classe e l'unica classe comune a PrintQueue e a PrintSystemJobInfo nella struttura ad albero di ereditarietà è PrintSystemObject che non dispone di tali proprietà.

Il metodo ReportAvailabilityAtThisTime, illustrato nell'esempio di codice di seguito, avvia l'inizializzazione di una variabile sentinel Boolean su true. Se la coda non è disponibile, verrà reimpostata su false.

Quindi, il metodo verifica se l'ora di inizio e l'ora di fine coincidono. In tal caso, la coda è sempre disponibile e il metodo restituisce true.

Se la coda non è disponibile per tutto il tempo, il metodo utilizza la proprietà statica UtcNow per ottenere l'ora corrente come oggetto DateTime. L'ora locale non è necessaria perché le proprietà StartTimeOfDay e UntilTimeOfDay sono in formato UTC.

Tuttavia, queste due proprietà non sono oggetti DateTime ma oggetti Int32 che esprimono l'orario come numero di minuti dopo la mezzanotte ora UTC. È quindi necessario convertire l'oggetto DateTime in minuti dopo la mezzanotte. Quindi, il metodo verifica se "now" si trova tra l'ora di inizio e l'ora di fine della coda, imposta sentinel su false se "now" non è compreso tra i due orari e quindi restituisce sentinel.

private static Boolean ReportAvailabilityAtThisTime(PrintQueue pq)
{
    Boolean available = true;
    if (pq.StartTimeOfDay != pq.UntilTimeOfDay) // If the printer is not available 24 hours a day
    {
        DateTime utcNow = DateTime.UtcNow;
        Int32 utcNowAsMinutesAfterMidnight = (utcNow.TimeOfDay.Hours * 60) + utcNow.TimeOfDay.Minutes;

        // If now is not within the range of available times . . .
        if (!((pq.StartTimeOfDay < utcNowAsMinutesAfterMidnight) 
           && 
           (utcNowAsMinutesAfterMidnight < pq.UntilTimeOfDay)))
        {
            available = false;
        }
    }
    return available;
}//end ReportAvailabilityAtThisTime
static Boolean ReportAvailabilityAtThisTime (PrintQueue^ pq) 
{
   Boolean available = true;
   if (pq->StartTimeOfDay != pq->UntilTimeOfDay)
   {
      DateTime utcNow = DateTime::UtcNow;
      Int32 utcNowAsMinutesAfterMidnight = (utcNow.TimeOfDay.Hours * 60) + utcNow.TimeOfDay.Minutes;

      // If now is not within the range of available times . . .
      if (!((pq->StartTimeOfDay < utcNowAsMinutesAfterMidnight) && (utcNowAsMinutesAfterMidnight < pq->UntilTimeOfDay)))
      {
         available = false;
      }
   }
   return available;
};

Il metodo TimeConverter.ConvertToLocalHumanReadableTime, illustrato nell'esempio di codice di seguito, non utilizza alcun metodo introdotto con Microsoft .NET Framework. Il metodo deve eseguire una doppia attività di conversione: deve convertire un numero intero che esprime i minuti dopo la mezzanotte in un orario leggibile e quindi convertire quest'ultimo nell'ora locale. A tale scopo, viene creato prima un oggetto DateTime, impostato sulla mezzanotte ora UTC, quindi viene utilizzato il metodo AddMinutes per aggiungere i minuti passati al metodo. Viene restituito un nuovo oggetto DateTime che esprime l'ora originale passata al metodo. Quindi, il metodo ToLocalTime la converte nell'ora locale.

class TimeConverter
{
    // Convert time as minutes past UTC midnight into human readable time in local time zone.
    internal static DateTime ConvertToLocalHumanReadableTime(Int32 timeInMinutesAfterUTCMidnight)
    {
        // Construct a UTC midnight object.
        // Must start with current date so that the local Daylight Savings system, if any, will be taken into account.
        DateTime utcNow = DateTime.UtcNow; 
        DateTime utcMidnight = new DateTime(utcNow.Year, utcNow.Month, utcNow.Day, 0, 0, 0, DateTimeKind.Utc);

        // Add the minutes passed into the method in order to get the intended UTC time.
        Double minutesAfterUTCMidnight = (Double)timeInMinutesAfterUTCMidnight;
        DateTime utcTime = utcMidnight.AddMinutes(minutesAfterUTCMidnight);

        // Convert to local time.
        DateTime localTime = utcTime.ToLocalTime();

        return localTime;

    }// end ConvertToLocalHumanReadableTime

}//end TimeConverter class
private ref class TimeConverter {

internal: 
   static DateTime ConvertToLocalHumanReadableTime (Int32 timeInMinutesAfterUTCMidnight) 
   {
      // Construct a UTC midnight object.
      // Must start with current date so that the local Daylight Savings system, if any, will be taken into account.
      DateTime utcNow = DateTime::UtcNow;
      DateTime utcMidnight = DateTime(utcNow.Year, utcNow.Month, utcNow.Day, 0, 0, 0, DateTimeKind::Utc);

      // Add the minutes passed into the method in order to get the intended UTC time.
      Double minutesAfterUTCMidnight = ((Double)timeInMinutesAfterUTCMidnight);
      DateTime utcTime = utcMidnight.AddMinutes(minutesAfterUTCMidnight);

      // Convert to local time.
      DateTime localTime = utcTime.ToLocalTime();

      return localTime;
   };
};

Vedere anche

Concetti

Documenti di Windows Presentation Foundation

Cenni preliminari sulla stampa

Riferimenti

DateTime

PrintSystemJobInfo

PrintQueue

Altre risorse

Esempi relativi alla stampa