質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
印刷

印刷とは、インキを用いて紙などの被印刷物に機械的に複製することを指します。現在は紙などの2次元の媒体だけでなく、3次元の曲面にも直接印刷する技術など様々な開発が進んでいます。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

.NET Framework 4.0

Microsoft Windows用のソフトウェア開発環境/実行環境である .NET Frameworkの4番目のメジャーバージョンです。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

Q&A

0回答

9978閲覧

PrintSystemJobInfo.JobStatusを使って印刷ジョブを監視し、印刷完了を判定したい

toro1

総合スコア90

印刷

印刷とは、インキを用いて紙などの被印刷物に機械的に複製することを指します。現在は紙などの2次元の媒体だけでなく、3次元の曲面にも直接印刷する技術など様々な開発が進んでいます。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

.NET Framework 4.0

Microsoft Windows用のソフトウェア開発環境/実行環境である .NET Frameworkの4番目のメジャーバージョンです。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

0グッド

0クリップ

投稿2017/08/07 03:12

編集2017/08/08 04:13

###前提・実現したいこと
今、vb.netでプリンタのスプーラのジョブを監視し、紙に印字されたかもしくは紙に印字される前にジョブをキャンセルされるかが判断するまで、ウェイトをかける(次の処理を待つ)プログラムを作成しています。(また、この時スプーラにジョブを残して再印刷するなどは今回は考慮していません)

ソースの参考にしたURL
https://social.msdn.microsoft.com/Forums/vstudio/ja-JP/0f697287-9643-4434-acf5-acc00b2e9a86?forum=vbgeneralja

###発生している問題
下記の判定で良いかどうかの裏付けを取りたいのでPrintSystemJobInfo.JobStatusが印刷完了しスプーラのジョブが削除されるまでにはどのように状態遷移するかの資料を探しています。

###印刷時の判定内容
紙に印刷された事を判定するのに、targetJob.JobStatus が PrintJobStatus.Completed を含む時、フラグを立て(printing=true)、targetJob.JobStatus が PrintJobStatus.Deleted を含む時、printing=trueかで印刷が完了したかの判断をしています。

###追伸
下記のソースコードを使ってプリンタに印刷しテストを行い、そのときの経験的に下記の紙に印刷された時の判定を決めました。

###該当のソースコード

vb.net

1 Dim QUEUE_POLLING_INTERVAL As Integer = 2 2 ''' <summary> 3 ''' 指定したドキュメントの印刷が開始されるまで待機します。 4 ''' </summary> 5 ''' <param name="printerName">印刷を行うプリンタ名。</param> 6 ''' <param name="timeOut">タイムアウト(ms)。0を指定すると無制限に待機します。</param> 7 ''' <param name="fileName">印刷の開始を待機するドキュメント名を指定します。</param> 8 ''' <param name="extention">印刷の開始を待機するドキュメントの拡張子を指定します。大文字・小文字は区別されません。</param> 9 ''' <param name="includes">印刷の開始を待機するドキュメント名に含まれる文字列を指定します。アルファベットが含まれる場合、大文字・小文字は区別されます。</param> 10 ''' <remarks> 11 ''' ジョブ名と <paramref name="fileName" /> が完全に一致するか、ジョブ名に <paramref name="includes" /> で指定した文字列が全て含まれているジョブの印刷開始を待機します。 12 ''' </remarks> 13 Private Function WaitForPrint(ByVal printerName As String, ByVal timeOut As Long, ByVal fileName As String, ByVal extention As String, ByVal ParamArray includes() As String) As Boolean 14 Dim isComprete As Boolean = False '紙に印字されたらTrue 15 Dim logid As Integer = Now.Millisecond 16 17 Dim includesString As String = String.Empty 18 includesString = String.Join(", ", includes) 19 20 Dim arguments As New System.Text.StringBuilder() 21 arguments.AppendLine(String.Format("printername : {0}", printerName)) 22 arguments.AppendLine(String.Format("timeOut : {0}", timeOut)) 23 arguments.AppendLine(String.Format("fileName : {0}", fileName)) 24 arguments.AppendLine(String.Format("extention : {0}", extention)) 25 arguments.AppendLine(String.Format("includes : {0}", includesString)) 26 27 Try 28 Me.LogWrite("プリンタ:{0} の印刷開始を待機します。(タイムアウト:{1} ms)" & vbCrLf & "引数 : {2}", printerName, timeOut, arguments.ToString) 29 30 ' プリンタのキューを取得し、指定されたジョブが開始されるまで待機 31 Using queue As PrintQueue = GetPrintQueue(printerName) 32 33 ' タイムアウト計測用タイマ 34 Dim st As New Stopwatch() 35 36 ' 印刷が開始されたことを示すフラグ 37 Dim spooling As Boolean = False 38 Dim printing As Boolean = False 'プリントが完了した場合はtrue(キャンセルで削除された場合もtrue) 39 40 ' タイムアウトが設定されていればタイマをスタート 41 If (timeOut > 0) Then st.Start() 42 43 Dim jobFound As Boolean = False 44 Dim targetJob As PrintSystemJobInfo = Nothing 45 46 Dim OldMessage As String = String.Empty 47 48 Do Until (printing = True) 49 ' CPUリソースを占有しないようにスリープ 50 System.Threading.Thread.Sleep(QUEUE_POLLING_INTERVAL) 51 'Application.DoEvents() 52 53 ' タイムアウト判定 54 If (st.ElapsedMilliseconds > timeOut) Then 55 If (jobFound = True) Then 56 Try 57 targetJob.Cancel() 58 Catch ex As Exception 59 ' ジョブキャンセル時の例外は無視 60 End Try 61 End If 62 Throw New TimeoutException("操作がタイムアウトしました。", New Exception(arguments.ToString)) 63 End If 64 65 ' まずはキューからジョブを検索する 66 If (jobFound = False) Then 67 ' キュー内のジョブを列挙 68 queue.Refresh() 69 Dim jobs As PrintJobInfoCollection = queue.GetPrintJobInfoCollection() 70 71 Me.LogWrite("ジョブの列挙を開始します。") 72 73 For Each job As PrintSystemJobInfo In jobs 74 If (job IsNot Nothing AndAlso job.Submitter = Environment.UserName) Then 75 76 Me.LogWrite("{0} : {1}", job.Name, job.JobStatus) 77 78 ' 拡張子 および ファイル名に含まれる文字列から、監視対象のジョブを特定する 79 If (String.IsNullOrEmpty(extention) = True OrElse job.Name.ToLower.EndsWith(extention.ToLower) = True) Then 80 Dim includesFound As Boolean = True 81 For Each match As String In includes 82 If (job.Name.Contains(match) = False) Then 83 includesFound = False 84 Exit For 85 End If 86 Next 87 88 ' ジョブ名と fileName の一致を確認 89 Dim fileNameFound As Boolean = job.Name.Trim.Equals(fileName.Trim) 90 91 ' ジョブ名と fileName が完全に一致するか、ジョブ名に includes で指定した文字列が全て含まれていればOK 92 jobFound = (includesFound Or fileNameFound) 93 94 Else 95 jobFound = False 96 End If 97 If (jobFound = True) Then 98 targetJob = job 99 Me.LogWrite("印刷対象のジョブ「{0}」が見つかりました。ステータス:{1}", job.Name, job.JobStatus) 100 Exit For 101 End If 102 End If 103 Next 104 Me.LogWrite("ジョブの列挙が終了しました。") 105 106 End If 107 108 If (jobFound = True) Then 109 targetJob.Refresh() 110 Dim nowMessage As String = String.Format("印刷対象のジョブ「{0}」を監視しています。ステータス:{1}", targetJob.Name, targetJob.JobStatus) 111 If OldMessage <> nowMessage Then 112 Me.LogWrite("印刷対象のジョブ「{0}」を監視しています。ステータス:{1}", targetJob.Name, targetJob.JobStatus) 113 OldMessage = nowMessage 114 End If 115 116 If (targetJob.JobStatus And PrintJobStatus.Completed) = PrintJobStatus.Completed Then 117 ' 紙に印字された。 118 isComprete = True 'この後deletedが発行されると考えている 119 ElseIf (targetJob.JobStatus And PrintJobStatus.Deleted) = PrintJobStatus.Deleted Then 120 ' ジョブを削除 121 printing = True 122 Me.LogWrite("プリンタ:{0} で {1} の印刷が開始されました。JobStatus:{2}", printerName, targetJob.Name, targetJob.JobStatus) 123 Return isComprete 124 ElseIf ((targetJob.JobStatus And PrintJobStatus.Error) = PrintJobStatus.Error) Then 125 Throw New ApplicationException("印刷中にエラーが発生しました。") 126 ElseIf ((targetJob.JobStatus And PrintJobStatus.Spooling) = PrintJobStatus.Spooling) Then 127 spooling = True 128 ElseIf (targetJob.JobStatus = PrintJobStatus.None AndAlso spooling = True) Then 129 ' 一度 Spooling 状態となってから None になったジョブは、 130 ' 「スプール済みでプリンタの都合で待たされている」と判断できるため 印刷開始とみなす。 131 printing = True 132 Me.LogWrite("プリンタ:{0} で {1} の印刷が開始されました。JobStatus:{2}", printerName, targetJob.Name, targetJob.JobStatus) 133 Return True 134 End If 135 End If 136 Loop 137 End Using 138 Catch ex As Exception 139 140 Me.LogWrite(ex) 141 142 Throw 143 End Try 144 Throw New NoNullAllowedException("戻り値の処理抜け") 145 End Function 146 147 ''' <summary> 148 ''' 指定したプリンタのキューを取得します。 149 ''' </summary> 150 ''' <param name="printerName">プリンタ名</param> 151 ''' <returns>指定したプリンタのキューを表す <see cref="System.Printing.PrintQueue" /> 。</returns> 152 ''' <remarks></remarks> 153 Private Function GetPrintQueue(ByVal printerName As String) As PrintQueue 154 Dim server As New LocalPrintServer() 155 Return New PrintQueue(server, printerName, 2) 156 End Function 157 158 Private Sub LogWrite(Str As Object) 159 Console.WriteLine(Str) 160 End Sub 161 Private Sub LogWrite(Str As String) 162 Console.WriteLine(Str) 163 End Sub 164 Private Sub LogWrite(format As String, ParamArray arg() As Object) 165 Console.WriteLine(format, arg) 166 End Sub

###補足情報(言語/FW/ツール等のバージョンなど)
言語 vb.net
FW .NET Framework 4.0
ツール VisualStudio 2010

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問