다음을 통해 공유


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

인쇄 큐를 하루 24시간 내내 사용할 수 있는 것은 아닙니다. 인쇄 큐에는 특정 시간에 사용할 수 없도록 설정할 수 있는 시작 및 종료 시간 속성이 있습니다. 예를 들어 오후 5시 이후에는 프린터를 특정 부서가 독점적으로 사용하도록 예약하는 데 이 기능을 사용할 수 있습니다. 해당 부서에서는 다른 부서에서 사용하는 것과 다른 큐에서 프린터를 처리하게 됩니다. 다른 부서의 큐는 오후 5시 이후에는 사용할 수 없도록 설정하고 선택한 부서의 큐는 항상 사용할 수 있도록 설정할 수 있습니다.

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

Microsoft .NET Framework의 APIs에 노출된 PrintQueuePrintSystemJobInfo 클래스를 사용하면 현재 시간에 지정한 큐에서 지정한 인쇄 작업을 인쇄할 수 있는지 여부를 원격으로 확인할 수 있습니다. 

예제

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

이러한 종류의 기능에 대한 두 가지 주요 단계는 다음과 같습니다.

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

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

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

첫 번째 코드 예제에서는 정적 메서드 ReportQueueAndJobAvailability를 보여 줍니다. 이 메서드는 PrintSystemJobInfo를 전달받고 도우미 메서드를 호출하여 현재 시간에 작업을 인쇄할 수 있는지, 그리고 인쇄할 수 없는 경우 언제 인쇄할 수 있는지를 확인합니다. PrintQueue는 이 메서드에 전달되지 않습니다. 그 이유는 PrintSystemJobInfo에서 해당 HostingPrintQueue 속성에서 큐에 대한 참조를 포함하고 있기 때문입니다.

하위 수준 메서드에는 PrintQueue 또는 PrintSystemJobInfo를 매개 변수로 사용하는 오버로드된 ReportAvailabilityAtThisTime 메서드가 포함되어 있습니다. 또한 TimeConverter.ConvertToLocalHumanReadableTime도 있습니다. 이러한 메서드에 대해서는 아래에서 설명합니다.

ReportQueueAndJobAvailability 메서드에서는 먼저 현재 시간에 큐 또는 인쇄 작업을 사용할 수 없는지 확인합니다. 이들 중 하나라도 사용할 수 없는 경우 큐를 사용할 수 없는지 확인합니다. 사용할 수 없는 경우 메서드에서는 이 사실과 큐를 다시 사용할 수 있게 될 시간을 보고합니다. 그런 다음 작업을 확인하고 작업을 사용할 수 없는 경우 다음에 인쇄할 수 있는 시간 범위를 보고합니다. 마지막으로 이 메서드는 작업을 인쇄할 수 있는 가장 이른 시간을 보고합니다. 이 시간은 다음 두 시간 중 나중 시간입니다.

  • 인쇄 큐를 사용할 수 있는 다음 시간

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

시간을 보고할 때는 출력에서 년, 월 및 일을 표시하지 않도록 만드는 ToShortTimeString 메서드도 호출합니다. 인쇄 큐나 인쇄 작업의 가용성을 특정 년, 월 또는 일로 제한할 수는 없습니다.

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

   }
};

ReportAvailabilityAtThisTime 메서드의 두 오버로드는 전달받는 형식을 제외하고는 동일합니다. 따라서 아래에서는 PrintQueue 버전만 표시됩니다.

참고참고

이들 메서드가 형식을 제외하고는 동일한데 샘플에서 제네릭 메서드 ReportAvailabilityAtThisTime<T>를 만들지 않은 이유가 궁금할 것입니다.그 이유는 이러한 메서드는 메서드에서 호출하는 StartTimeOfDayUntilTimeOfDay 속성이 있는 클래스로 제한해야 하지만 제네릭 메서드는 단일 클래스로만 제한할 수 있고 상속 트리에서 PrintQueuePrintSystemJobInfo 모두에 공통인 클래스는 이러한 속성이 없는 PrintSystemObject뿐이기 때문입니다.

아래 코드 예제에 표시된 ReportAvailabilityAtThisTime 메서드는 먼저 Boolean 센티널 변수를 true로 초기화합니다. 큐를 사용할 수 없는 경우 이 변수가 false로 재설정됩니다.

그런 다음 이 메서드는 시작 및 "끝" 시간이 동일한지 확인합니다. 동일한 경우 큐를 항상 사용할 수 있으므로 메서드는 true를 반환합니다.

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

그러나 이러한 두 속성은 DateTime 개체가 아닙니다. 이러한 속성은 시간을 UTC 자정 이후의 시간(분)으로 표시하는 Int32입니다. 따라서 DateTime 개체를 자정 이후의 시간(분)으로 변환해야 합니다. 변환을 마치면 메서드에서는 "지금"이 큐의 시작 및 "끝" 시간 사이에 있는지 확인하고 "지금"이 두 시간 사이에 없으면 센티널을 false로 설정한 다음 센티널을 반환합니다.

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

아래 코드 예제에 표시된 TimeConverter.ConvertToLocalHumanReadableTime 메서드는 Microsoft .NET Framework에 새로 추가된 메서드를 사용하지 않으므로 간략히 설명하고 넘어갑니다. 이 메서드는 이중 변환 작업을 수행합니다. 자정 이후의 시간(분)을 표시하는 정수를 가져와서 사람이 인식할 수 있는 시간으로 변환한 다음 이를 현지 시간으로 변환해야 합니다. 이를 수행하기 위해 먼저 UTC 자정으로 설정된 DateTime 개체를 만든 다음 AddMinutes 메서드를 사용하여 메서드에 전달된 시간(분)을 추가합니다. 그러면 메서드에 전달된 원래 시간을 표시하는 새 DateTime이 반환됩니다. 그런 다음 ToLocalTime 메서드에서 이 시간을 현지 시간으로 변환합니다.

    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 'end TimeConverter class
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;
   };
};

참고 항목

참조

DateTime

PrintSystemJobInfo

PrintQueue

개념

WPF의 문서

인쇄 개요