다음을 통해 공유


방법: 인쇄 작업을 현재 인쇄할 수 있는지 확인

인쇄 대기열을 늘 하루 24시간 동안 사용할 수 있는 것은 아닙니다. 하루 중 인쇄 대기열에는 특정 시간에 사용할 수 없도록 설정될 수 있는 시작 및 종료 시간 속성이 있습니다. 예를 들어, 오후 5시 이후에 특정 부서에서만 사용하도록 프린터를 예약할 때 이 기능을 사용할 수 있습니다. 해당 부서의 프린터 사용 대기열은 다른 부서에서 사용하는 것과 다를 것입니다. 다른 부서의 대기열은 오후 5시 이후에 사용할 수 없도록 설정되지만 선호하는 부서의 대기열은 항상 사용할 수 있도록 설정할 수 있을 것입니다.

또한 인쇄 작업 자체는 지정된 시간 범위 내에서만 인쇄가 가능하도록 설정할 수 있습니다.

Microsoft .NET Framework의 API에 노출되는 PrintQueuePrintSystemJobInfo 클래스를 통해 지정된 인쇄 작업이 현재 지정된 대기열에서 인쇄할 수 있는지 여부를 원격으로 확인할 수 있습니다.

예제

아래 예제는 인쇄 작업의 문제를 진단할 수 있는 샘플입니다.

이 종류의 기능에는 다음 두 가지 주요 단계가 있습니다.

  1. PrintQueueStartTimeOfDayUntilTimeOfDay 속성을 읽어 현재 시간이 이 둘 사이인지 확인합니다.

  2. PrintSystemJobInfoStartTimeOfDayUntilTimeOfDay 속성을 읽어 현재 시간이 이 둘 사이인지 확인합니다.

그러나 이러한 속성이 DateTime 개체가 아니라는 사실에서 문제가 발생합니다. 이러한 속성은 자정 이후 시간(분)으로 시간을 표현하는 Int32 개체입니다. 게다가 현재 표준 시간대의 자정이 아니라 자정 UTC(협정 세계시)입니다.

첫 번째 코드 예제는 PrintSystemJobInfo로 전달되는 정적 메서드 ReportQueueAndJobAvailability를 제시하고 도우미 메서드를 호출하여 작업이 현재 시간에 인쇄할 수 있는지 여부와 인쇄할 수 있는 시점을 확인합니다. PrintQueue는 메서드로 전달되지 않습니다. PrintSystemJobInfo는 그 HostingPrintQueue 속성에 대기열 참조가 포함되기 때문입니다.

하위 메서드에는 PrintQueue 또는 PrintSystemJobInfo를 매개변수로 사용할 수 있는 오버로드된 ReportAvailabilityAtThisTime 메서드가 포함됩니다. TimeConverter.ConvertToLocalHumanReadableTime도 있습니다. 이 모든 방법이 아래에 설명되어 있습니다.

ReportQueueAndJobAvailability 메서드는 현재 대기열 또는 인쇄 작업을 사용할 수 없는지 여부를 확인하는 것으로 시작합니다. 둘 중 하나를 사용할 수 없는 경우 대기열을 사용할 수 없는지 확인합니다. 사용할 수 없는 경우 이 메서드는 이 사실과 대기열을 다시 사용할 수 있게 되는 시간을 보고합니다. 그런 다음 작업을 확인하고 작업을 사용할 수 없는 경우 인쇄할 수 있는 다음 시간 범위를 보고합니다. 마지막으로 이 메서드는 작업을 인쇄할 수 있는 가장 빠른 시간을 보고합니다. 이것은 다음 두 시간 중 나중 시간입니다.

  • 다음에 인쇄 대기열을 사용할 수 있는 시간입니다.

  • 다음에 인쇄 작업을 사용할 수 있는 시간입니다.

하루 중 시간을 보고할 때 ToShortTimeString 메서드도 호출되는데 그 이유는 출력에 연, 월, 일을 표시하지 않기 때문입니다. 인쇄 대기열 또는 인쇄 작업의 사용 가능성을 특정 연, 월, 일로 제한할 수 없습니다.

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

   }
};
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
Friend Shared Sub ReportQueueAndJobAvailability(ByVal theJob As PrintSystemJobInfo)
    If Not(ReportAvailabilityAtThisTime(theJob.HostingPrintQueue) AndAlso ReportAvailabilityAtThisTime(theJob)) Then
        If Not ReportAvailabilityAtThisTime(theJob.HostingPrintQueue) Then
            Console.WriteLine(vbLf & "That queue is not available at this time of day." & vbLf & "Jobs in the queue will start printing again at {0}", TimeConverter.ConvertToLocalHumanReadableTime(theJob.HostingPrintQueue.StartTimeOfDay).ToShortTimeString())
            ' TimeConverter class is defined in the complete sample
        End If

        If Not ReportAvailabilityAtThisTime(theJob) Then
            Console.WriteLine(vbLf & "That job is set to print only between {0} and {1}", TimeConverter.ConvertToLocalHumanReadableTime(theJob.StartTimeOfDay).ToShortTimeString(), TimeConverter.ConvertToLocalHumanReadableTime(theJob.UntilTimeOfDay).ToShortTimeString())
        End If
        Console.WriteLine(vbLf & "The job will begin printing as soon as it reaches the top of the queue after:")
        If theJob.StartTimeOfDay > theJob.HostingPrintQueue.StartTimeOfDay Then
            Console.WriteLine(TimeConverter.ConvertToLocalHumanReadableTime(theJob.StartTimeOfDay).ToShortTimeString())
        Else
            Console.WriteLine(TimeConverter.ConvertToLocalHumanReadableTime(theJob.HostingPrintQueue.StartTimeOfDay).ToShortTimeString())
        End If

    End If 'end if at least one is not available

End Sub

ReportAvailabilityAtThisTime 메서드의 두 오버로드는 동일하지만 이에 전달되는 형식만 다르므로 PrintQueue 버전만 아래에 표시됩니다.

참고

두 메서드가 동일하지만 형식만 달라 이 샘플에서는 제네릭 메서드 ReportAvailabilityAtThisTime<T>를 만들지 않는 이유에 대한 의문이 제기됩니다. 그 이유는 이러한 메서드는 메서드가 호출하지만 제네릭 메서드가 단일 클래스로 제한될 수 있는 StartTimeOfDayUntilTimeOfDay 속성이 있는 클래스로 제한해야 하지만 제네릭 메서드는 단일 클래스로 제한될 수 있으며 상속 트리에서 PrintQueuePrintSystemJobInfo에만 공통되는 클래스는 이러한 속성이 없는 PrintSystemObject이기 때문입니다.

ReportAvailabilityAtThisTime 메서드(아래 코드 예제에 다옴)는 Boolean sentinel 변수를 true로 초기화하는 것으로 시작합니다. 대기열을 사용할 수 없는 경우 false로 다시 설정됩니다.

다음으로 이 메서드는 시작 시간과 "끝" 시간이 같은지 확인합니다. 같으면 대기열을 항상 사용할 수 있어 메서드가 true를 반환합니다.

대기열을 항상 사용할 수 없는 경우 메서드는 정적 UtcNow 속성을 사용하여 현재 시간을 DateTime 개체로 가져옵니다. (StartTimeOfDayUntilTimeOfDay 속성은 UTC 시간이므로 현지 시간이 필요하지 않습니다.)

그러나 이 두 속성은 DateTime 개체가 아닙니다. 이 둘은 시간을 UTC-자정 이후의 분 수로 표현하는 Int32다. 따라서 DateTime 개체를 자정 이후 분으로 변환해야 합니다. 이 작업이 완료되면 메서드는 단순히 "지금"이 대기열의 시작 시간과 "끝" 시간 사이인지 확인하고, "지금"이 두 시간 사이에 있지 않으면 sentinel을 false로 설정하고, sentinel을 반환합니다.

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;
};
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
Private Shared Function ReportAvailabilityAtThisTime(ByVal pq As PrintQueue) As Boolean
    Dim available As Boolean = True
    If pq.StartTimeOfDay <> pq.UntilTimeOfDay Then ' If the printer is not available 24 hours a day
        Dim utcNow As Date = Date.UtcNow
        Dim utcNowAsMinutesAfterMidnight As Int32 = (utcNow.TimeOfDay.Hours * 60) + utcNow.TimeOfDay.Minutes

        ' If now is not within the range of available times . . .
        If Not((pq.StartTimeOfDay < utcNowAsMinutesAfterMidnight) AndAlso (utcNowAsMinutesAfterMidnight < pq.UntilTimeOfDay)) Then
            available = False
        End If
    End If
    Return available
End Function 'end ReportAvailabilityAtThisTime

TimeConverter.ConvertToLocalHumanReadableTime 메서드(아래 코드 예제에 나옴)는 Microsoft .NET Framework에 도입된 메서드를 사용하지 않으므로 여기서는 간단하게 다룹니다. 이 메서드에는 이중 변환 작업이 있어 자정 이후 분을 표현하는 정수를 사람이 읽을 수 있는 시간으로 변환해야 하며 이를 현지 시간으로 변환해야 합니다. 먼저 UTC 자정으로 설정된 DateTime 개체를 만든 다음 AddMinutes 메서드를 사용하여 메서드에 전달된 분을 추가하여 이 작업을 수행합니다. 그러면 메서드에 전달된 원래 시간을 표현하는 새 DateTime가 반환됩니다. 그런 다음 ToLocalTime 메서드가 이를 현지 시간으로 변환합니다.

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;
   };
};
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
Friend Class TimeConverter
    ' Convert time as minutes past UTC midnight into human readable time in local time zone.
    Friend Shared Function ConvertToLocalHumanReadableTime(ByVal timeInMinutesAfterUTCMidnight As Int32) As Date
        ' Construct a UTC midnight object.
        ' Must start with current date so that the local Daylight Savings system, if any, will be taken into account.
        Dim utcNow As Date = Date.UtcNow
        Dim utcMidnight As New Date(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.
        Dim minutesAfterUTCMidnight As Double = CType(timeInMinutesAfterUTCMidnight, Double)
        Dim utcTime As Date = utcMidnight.AddMinutes(minutesAfterUTCMidnight)

        ' Convert to local time.
        Dim localTime As Date = utcTime.ToLocalTime()

        Return localTime

    End Function ' end ConvertToLocalHumanReadableTime

End Class

참고 항목