プロが教える店舗&オフィスのセキュリティ対策術

VB 2005で開発しています

PDFファイルを印刷し印刷が終わったらAcrobatを終了させたいのですが、
方法が分かりません。

Dim proc As New Process

proc.StartInfo.FileName = "z:\book1.pdf"
proc.StartInfo.Verb = "Print"
proc.StartInfo.CreateNoWindow = True
proc.Start()

この後、印刷が完了した後Acrobatのみ残ってしまいます。
印刷が終了した時点でAcrobatを終わらせる方法はないでしょうか。
ご教示お願いします。

A 回答 (9件)

>印刷を開始されたことを確認するため監視し続けるので、プリンターに負荷がかかり印刷が少し遅くなります。


なるほどです。。。。

>(1)PDFファイルを印刷する。
>(2)印刷が開始されたことを監視するためループし続ける(念のため1分でタイムアウト)
>(3)印刷が開始されたら、1秒おきにスプールの終了をチェック(status)する
>(4)スプールが終了したらAdobeReaderを終了させる。

手順を変えてみてはいかがでしょうか?
一つ一つのレポートのスプール終了を待たずに、次々とレポートをスプールさせてみては?

サンプルソースにて
・ジョブを生成させた端末
・ジョブを生成させたユーザ
・スプール中のドキュメント名
が取れると思います。

一番最後のレポートだけスプールが終了されたことを判定し、Acrobatを終了させるなんてどうでしょうか?
    • good
    • 0
この回答へのお礼

そうですね。
その方向で見直してみます。

今回は、大変お世話になりました。
今後ともよろしくお願いします。

お礼日時:2006/04/26 18:29

#7の続きですー


-----------------------------------------
JobInfo_2.vb
-----------------------------------------
'JOB管理/子クラス_2
Imports System.Runtime.InteropServices

Public NotInheritable Class JobInfo_2
  Inherits JobInfo

#Region "宣言部"

#Region "宣言部:定数部"

#Region "宣言部:定数部:内部"
  Private Const CCHDEVICENAME As Integer = 32
  Private Const CCHFORMNAME As Integer = 32
#End Region

#Region "宣言部:定数部:DEVMODE関連"
  Public Enum enmエントリ数
    DM_ORIENTATION = &H1        'dmOrientation
    DM_PAPERSIZE = &H2         'dmPaperSize
    DM_PAPERLENGTH = &H4        'dmPaperLength
    DM_PAPERWIDTH = &H8         'dmPaperWidth
    DM_SCALE = &H10           'dmScale
    DM_POSITION = &H20         'dmPosition
    DM_COPIES = &H100          'dmCopies
    DM_DEFAULTSOURCE = &H200      'dmDefaultSource
    DM_PRINTERQUALITY = &H400      'dmPrinterQuality
    DM_COLOR = &H800          'dmColor
    DM_DUPLEX = &H1000         'dmDuplex
    DM_YRESOLUTION = &H2000       'dmYResolution
    DM_TTOPTION = &H4000        'dmTTOption
    DM_COLLATE = &H8000&        'dmCollate
    DM_FORMNAME = &H10000        'dmFormName
    DM_LOGPIXELS = &H20000       'dmLogPixels
    DM_BITSPERPEL = &H40000       'dmBitsPerPel
    DM_PELSWIDTH = &H80000       'dmPelsWidth
    DM_PELSHEIGHT = &H100000      'dmDisplayFlags
    DM_DISPLAYFREQUENCY = &H400000   'dmDisplayFrequency
    DM_ICMMETHOD = &H2000000      'dmICMMetHod
    DM_ICMINTENT = &H4000000      'dmICMintent
    DM_MEDIANTENT = &H8000000      'dmMediaType
    DM_DITHERTYPE = &H10000000     'dmDitherType
  End Enum
  Public Enum enm用紙方向 As Short
    縦 = 1  '縦向き:DMORIENT_PORTAIT
    横 = 2  '横向き:DMORIENT_LANDSCAPE
  End Enum
  Public Enum enm用紙サイズ As Short
    DMPAPER_FANFOLD_LGL_GERMAN = 41         'German Legal Fanfold 8 1/2 x 13 in
    DMPAPER_10X14 = 16               '10×14インチシート
    DMPAPER_11X17 = 17               '11×17インチシート
    DMPAPER_9X11 = 44                '9×11インチシート
    DMPAPER_A2 = 66                 'A2 420×594mm
    DMPAPER_A3 = 8                 'A3 297×420mm
    DMPAPER_A3_EXTRA = 3              'A3 Extra 322×445mm
    DMPAPER_A3_EXTRA_TRANSVERSE = 68        'A3 Extra Transverse 322×445mm
    DMPAPER_A3_TRANSVERSE = 67           'A3 Transverse 297×420mm
    DMPAPER_A4 = 9                 'A4 210×297mm
    DMPAPER_A4_SMALL = 10              'A4 Small 210×297mm
    DMPAPER_A4_EXTRA = 53              'A4 EXTRA 9,27×12.69インチ
    DMPAPER_A4_PLUS = 60              'A4 Plus 210×330mm
    DMPAPER_A4_TRANSVERSE = 55           'A4 Transverse 210×297mm
    DMPAPER_A5 = 11                 'A5 148×120mm
    DMPAPER_A5_EXTRA = 64              'A5 Extra 174×235mm
    DMPAPER_A_PLUS = 61               'SuperA/SuperA/A4 227×356mm
    DMPAPER_B4 = 12                 'B4 250×354mm
    DMPAPER_B5 = 13                 'B5 182×257mm
    DMPAPER_B5_EXTRA = 65              'B5 Extra 201×276mm(ISO規格のB5)
    DMPAPER_B5_TRANSVERSE = 62           'B5 Transverse 182×257mm(JISの規格)
    DMPAPER_B_PLUS = 58               'SuperB/SuperB/A3 305×487mm
    DMPAPER_CSHEET = 24               'Cサイズシート
    DMPAPER_DSHEET = 25               'Dサイズシート
    DMPAPER_ENV_9 = 19               '封筒 #9 3 7/8×8 7/8
    DMPAPER_ENV_10 = 19               '封筒 #10 3 7/8×8 7/8
    DMPAPER_ENV_11 = 20               '封筒 #11 3 7/8×8 7/8
    DMPAPER_ENV_12 = 21               '封筒 #12 3 7/8×8 7/8
    DMPAPER_ENV_14 = 22               '封筒 #14 3 7/8×8 7/8
    DMPAPER_ENV_B4 = 23               '封筒 B4 250×353mm
    DMPAPER_ENV_B5 = 33               '封筒 B5 176×250mm
    DMPAPER_ENV_B6 = 34               '封筒 B6 176×125mm
    DMPAPER_ENV_C3 = 35               '封筒 C3 324×458mm
    DMPAPER_ENV_C4 = 29               '封筒 C4 229×324mm
    DMPAPER_ENV_C5 = 30               '封筒 C5 162×229mm
    DMPAPER_ENV_C6 = 28               '封筒 C6 114×162mm
    DMPAPER_ENV_C65 = 31              '封筒 C65 114×229mm
    DMPAPER_ENV_DL = 32               '封筒 DL 110×220mm
    DMPAPER_ENV_INVITE = 27             '封筒 Invite 220×220mm
    DMPAPER_ENV_ITALY = 36             '封筒 110×230mm
    DMPAPER_ENV_MONARCH = 37            '封筒 Monarch 3.875×7.5インチ
    DMPAPER_ENV_PERSONAL = 38            '6 3/4 封筒 3 5/8×6 1/2インチ
    DMPAPER_ESHEET = 26               'Eサイズシート
    DMPAPER_EXECUTIVE = 7              'エグゼキューティブ 7 1/4×10 1/2インチ
    DMPAPER_FANFOLD_LGL_GREMAN = 41         'German Legal Fanfold 8 1/2×13インチ
    DMPAPER_FANFOLD_STD_GERMAN = 40         'German Std Fanfold 8 1/2×12インチ
    DMPAPER_FANFOLD_US = 39             'US Std Fanfold 14 7/8×11インチ
    DMPAPER_FIRST = DMPAPER_LETTER         '
    DMPAPER_FOLIO = 14               'フォリオ 8 1/2×13インチ
    DMPAPER_ISO_B4 = 42               'B4(ISO) 250×353mm
    DMPAPER_JAPANESE_POSTCARD = 43         'Japanese Postcard 100×148mm
    DMPAPER_LAST = DMPAPER_FANFOLD_LGL_GERMAN    '
    DMPAPER_LEDGER = 4               'レジャー 17×11インチ
    DMPAPER_LEGAL = 5                'リーガル 8 1/2×11インチ
    DMPAPER_LEGAL_EXTRA = 51            'リーガル Extra 9\257×15インチ
    DMPAPER_LETTER = 1               'レター 8 1/2×11インチ
    DMPAPER_LETTER_SMALL = 2            'レター Small 8 1/2×11インチ
    DMPAPER_LETTER_EXTRA = 50            'レター Extra 9\275×12インチ
    DMPAPER_LETTER_EXTRA_TRANSVERSE = 56      'レター Extra Transverse 9\275×12インチ
    DMPAPER_LETTER_PLUS = 59            'レター Plus 8.5×12.69インチ
    DMPAPER_LETTER_TRANSVERSE = 54         'レター Transverse 8\275×11インチ
    DMPAPER_NOTE = 18                'ノート 8 1/2×11インチ
    DMPAPER_QUARTO = 15               'クォート 215×275mm
    DMPAPER_STATEMENT = 6              'ステートメント 5 1/2×8 1/2インチ
    DMPAPER_TABLOID = 3               'タブロイド 11×17インチ
    DMAPPER_USER = 256               'ユーザー定義
  End Enum
  Public Enum enmデフォルトのピン番号 As Short
    DMBIN_ONLYONE = 1    '上段のトレー
    DMBIN_LOWER = 2     '下段のトレー
    DMBIN_MIDDLE = 3    '中央のトレー
    DMBIN_MANUAL = 4    '手差し
    DMBIN_ENVELOPE = 5   '封筒フィーダ
    DMBIN_ENVMANUAL = 6   '封筒手差し
    DMBIN_AUTO = 7     '現在の設定値(デフォルト
    DMBIN_TRACTOR = 8    'トラクターフィーダ
    DMBIN_SMALLFMT = 9   '小さいペーパーフィーダ
    DMBIN_LARGEFMT = 10   '大きいペーパーフィーダ
    DMBIN_CASSETTE = 11   '容量の大きいフィーダ
    DMBIN_FORMSOURCE = 15  '
    DMBIN_USER = 256    'ユーザー定義
  End Enum
  Public Enum enm印刷品質 As Short
    簡易印刷 = -1  'DMRES_DRAFT
    低品位 = -2   'DMRES_LOW
    中品位 = -3   'DMRES_MEDIUM
    高品位 = -4   'DMRES_HIGH
  End Enum
  Public Enum enm色モード As Short
    モノクロ = 1  'DMCOLOR_MONOCHROME
    色付き = 2   'DMCOLOR_COLOR
  End Enum
  Public Enum enm両面印刷 As Short
    片面印刷 = 1      'DMDUP_SIMPLEX
    両面印刷_垂直裏返 = 2  'DMDUP_VERTICAL
    両面印刷_水平裏返 = 3  'DMDUP_HORIZONTAL
  End Enum
  Public Enum enmTTFont印刷方法 As Short
    ビットマップとして出力 = 1       'DMTT_BITMAP
    ソフトフォントとしてダウンロード = 2  'DMTT_DOWNLOAD
    デバイスフォントに置き換え = 3     'DMTT_SUBDEV
  End Enum
  Public Enum enmページ揃え As Short
    しない = 0 'DMCOLLATE_FALSE
    する = 1  'DMCOLLATE_TRUE
  End Enum
  Public Enum enmディスプレイモード
    モノクロ = &H1     'DM_GRAYSCALE
    インターレース = &H2  'DM_INTERLACED
  End Enum
#End Region

#End Region

#Region "宣言部:API"

#Region "宣言部:API:構造体"

#Region "宣言部:API:構造体:DEVMODE"
  'http://www.winapi-database.com/Struct/DEVMODE.html
  <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
    Public Structure DEVMODE
    <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=CCHDEVICENAME)> Dim dmDeviceName As String
    '<MarshalAs(UnmanagedType.ByValArray, SizeConst:=CCHDEVICENAME)> Dim dmDeviceName() As Byte
    Dim dmSpecVersion As Short
    Dim dmDriverVersion As Short
    Dim dmSize As Short
    Dim dmDriverExtra As Short
    Dim dmFields As enmエントリ数
    Dim dmOrientation As enm用紙方向
    Dim dmPaperSize As enm用紙サイズ
    Dim dmPaperLength As Short
    Dim dmPaperWidth As Short
    Dim dmScale As Short
    Dim dmCopies As Short
    Dim dmDefaultSource As enmデフォルトのピン番号
    Dim dmPrintQuality As enm印刷品質
    Dim dmColor As enm色モード
    Dim dmDuplex As enm両面印刷
    Dim dmYResolution As Short
    Dim dmTTOption As enmTTFont印刷方法
    Dim dmCollate As enmページ揃え
    <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=CCHFORMNAME)> Dim dmFormName As String
    '<MarshalAs(UnmanagedType.ByValArray, SizeConst:=CCHFORMNAME)> Dim dmFormName() As Byte
    Dim dmUnusedPadding As Short
    Dim dmBitsPerPel As Short
    Dim dmPelsWidth As Integer
    Dim dmPelsHeight As Integer
    Dim dmDisplayFlags As enmディスプレイモード
    Dim dmDisplayFrequency As Integer
  End Structure
#End Region

#Region "宣言部:API:構造体:ACL"
  'http://www.winapi-database.com/Struct/ACL.html
  Public Structure ACL
    Dim AclRevision As Byte
    Dim Sbz1 As Byte
    Dim AclSize As Short
    Dim AceCount As Short
    Dim Sbz2 As Short
  End Structure
#End Region

#Region "宣言部:API:構造体:SECURITY_DESCRIPTOR"
  'http://www.winapi-database.com/Struct/SECURITY_D …
  Public Structure SECURITY_DESCRIPTOR
    Dim Revision As Byte
    Dim Sbz1 As Byte
    Dim Control As Integer
    Dim Owner As Integer
    Dim Group As Integer
    Dim Sacl As ACL
    Dim Dacl As ACL
  End Structure
#End Region

#Region "宣言部:API:構造体:JOB_INFO_2"
  'http://www.winapi-database.com/Struct/JOB_INFO_2 …
  Public Structure JOB_INFO_2
    Dim JobId As Integer
    Dim pPrinterName As IntPtr
    Dim pMachineName As IntPtr
    Dim pUserName As IntPtr
    Dim pDocument As IntPtr
    Dim pNotifyName As IntPtr
    Dim pDatatype As IntPtr
    Dim pPrintProcessor As IntPtr
    Dim pParameters As IntPtr
    Dim pDriverName As IntPtr
    Dim pDevMode As IntPtr       'DEVMODE構造体
    Dim pStatus As IntPtr
    Dim pSecurityDescriptor As IntPtr  'SECURITY_DESCRIPTOR構造体
    Dim Status As enmジョブステータス
    Dim Priority As enmプライオリティ
    Dim Position As Integer
    Dim StartTime As Integer
    Dim UntilTime As Integer
    Dim TotalPages As Integer
    Dim Size As Integer
    Dim Submitted As SYSTEMTIME
    Dim Time As Integer
    Dim PagesPrinted As Integer
#Region "内部変換プロパティ"
    Public ReadOnly Property プリンタ名() As String
      Get
        Return Marshal.PtrToStringAuto(pPrinterName)
      End Get
    End Property
    Public ReadOnly Property マシン名() As String
      Get
        Return Marshal.PtrToStringAuto(pMachineName)
      End Get
    End Property
    Public ReadOnly Property ユーザ名() As String
      Get
        Return Marshal.PtrToStringAuto(pUserName)
      End Get
    End Property
    Public ReadOnly Property 印刷ジョブ名() As String
      Get
        Return Marshal.PtrToStringAuto(pDocument)
      End Get
    End Property
    Public ReadOnly Property 通知すべきユーザー名() As String
      Get
        Return Marshal.PtrToStringAuto(pNotifyName)
      End Get
    End Property
    Public ReadOnly Property データのタイプ() As String
      Get
        Return Marshal.PtrToStringAuto(pDatatype)
      End Get
    End Property
    Public ReadOnly Property プリンタプロセッサ名() As String
      Get
        Return Marshal.PtrToStringAuto(pPrintProcessor)
      End Get
    End Property
    Public ReadOnly Property プリントプロセッサのパラメータ() As String
      Get
        Return Marshal.PtrToStringAuto(pParameters)
      End Get
    End Property
    Public ReadOnly Property プリンタドライバ名() As String
      Get
        Return Marshal.PtrToStringAuto(pDriverName)
      End Get
    End Property
    Public ReadOnly Property 構造体_DEVMODE() As DEVMODE
      Get
        Return Marshal.PtrToStructure(pDevMode, GetType(DEVMODE))
      End Get
    End Property
    Public ReadOnly Property 印刷ジョブのステータス() As String
      Get
        Return Marshal.PtrToStringAuto(pStatus)
      End Get
    End Property
    Public ReadOnly Property 構造体_SECURITY_DESCRIPTOR() As SECURITY_DESCRIPTOR
      Get
        Return Marshal.PtrToStructure(pSecurityDescriptor, GetType(SECURITY_DESCRIPTOR))
      End Get
    End Property
#End Region
  End Structure
#End Region

#End Region

#End Region

#End Region

#Region "メソッド"
  Protected Overrides Sub 継承設定()
    With 継承項目
      .レベル = enmレベル.LEVEL_2
      .ジョブ = New JOB_INFO_2()
    End With
  End Sub
#End Region

End Class


-----------------------------------------
JobInfo3.vb
-----------------------------------------
'JOB管理/子クラス_3
Public NotInheritable Class JobInfo_3
  Inherits JobInfo

#Region "宣言部"

#Region "宣言部:API"

#Region "宣言部:API:構造体"

#Region "宣言部:API:構造体:JOBINFO"
  'http://www.ない
  Public Structure JOB_INFO_3
    Dim JobId As Integer
    Dim NextJobId As Integer
    Dim Reserved As Integer
  End Structure
#End Region

#End Region

#End Region

#End Region

#Region "メソッド"
  Protected Overrides Sub 継承設定()
    With 継承項目
      .レベル = enmレベル.LEVEL_3
      .ジョブ = New JOB_INFO_3()
    End With
  End Sub
#End Region

End Class
    • good
    • 0
この回答へのお礼

1050YENさん、ありがとうございます。

ソースを自分のものにしようと、研究していたため返事か遅れ申し訳ありませんでした。

>先にも述べたように、「もはやわたしのわがまま」でソースを書いておりますので、
>JOB_INFO_1だけではなくJOB_INFO_2/JOB_INFO_3を利用したものも追加しております。

とんでもないです。
親クラスを持った継承クラスとか、そこらの本を読むより、実践で身につきました。
兎に角、今回は勉強になりました。

思い通りのプログラムが完成したのですが、
印刷を開始されたことを確認するため監視し続けるので、プリンターに負荷がかかり印刷が少し遅くなります。
これは、私の使い方が不味いのか、いたしかたない物なのか、どうでしょうか。

(1)PDFファイルを印刷する。
(2)印刷が開始されたことを監視するためループし続ける(念のため1分でタイムアウト)
(3)印刷が開始されたら、1秒おきにスプールの終了をチェック(status)する
(4)スプールが終了したらAdobeReaderを終了させる。

(2)で監視し続けるため時間がかかる様です。

お礼日時:2006/04/26 09:55

#6の続きですー


-----------------------------------------
JobInfo_1.vb
-----------------------------------------
'JOB管理/子クラス_1
Imports System.Runtime.InteropServices

Public NotInheritable Class JobInfo_1
  Inherits JobInfo

#Region "宣言部"

#Region "宣言部:API"

#Region "宣言部:API:JOB_INFO_1"
  'http://www.winapi-database.com/Struct/JOB_INFO_1 …
  Public Structure JOB_INFO_1
    Dim JobId As Integer
    Dim pPrinterName As IntPtr
    Dim pMachineName As IntPtr
    Dim pUserName As IntPtr
    Dim pDocument As IntPtr
    Dim pDatatype As IntPtr
    Dim pStatus As IntPtr
    Dim Status As enmジョブステータス
    Dim Priority As enmプライオリティ
    Dim Position As Integer
    Dim TotalPages As Integer
    Dim PagesPrinted As Integer
    Dim Submitted As SYSTEMTIME
#Region "内部変換プロパティ"
    Public ReadOnly Property プリンタ名() As String
      Get
        Return Marshal.PtrToStringAuto(pPrinterName)
      End Get
    End Property
    Public ReadOnly Property マシン名() As String
      Get
        Return Marshal.PtrToStringAuto(pMachineName)
      End Get
    End Property
    Public ReadOnly Property ユーザ名() As String
      Get
        Return Marshal.PtrToStringAuto(pUserName)
      End Get
    End Property
    Public ReadOnly Property 印刷ジョブ名() As String
      Get
        Return Marshal.PtrToStringAuto(pDocument)
      End Get
    End Property
    Public ReadOnly Property データのタイプ() As String
      Get
        Return Marshal.PtrToStringAuto(pDatatype)
      End Get
    End Property
    Public ReadOnly Property 印刷ジョブのステータス() As String
      Get
        Return Marshal.PtrToStringAuto(pStatus)
      End Get
    End Property
#End Region
  End Structure
#End Region

#End Region

#End Region

#Region "メソッド"
  Protected Overrides Sub 継承設定()
    With 継承項目
      .レベル = enmレベル.LEVEL_1
      .ジョブ = New JOB_INFO_1()
    End With
  End Sub
#End Region

End Class
    • good
    • 0

お心遣い、感謝いたしすル。

m(_ _)m
やっと帰れました。

私がここまでやる理由は、正直をいうと、自分の発言をライブラリとして、客先からでも参照のできるようにしたいというのが理由です。
だから、質問者の求める機能より、もはや自分のわがままでやっております^^;;

それが参考になれば幸いです。



>Return l_詳細が抜けていた
確かに。。。お恥ずかしい限りです。。。

>時間が9時間ずれる
この現象は知りませんでした。
調べたら、変換をしないといけないようですね。
http://www.atmark.gr.jp/~s2000/r/rtl/InternetSho …
下に書いてあるサンプルは、臨時対応で固定で9時間を足してます^^;;;;;


先にも述べたように、「もはやわたしのわがまま」でソースを書いておりますので、
JOB_INFO_1だけではなくJOB_INFO_2/JOB_INFO_3を利用したものも追加しております。

さらに、今後メソッドを追加していく予定なので、親クラスを持った継承クラスとして、作成しなおしました。
各JOB_INFO_ほにゃららのメンバにENUMステートメントを利用し、デバッグ時に値が見易くなっております。
それに伴い「メソッド:変換_情報()」は廃止いたしました。


以上が私のわがままでの発展内容です(ーー;)

このスレは、私が立てるべきだったかなw



ここからは私の勝手な発言なので、消されるのを覚悟で書きます。
あなたの質問の仕方/発言と、対応方法から
「プログラム経験がまだ浅い」けど「非常にセンスがある方」
とお見受けいたしました。

私の今回のクラスで何かお気づきの点がありましたら、遠慮なく文句なり何なり言っていただけると助かります。
今後ともよろしくお願いいたします。

この度はありがとうございました。。。
さらに待たせてすいませんでした。。。。。。



-----------------------------------------
テスト実行モジュール
-----------------------------------------
Module mdlMain
  Sub Main()
    Dim l_job1 As New JobInfo_1()
    Dim l_job2 As New JobInfo_2()
    Dim l_job3 As New JobInfo_3()
    Dim l_Ary As ArrayList
    Dim l_jobInf1 As JobInfo_1.JOB_INFO_1
    Dim l_jobInf2 As JobInfo_2.JOB_INFO_2
    Dim l_jobInf3 As JobInfo_3.JOB_INFO_3


    'JOB_INFO_1で取得
    l_Ary = l_job1.一覧
    For Each l_jobInf1 In l_Ary
      With l_jobInf1
        Console.WriteLine(.Status & vbTab & .印刷ジョブ名)
      End With
    Next

    'JOB_INFO_2で取得
    l_Ary = l_job2.一覧
    For Each l_jobInf2 In l_Ary
      With l_jobInf2
        Console.WriteLine(.Status & vbTab & .印刷ジョブ名)
      End With
    Next

    'JOB_INFO_3で取得
    l_Ary = l_job3.一覧
    For Each l_jobInf3 In l_Ary
      With l_jobInf3
        Console.WriteLine("デバッグするようなものは無い")
      End With
    Next
  End Sub
End Module

-----------------------------------------
JobInfo.vb
-----------------------------------------
'JOB管理/親クラス
Imports System.Runtime.InteropServices

Public MustInherit Class JobInfo

#Region "宣言部"

#Region "宣言部:定数"
  Private Const DEF_初期値_バッファ取得パーフォマンス As Integer = 100
#End Region

#Region "宣言部:API"

#Region "宣言部:API:構造体"

#Region "宣言部:API:構造体:SYSTEMTIME"
  'http://www.winapi-database.com/Struct/SYSTEMTIME …
  Public Structure SYSTEMTIME
    Dim wYear As Short
    Dim wMonth As Short
    Dim wDayOfWeek As Short
    Dim wDay As Short
    Dim wHour As Short
    Dim wMinute As Short
    Dim wSecond As Short
    Dim wMilliseconds As Short
    Public ReadOnly Property 日時() As DateTime
      Get
        Dim l_datRet As DateTime
        Dim l_dbl時差 As Double = 9
        l_datRet = New DateTime(wYear, wMonth, wDay, wHour, wMinute, wSecond, wMilliseconds)
        l_datRet.AddHours(l_dbl時差)
        Return l_datRet.AddHours(l_dbl時差)
      End Get
    End Property
  End Structure
#End Region

#End Region

#Region "宣言部:API:Declare"
  <DllImport("winspool.drv", CharSet:=CharSet.Auto, SetLastError:=True)> _
  Private Shared Function OpenPrinter( _
    ByVal pPrinterName As String, _
    ByRef hPrinter As IntPtr, _
    ByVal pDefault As IntPtr _
  ) As Boolean
  End Function

  <DllImport("winspool.drv", CharSet:=CharSet.Auto, SetLastError:=True)> _
  Private Shared Function ClosePrinter( _
    ByVal hPrinter As IntPtr _
  ) As Boolean
  End Function

  <DllImport("winspool.drv", CharSet:=CharSet.Auto, SetLastError:=True)> _
  Private Shared Function EnumJobs( _
    ByVal hPrinter As IntPtr, _
    ByVal FirstJob As Integer, _
    ByVal NoJobs As Integer, _
    ByVal Level As Integer, _
    ByRef pJob As Byte, _
    ByVal cdBuf As Integer, _
    ByRef pcbNeeded As Integer, _
    ByRef pcReturned As Integer _
  ) As Integer
  End Function
#End Region

#End Region

#Region "宣言部:変数"

#Region "宣言部:変数:内部"
  Private _プリンタ名 As String
  Private _プリンタハンドル As IntPtr
#End Region

#End Region

#Region "宣言部:返し:定数部"

#Region "宣言部:返し:定数部:JOB_INFO"
  Public Enum enmジョブステータス
    JS_PAUSED = &H1   '中断
    JS_ERROR = &H2   'エラー
    JS_DELETING = &H4  '削除中
    JS_SPOOLING = &H8  'スプール中
    JS_PRINTING = &H10 '印刷中
    JS_OFFLINE = &H20  'オフライン
    JS_PAPER_OUT = &H40 '用紙切れ
    JS_PRINTED = &H80  '印刷済み
  End Enum
  Public Enum enmプライオリティ
    NO_PRIORITY = 0   '未設定
    MIN_PRIORITY = 1  '最低
    MAX_PRIORITY = 99  '最大
  End Enum
#End Region

#End Region

#Region "宣言部:継承"
  '必要なメソッド
  Protected MustOverride Sub 継承設定()

  Protected Enum enmレベル
    LEVEL_1 = 1
    LEVEL_2 = 2
    LEVEL_3 = 3
  End Enum

  Protected Structure 継承設定必須
    Dim レベル As enmレベル
    Dim ジョブ As Object
  End Structure
  Protected 継承項目 As 継承設定必須
#End Region

#End Region

#Region "イベント部"

#Region "イベント部:New"
  Public Sub New()

    '取得するプリンタ
    _プリンタ名 = (New Drawing.Printing.PrintDocument()).PrinterSettings().PrinterName

    'オブジェクトハンドルを取得
    Call OpenPrinter(_プリンタ名, _プリンタハンドル, New IntPtr())

    '継承物の初期設定を行う
    Call 継承設定()
  End Sub
#End Region

#Region "イベント部:Finalize"
  Protected Overrides Sub Finalize()
    MyBase.Finalize()

    If Not _プリンタハンドル.Equals((New IntPtr()).Zero) Then
      'オブジェクトハンドルを開放
      Call ClosePrinter(_プリンタハンドル)
    End If
  End Sub
#End Region

#End Region

#Region "プロパティ部"

#Region "メソッド部:一覧"
  Public ReadOnly Property 一覧() As ArrayList
    Get
      Return 取得(継承項目.レベル, 継承項目.ジョブ)
    End Get
  End Property
#End Region

#End Region

#Region "メソッド部"

#Region "メソッド部:取得"
  Private Function 取得(ByVal p_レベル As enmレベル, ByRef p_ジョブ As Object) As ArrayList
    Dim l_aryRet As New ArrayList()

    Dim l_intFirstJobIndex As Integer = 0
    Dim l_intNeeded As Integer
    Dim l_intReturned As Integer
    Dim l_bytJobBuff() As Byte

    Dim i As Integer

    Dim l_intSize_JobInfo As Integer = Marshal.SizeOf(p_ジョブ.GetType)
    Dim l_ptrJobInfo As IntPtr = Marshal.AllocHGlobal(l_intSize_JobInfo)

    Do
      '必要なバッファサイズを求める
      Call EnumJobs( _
        _プリンタハンドル, _
        l_intFirstJobIndex, _
        DEF_初期値_バッファ取得パーフォマンス, _
        p_レベル, _
        0, _
        0, _
        l_intNeeded, _
        l_intReturned _
      )
      '取得出来なかった
      If l_intNeeded = 0 Then
        Exit Do
      End If

      '領域を確保する
      Erase l_bytJobBuff
      ReDim l_bytJobBuff(l_intNeeded - 1)

      '情報を取得する
      Call EnumJobs( _
        _プリンタハンドル, _
        l_intFirstJobIndex, _
        DEF_初期値_バッファ取得パーフォマンス, _
        p_レベル, _
        l_bytJobBuff(0), _
        l_intNeeded, _
        l_intNeeded, _
        l_intReturned _
      )

      '取得件数分のループを行う
      For i = 0 To l_intReturned - 1
        Marshal.Copy(l_bytJobBuff, i * l_intSize_JobInfo, l_ptrJobInfo, l_intSize_JobInfo)
        p_ジョブ = Marshal.PtrToStructure(l_ptrJobInfo, p_ジョブ.GetType)
        l_aryRet.Add(p_ジョブ)
      Next
      l_intFirstJobIndex += DEF_初期値_バッファ取得パーフォマンス
    Loop
    Call Marshal.FreeHGlobal(l_ptrJobInfo)

    Return l_aryRet
  End Function

#End Region

#End Region

End Class

残りは、次の発言で(大きすぎたw)
    • good
    • 0

今晩、ソースを張ります。


すいません。
なかなか帰れなくて。。。
    • good
    • 0
この回答へのお礼

1050YENさん、有難うございます。

>なかなか帰れなくて。。。
お体に気を付けて

昨日のソースで、
オーバーロード、コレクション、Enum ステートメントなど
思わぬ副産物があり、お勉強になりました。
少し賢くなりました。

お礼日時:2006/04/21 19:01

先ほどのものは、メソッド事態は正常ですが、戻り値を未設定のまま終了しておりました。


すいません。

私もJOB管理機能は必要なので、今、少し修正を加えております。
動くようになってきましたので、最新版として張りたいと思ったのですが、、、

サンプルソースが大きすぎて、会社の重いLANから送信出来ません。

すいませんが、また今晩自宅から張ります。
    • good
    • 0
この回答へのお礼

1050YENさん、有難うございます。

今、テスト中です。

現在把握しているものは、

Private Function 変換_情報(ByVal p_udtJobInfo1 As JOB_INFO_1) As 詳細 で
Return l_詳細が抜けていた

Private Function 変換_日付(ByVal p_SYSTEMTIME As SYSTEMTIME) As DateTime で
時間が9時間ずれる

たしか、もう一つどこか修正したような気が?

小さいPDFファイルの印刷は一瞬で終わってしまうので拾えないのではと思ってましたが、
問題なく拾えるようでした。

ぜひ、最新版をお願いいたします。

お礼日時:2006/04/21 10:21

昨日終電に間に合わず、今帰宅です^^;



ありましたが、まだ作成途中のクラスだったようで、正確に動くかは未確認です。
メイン部はだぶん大丈夫だとは思うのですが、、、

参考になれば嬉しいです。


Imports System.Runtime.InteropServices


#Region "スプール情報"

Public Class スプール情報

#Region "宣言部"
  Private Const DEF_初期値_バッファ取得パーフォマンス As Integer = 100

#Region "宣言部:返し"

#Region "宣言部:返し:定数部"
  Public Enum enmジョブステータス
    JS_PAUSED = &H1   '中断
    JS_ERROR = &H2   'エラー
    JS_DELETING = &H4  '削除中
    JS_SPOOLING = &H8  'スプール中
    JS_PRINTING = &H10 '印刷中
    JS_OFFLINE = &H20  'オフライン
    JS_PAPER_OUT = &H40 '用紙切れ
    JS_PRINTED = &H80  '印刷済み
  End Enum
  Public Enum enmプライオリティ
    NO_PRIORITY = 0   '未設定
    MIN_PRIORITY = 1  '最低
    MAX_PRIORITY = 99  '最大
  End Enum
#End Region

#Region "宣言部:返し:構造体"
  Public Structure 詳細
    Public ジョブID As Integer
    Public プリンタ名 As String
    Public マシン名 As String
    Public ユーザ名 As String
    Public 印刷ジョブ名 As String
    Public データのタイプ As String
    Public 印刷ジョブのステータス As String
    Public ステータス As enmジョブステータス
    Public プライオリティ As enmプライオリティ
    Public 印刷キュー内のジョブの位置 As Integer
    Public ページ数 As Integer
    Public 印刷済みページ数 As Integer
    Public ドキュメントガスプールされた日時 As DateTime
  End Structure
#End Region

#End Region

#Region "宣言部:API"
  Public Structure SYSTEMTIME
    Dim wYear As Int16
    Dim wMonth As Int16
    Dim wDayOfWeek As Int16
    Dim wDay As Int16
    Dim wHour As Int16
    Dim wMinute As Int16
    Dim wSecond As Int16
    Dim wMilliseconds As Int16
  End Structure
  Public Structure JOB_INFO_1
    Dim JobId As Integer
    Dim pPrinterName As IntPtr
    Dim pMachineName As IntPtr
    Dim pUserName As IntPtr
    Dim pDocument As IntPtr
    Dim pDatatype As IntPtr
    Dim pStatus As IntPtr
    Dim Status As Integer
    Dim Priority As Integer
    Dim Position As Integer
    Dim TotalPages As Integer
    Dim PagesPrinted As Integer
    Dim Submitted As SYSTEMTIME
  End Structure

  Private Declare Auto Function OpenPrinter Lib "winspool.drv" ( _
    ByVal pPrinterName As String, _
    ByRef hPrinter As IntPtr, _
    ByVal pDefault As IntPtr) As Boolean
  Private Declare Auto Function EnumJobs Lib "winspool.drv" ( _
    ByVal hPrinter As IntPtr, _
    ByVal FirstJob As Integer, _
    ByVal NoJobs As Integer, _
    ByVal Level As Integer, _
    ByRef pJob As Byte, _
    ByVal cdBuf As Integer, _
    ByRef pcbNeeded As Integer, _
    ByRef pcReturned As Integer _
  ) As Integer
  Private Declare Auto Function ClosePrinter Lib "winspool.drv" ( _
    ByVal hPrinter As IntPtr _
  ) As Boolean

#End Region

#Region "宣言部:内部変数"
  Private _PrintWnd As IntPtr
  Private _プリンタ名 As String
#End Region

#End Region

#Region "イベント部"

#Region "イベント部:New"
  Public Sub New()
    Me.New((New Drawing.Printing.PrintDocument()).PrinterSettings().PrinterName)
  End Sub

  Public Sub New(ByVal p_strプリンタ As String)
    '取得するプリンタ
    _プリンタ名 = p_strプリンタ

    'オブジェクトハンドルを取得
    Call OpenPrinter(p_strプリンタ, _PrintWnd, New IntPtr())
  End Sub
#End Region

#Region "イベント部:Finalize"
  Protected Overrides Sub Finalize()
    MyBase.Finalize()

    If Not _PrintWnd.Equals((New IntPtr()).Zero) Then
      'オブジェクトハンドルを開放
      Call ClosePrinter(_PrintWnd)
    End If
  End Sub
#End Region

#End Region

#Region "プロパティ部"
  Public ReadOnly Property プリンタ名() As String
    Get
      Return _プリンタ名
    End Get
  End Property

  Public ReadOnly Property スプール一覧() As ArrayList
    Get
      Return 取得_スプール()
    End Get
  End Property
#End Region

#Region "メソッド部"

#Region "メソッド部:取得_スプール"
  Private Function 取得_スプール() As ArrayList
    'JOB_INFO_1を利用する
    Const DEF_LEVEL1 As Integer = 1

    '戻り
    Dim l_aryRet As New ArrayList()

    Dim l_intFirstJobIndex As Integer = 0
    Dim l_intNeeded As Integer
    Dim l_intReturned As Integer
    Dim l_bytJobBuff() As Byte

    Dim i As Integer
    Dim l_udtJobInfo1 As JOB_INFO_1

    Dim l_intSize_JobInfo As Integer = Marshal.SizeOf(l_udtJobInfo1.GetType)
    Dim l_ptrJobInfo1 As IntPtr = Marshal.AllocHGlobal(l_intSize_JobInfo)

    Do
      '必要なバッファサイズを求める
      Call EnumJobs( _
        _PrintWnd, _
        l_intFirstJobIndex, _
        DEF_初期値_バッファ取得パーフォマンス, _
        DEF_LEVEL1, _
        0, _
        0, _
        l_intNeeded, _
        l_intReturned _
      )
      '取得出来なかった
      If l_intNeeded = 0 Then
        Exit Do
      End If

      '領域を確保する
      Erase l_bytJobBuff
      ReDim l_bytJobBuff(l_intNeeded - 1)

      '情報を取得する
      Call EnumJobs( _
        _PrintWnd, _
        l_intFirstJobIndex, _
        DEF_初期値_バッファ取得パーフォマンス, _
        DEF_LEVEL1, _
        l_bytJobBuff(0), _
        l_intNeeded, _
        l_intNeeded, _
        l_intReturned _
      )

      '取得件数分のループを行う
      For i = 0 To l_intReturned - 1
        Marshal.Copy(l_bytJobBuff, i * l_intSize_JobInfo, l_ptrJobInfo1, l_intSize_JobInfo)
        l_udtJobInfo1 = Marshal.PtrToStructure(l_ptrJobInfo1, l_udtJobInfo1.GetType)
        l_aryRet.Add(変換_情報(l_udtJobInfo1))
      Next

      l_intFirstJobIndex += DEF_初期値_バッファ取得パーフォマンス
    Loop

    '開放
    Marshal.FreeHGlobal(l_ptrJobInfo1)

    Return l_aryRet
  End Function

#Region "メソッド部:変換処理"
  Private Function 変換_情報(ByVal p_udtJobInfo1 As JOB_INFO_1) As 詳細
    Dim l_詳細 As 詳細

    With l_詳細
      .ジョブID = p_udtJobInfo1.JobId
      .プリンタ名 = Marshal.PtrToStringAuto(p_udtJobInfo1.pPrinterName)
      .マシン名 = Marshal.PtrToStringAuto(p_udtJobInfo1.pMachineName)
      .ユーザ名 = Marshal.PtrToStringAuto(p_udtJobInfo1.pUserName)
      .印刷ジョブ名 = Marshal.PtrToStringAuto(p_udtJobInfo1.pDocument)
      .データのタイプ = Marshal.PtrToStringAuto(p_udtJobInfo1.pDatatype)
      .印刷ジョブのステータス = Marshal.PtrToStringAuto(p_udtJobInfo1.pStatus)
      .ステータス = CType(p_udtJobInfo1.Status, enmジョブステータス)
      .プライオリティ = CType(p_udtJobInfo1.Priority, enmプライオリティ)
      .印刷キュー内のジョブの位置 = p_udtJobInfo1.Position
      .ページ数 = p_udtJobInfo1.TotalPages
      .印刷済みページ数 = p_udtJobInfo1.PagesPrinted
      .ドキュメントガスプールされた日時 = 変換_日付(p_udtJobInfo1.Submitted)
    End With
  End Function

  Private Function 変換_日付(ByVal p_SYSTEMTIME As SYSTEMTIME) As DateTime
    With p_SYSTEMTIME
      Return New DateTime(.wYear, .wMonth, .wDay, .wHour, .wMinute, .wSecond, .wMilliseconds)
    End With
  End Function
#End Region

#End Region

#End Region

End Class

#End Region
    • good
    • 0

>印刷が終了しないうちに


そうですかー
残念です。


こちらは、印刷がされたら困るので、プリンタを一時停止状態にして、小さなPDFにて実行をしました。
そのせいでしょうか。。。。


>EnumJobs() API を使えば何とかなるかなとか思っていますが、どんなものでしょうか。
たしかにスプール監視でいけるかも知れませんが、確証は全くありません。

今職場なのですが、確か自宅に
http://okwave.jp/kotaeru.php3?q=103563
を.NET化したクラスがあったような気がします。

見つけたら今晩張っておきますね。
    • good
    • 0
この回答へのお礼

150YENさん、有難うございます。
参考URLを拝見しました。
やりたかった事は、まさにコレです。
複数のPDFファイルを印刷したい時に印刷が終了する前に次の印刷が開始されてしまって結果として印刷されないPDFファイルが発生する。
印刷が終了したらAdobe Readerが閉じてくれれば何とかなるかなと思っていました。

>見つけたら今晩張っておきますね。
ぜひ見つけてください(笑).... m(__)m

お礼日時:2006/04/20 10:36

Module Module1


  Private Declare Auto Function FindExecutable Lib "shell32.dll" ( _
      ByVal lpFile As String, _
      ByVal lpDirectory As String, _
      ByVal lpResult As String _
  ) As Integer

  Sub Main()
    Call Test("c:\1.pdf")
  End Sub

  Sub Test(ByVal p_strPath As String)
    Const DEF_BUFF_LEN As Integer = 1024
    Dim l_strExeName As String

    '引数のファイルに関連づいたアプリケーションパスを取得
    If Not Exe取得(p_strPath, l_strExeName) Then
      MsgBox("EXEの取得失敗")
      Return
    End If

    '印刷を行う
    Call 印刷開始(p_strPath)

    'EXEを終了させる
    Call 終了処理(l_strExeName)
  End Sub

  'Exeのパスを取得する
  Private Function Exe取得(ByVal p_strPath As String, ByRef p_strExe As String) As Boolean
    Const DEF_BUFF_LEN As Integer = 1024
    Dim l_blnRet As Boolean = False
    Dim l_strExeName As String = New String(CChar(" "), DEF_BUFF_LEN)
    Dim lngInstance As Integer = FindExecutable(p_strPath, vbNullString, l_strExeName)
    If lngInstance >= 33 Then
      p_strExe = Strings.Left(l_strExeName, (InStr(l_strExeName, vbNullChar) - 1))
      l_blnRet = True
    End If
    Return l_blnRet
  End Function

  '印刷実行部
  Private Sub 印刷開始(ByVal p_strPath As String)
    Dim proc As New Process()
    Dim l_procinf As New ProcessStartInfo()

    With l_procinf
      .FileName = p_strPath
      .Verb = "Print"
      .CreateNoWindow = True
    End With
    proc.Start(l_procinf)
  End Sub


  'Exeを終了させる
  Private Sub 終了処理(ByVal p_strExe As String)
    Dim l_finfo As New IO.FileInfo(p_strExe)
    Dim l_proc As Process
    Dim localByName As Process() = Process.GetProcessesByName(IO.Path.GetFileNameWithoutExtension(p_strExe))

    For Each l_proc In localByName
      If l_proc.MainModule.FileName.Equals(p_strExe) Then
        l_proc.CloseMainWindow()
        l_proc.Dispose()
      End If
    Next
  End Sub

End Module
    • good
    • 0
この回答へのお礼

1050YENさん有難うございます

早速試してみました。

'印刷を行う
Call 印刷開始(p_strPath)

ここで印刷が終了しないうちに

'EXEを終了させる
Call 終了処理(l_strExeName)

に飛んでしまいます。
やはりスプールを監視しなければいけないのかなと思っています。

EnumJobs() API を使えば何とかなるかなとか思っていますが、どんなものでしょうか。

お礼日時:2006/04/19 11:35

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!