方法 : 現在、印刷ジョブが印刷可能であるかどうかを検出する

印刷キューは、24 時間常に使用できるわけではありません。 印刷キューには開始時刻と終了時刻のプロパティがあり、特定の時間帯にキューを使用不可能にする場合にこれらを設定します。 この機能は、たとえば、特定の部門が午後 5 時以降にプリンターを独占使用するための予約を行うときに使用できます。 この部門は、プリンターにサービスを提供するキューとして、他の部門が使用するキューとは異なるキューを使用します。 この部門用のキューは常に使用できるように設定し、他の部門のキューは午後 5 時以降は使用できなくなるように設定します。

さらに、印刷ジョブ自体を、指定した時間の間だけ印刷できるように設定できます。

Microsoft .NET Framework の APIs で公開される PrintQueue クラスおよび PrintSystemJobInfo クラスは、特定の印刷ジョブが特定のキューで現在印刷可能かどうかをリモートで確認するときに利用できます。 

使用例

次の例は、印刷ジョブに関する問題を診断できるサンプルです。

この種の関数の主な手順は次の 2 つです。

  1. PrintQueueStartTimeOfDay プロパティおよび UntilTimeOfDay プロパティを読み取って、現在の時刻がこの 2 つの間であるかどうかを判断します。

  2. PrintSystemJobInfoStartTimeOfDay プロパティおよび UntilTimeOfDay プロパティを読み取って、現在の時刻がこの 2 つの間であるかどうかを判断します。

ただし、これらのプロパティは DateTime オブジェクトではないことに注意してください。 これらのプロパティは、時刻を午前 0 時からの経過時間 (分) として表す Int32 オブジェクトです。 さらに、これは、現在のタイム ゾーンでの午前 0 時ではなく、UTC (世界協定時刻) の午前 0 時です。

最初のコード例に示す静的メソッド ReportQueueAndJobAvailability では、PrintSystemJobInfo を受け取り、ヘルパー メソッドを呼び出して、ジョブが現時点で印刷できるかどうかと、できない場合はいつ印刷できるかを判断します。 PrintQueue はメソッドに渡されないことに注意してください。 これは、キューに対する参照が、PrintSystemJobInfoHostingPrintQueue プロパティに格納されているからです。

下位メソッドの 1 つに、オーバーロードされた ReportAvailabilityAtThisTime メソッドがあり、このメソッドはパラメーターとして PrintQueue または PrintSystemJobInfo を受け取ります。 また、TimeConverter.ConvertToLocalHumanReadableTime もあります。 これらのすべてのメソッドについては、後で説明します。

ReportQueueAndJobAvailability メソッドは、最初に、現時点でキューまたは印刷ジョブが使用不可能になっているかどうかを確認します。 どちらかが使用不可能の場合は、次に、キューが使用不可能かどうかを確認します。 使用不可能の場合は、このことと、いつキューが再び使用可能になるかを報告します。 次に、ジョブを確認し、使用不可能の場合は、ジョブが印刷可能になる時間帯を報告します。 最後に、このジョブが最短でいつ印刷可能になるかを報告します。 これは、次の 2 つのうち、遅い方の時刻です。

  • 印刷キューが次回使用可能になる時刻。

  • 印刷ジョブが次回使用可能になる時刻。

時刻を報告するときに、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 メソッドの 2 つのオーバーロードは、渡される型を除いて同一であるので、PrintQueue バージョンだけを後に示します

メモメモ

これらのメソッドが型以外は同一であるにもかかわらず、このサンプルでジェネリック メソッド ReportAvailabilityAtThisTime<T> を作成しない理由について次に説明します。このようなメソッドでは、メソッドが呼び出す StartTimeOfDay プロパティと UntilTimeOfDay プロパティを持つクラスを限定する必要がありますが、ジェネリック メソッドでは限定できるクラスは 1 つだけであるにもかかわらず、継承ツリー内の PrintQueuePrintSystemJobInfo の両方に共通の唯一のクラス PrintSystemObject には、これらのプロパティはありません。

ReportAvailabilityAtThisTime メソッド (後のコード例に示します) は、最初に、Boolean 型のセンティネル変数を true に初期化します。 この変数は、キューが使用不可能の場合に false に再設定されます。

次に、開始時刻と終了 (until) 時刻が同一であるかどうかを確認します。 同一ならば、キューは常時使用できるので true を返します。

キューが常時使用可能ではない場合は、静的プロパティ UtcNow を使用して、現在の時刻を DateTime オブジェクトとして取得します (StartTimeOfDay および UntilTimeOfDay プロパティ自体が UTC 時間なのでローカル時刻は必要ありません)。

ただし、この 2 つのプロパティは DateTime オブジェクトではありません。 これらは、時刻を UTC の午前 0 時からの経過時間 (分) として表す Int32 です。 したがって、DateTime オブジェクトを、午前 0 時からの経過時間 (分) に変換する必要があります。 その後で、現在の時刻 (now) がキューの開始時刻 (start) と終了時刻 (until) の間であるかどうかを調べ、現在の時刻が 2 つの時刻の間ではない場合は、センティネル変数を 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 で導入されたメソッドを使用していないので、詳しい説明は省略します。 このメソッドは、二重の変換を行います。午前 0 時からの経過時間 (分) 表す整数を受け取って、人間可読な時刻に変換し、この時刻をローカル時刻に変換する必要があります。 このことを実現するために、最初に UTC 午前 0 時に設定された DateTime オブジェクトを作成し、AddMinutes メソッドを使用して、メソッドに渡された午前 0 時からの経過時間 (分) を加算します。 このメソッドからは、渡された元の時刻を表す新しい 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 のドキュメント

印刷の概要