Compartilhar via


Como: Discover Whether a Print Job Can Be Printed At This Time of Day

Filas de impressão nem sempre estão disponíveis 24 horas por dia. Elas têm propriedades de horários de início e fim que podem ser definidas para torná-las indisponíveis em certas horas do dia. Essa característica pode ser utilizada, por exemplo, para reservar uma impressora para uso exclusivo de um certo departamento após 5 P.M. Aquele departamento poderia ter uma fila diferente oferecendo serviço de impressão que outros departamentos utilizam. A fila para outros departamentos poderia ser definida como indisponível após 5 P.M., enquanto a fila para o departamento favorecido poderia ser definida como disponível a toda hora.

Além disso, os próprios trabalhos de impressão podem ser definidos para serem impressos apenas numa determinada faixa de tempo.

As classes PrintQueue e PrintSystemJobInfo expostas nas APIs do Microsoft .NET Framework fornecem um meio de verificar remotamente se um determinado trabalho de impressão pode ser impresso numa dada fila no momento atual.

Exemplo

O exemplo abaixo é tirado de uma aplicação de exemplo que pode diagnosticar problemas com um trabalho de impressão. Para o exemplo completo, veja Diagnosticar problemáticos trabalho de Imprimir exemplo.

Há dois passos principais para esse tipo de função, como segue.

  1. Ler as propriedades StartTimeOfDay e UntilTimeOfDay do PrintQueue para determinar se o horário atual está entre eles.

  2. Ler as propriedades StartTimeOfDay e UntilTimeOfDay do PrintSystemJobInfo para determinar se o horário atual está entre eles.

Mas complicaçoes surgem do fato que essas propriedades não são objetos DateTime. Em vez disso, são objetos Int32 que expressam a hora do dia como número de minutos desde a meia-noite. Além disso, não é meia-noite na zona de horário atual, mas meia-noite UTC (Coordinated Universal Time).

O primeiro código de exemplo apresenta o método estático ReportQueueAndJobAvailability, a que é passado um PrintSystemJobInfo e chama métodos auxiliares para determinar se um trabalho pode ser impresso no horário atual e, se não, quando pode ser impresso. Observe que um PrintQueue não é passado para o método. Isso ocorre porque o PrintSystemJobInfo inclui uma referência à fila na sua propriedade HostingPrintQueue.

Os métodos subordinados incluem o método sobrecarregado ReportAvailabilityAtThisTime que pode receber um PrintQueue ou um PrintSystemJobInfo como parâmetro. Também há um TimeConverter.ConvertToLocalHumanReadableTime. Todos esses métodos são discutidos abaixo.

O método ReportQueueAndJobAvailability começa verificando se a fila ou o trabalho de impressão está indisponível neste momento. Se cada um deles estiver indisponível, verifica então para ver se a fila está indisponível. Se não estiver disponível, então o método relata o fato e a hora em que a fila estará disponível novamente. Então verifica o trabalho e, se estiver indisponível, relata a próxima faixa de horário em que pode ser impresso. Finalmente, o método relata o horário mais cedo em que o trabalho pode ser impresso. Isso é o mais tarde dos dois horários seguintes.

  • O horário em que a fila de impressão estará disponível.

  • O horário em que a fila de impressão estará disponível.

Ao reportar horários do dia, o método ToShortTimeString também é chamado porque esse método suprime os anos, meses e dias da saída. Você não pode restringir a disponibilidade de uma fila de impressão ou trabalho de impressão a anos, meses ou dias particulares.

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

   }
};

As duas sobrecargas do método ReportAvailabilityAtThisTime são idênticas, exceto pelo tipo passado a elas, então apenas a versão PrintQueue é apresentada a seguir. Para o exemplo completo, veja Diagnosticar problemáticos trabalho de Imprimir exemplo.

ObservaçãoObservação:

O fato de que os métodos são idênticos, exceto para o tipo levanta a questão de por que a amostra não cria um método genérico ReportAvailabilityAtThisTime <t>. O motivo é que um tal método teria que ser restrito a uma classe que tem as propriedades StartTimeOfDay e UntilTimeOfDay que o método chama, mas um método genérico só pode ser restrito a uma única classe e a única classe comum a bmaos PrintQueue e PrintSystemJobInfo na árvore de herança é PrintSystemObject, que não tem tais propriedades.

O método ReportAvailabilityAtThisTime (apresentado no código de exemplo abaixo) começa inicializando uma variável de sentinela Boolean como true. Será redefinido como false se a fila não estiver disponível.

Em seguida, o método verifica se os horários de início de "até" são idênticos. Se forem, a fila sempre estará disponível, e então o método retorna true.

Se a fila não estiver disponível o tempo todo, o método utiliza a propriedade estática UtcNow para obter o horário atual como um objeto DateTime. (Não precisamos do tempo local porque as propriedades StartTimeOfDay e UntilTimeOfDay são elas próprias em horário UTC.)

Entretanto, essas duas propriedades não são objetos DateTime. Elas são Int32s expressando o horário como o número de minutos após a meia-noite-UTC. Então temos que converter nosso objeto DateTime em minutos-após-meia-noite. Quando isso é feito, o método simplesmente verifica para ver se "agora" está entre os horários de início e "até" da fila, define a sentinela como falso se "agora" não estiver entre os dois horários, e retorna a sentinela.

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

O método TimeConverter.ConvertToLocalHumanReadableTime (apresentado no código de exemplo abaixo) não utiliza quaisquer métodos introduzidos com o Microsoft .NET Framework, então a discussão é breve. O método tem uma tarefa de conversão dupla: Ele deve fazer um número inteiro expressar meia minutos depois-noite e convertê-lo em um horário legível e ele deve converter isso para a time local. Realiza isso criando primeiro um objeto DateTime definido como meia-noite UTC e então utiliza o método AddMinutes para acrescentar os minutos que foram passados ao método. Isso retorna um novo DateTime expressando o horário original que foi passado ao método. O método ToLocalTime converte isso então para o horário local.

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

Consulte também

Conceitos

Documentos em Windows Presentation Foundation

Visão Geral de Impressão

Referência

DateTime

PrintSystemJobInfo

PrintQueue

Outros recursos

Exemplos de impressão