Xpdf:PDFのセキュリティ情報を取得するVBA関数

TOP > Xpdf ツール > サンプル


Baby Metal-21

概要

PDFの文書のプロパティにあるセキュリティ情報を取得します。

  1. 文書プロパティのセキュリティ設定の有り無し
  2. 「印刷」を許可しない、する
  3. 「テキストや画像の抽出」を許可しない、する
  4. 「内容の変更」を許可しない、する
  5. 「テキスト注釈の追加・変更と対話式フォームフィールドを埋め込む」 許可しない、する
  6. 「新しい対話式フォームフィールドを作成と変更」 許可しない、する

Xpdf の pdfindo.exe を使って情報を取得します。

Xpdf : PDFのセキュリティ情報を取得するVBA関数

Xpdf

Xpdf について初めて知った方は先にコチラを御覧ください。

機能

  1. PDFの文書のプロパティ情報をXpdf の pdfindo.exe を「-rawdates 」オプションで取得します。
  2. 結果は標準出力としてテキストに出力します。
  3. そのテキストからPDFのセキュリティに関する部分を抽出します。

形式

001 Public Sub xpdfGetPdfSecurity( _ 002 ByVal strPdfFilePath As String, _ 003 ByRef strOut() As String, _ 004 ByRef strErr As String)


 Highlight:プログラミング言語のソースコードを構文で色分け (GUI編)
 

戻り値

無し


VBAサンプル

  • 事前にXpdf をコチラを参考にダウンロードしてください。
  • そして CON_PDFINFO_PATH に pdfinfo.exe のフルパスを設定します。

DownloadcLine-xpdfGetPdfSecurity.xls

001 Option Explicit 002 003 Declare Function WaitForSingleObject Lib "kernel32" _ 004 (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long 005 Declare Function CloseHandle Lib "kernel32" _ 006 (ByVal hObject As Long) As Long 007 Declare Function GetExitCodeProcess Lib "kernel32" _ 008 (ByVal hProcess As Long, lpExitCode As Long) As Long 009 Declare Function OpenProcess Lib "kernel32" _ 010 (ByVal dwDesiredAccess As Long, _ 011 ByVal bInheritHandle As Long, _ 012 ByVal dwProcessID As Long) As Long 013 Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) 014 015 Const SYNCHRONIZE = 1048576 016 Const PROCESS_QUERY_INFORMATION = &H400 017 018 'xpdf-3.04 pdfinfo.exe 019 Const CON_PDFINFO_PATH = _ 020 "D:¥Tools¥xpdfbin-win-3.04¥bin32¥pdfinfo.exe" 021 022 ' テスト用呼び出し 023 Sub Main_Test() 024 Dim strOut(10) As String 025 Dim strPdfFilePath As String 026 Dim strErr As String 027 028 strPdfFilePath = Application.ActiveWorkbook.Path & _ 029 "¥" & "TEST-3.pdf" 030 031 Call xpdfGetPdfSecurity(strPdfFilePath, strOut, strErr) 032 033 If strErr <> "" Then 034 MsgBox strErr, vbCritical 035 Exit Sub 036 End If 037 If strOut(0) = "" Then 038 MsgBox "取得出来ませんでした" 039 Exit Sub 040 End If 041 042 Dim i As Long 043 For i = 0 To UBound(strOut) 044 Debug.Print "strOut(" & i & ")=[" & strOut(i) & "]" 045 Next i 046 End Sub 047 048 '************************************************** 049 ' 050 ' Get Security information for PDF file 051 ' 052 ' 機能 : pdfinfo.exe のメタ情報から 053 ' PDF文書のセキュリティ情報を取得する。 054 ' 055 ' Create : 2016/06/20 056 ' Update : 2017/09/14 057 ' Vertion : 1.0.4 058 ' 059 ' 引数1 : strPdfFilePath As String (IN) 060 ' PDFファイルのフルパス 061 ' 引数2 : strOut() As String (OUT) 062 ' メタデータの「Encrypted:」の内容 063 ' 引数3 : strErr As String (OUT) 064 ' エラーメッセージ 065 ' 066 ' 戻り値 : 無し 067 ' 068 ' 備考 : strErr<>""の時はエラー扱いとする。 069 ' strOut(0)=""の時はエラー扱いとする。 070 ' 071 ' URL : https://pdf-file.nnn2.com/?p=859 072 ' 073 ' その他 : 著作権等は主張しません。 074 ' 上記URLにコメントを頂けると嬉しいです。 075 ' 076 '************************************************** 077 078 ' 出力例:サンプル 079 ' strOut(0)="yes" セキュリティ設定有り 080 ' strOut(1)="print:no" 「印刷」 許可しない 081 ' strOut(2)="copy:no" 「テキストや画像の抽出」許可しない 082 ' strOut(3)="change:no" 「内容の変更」 許可しない 083 ' strOut(4)="addNotes:no" 084 ' 「テキスト注釈の追加・変更と対話式フォームフィールドを埋め込む」 許可しない 085 ' 「change:noならば、新しい対話式フォームフィールドを作成と変更」 許可しない 086 087 Public Sub xpdfGetPdfSecurity( _ 088 ByVal strPdfFilePath As String, _ 089 ByRef strOut() As String, _ 090 ByRef strErr As String) 091 On Error GoTo Err_xpdfGetPdfSecurity: 092 093 Dim strXpdfPath As String 094 Dim strOutFilePath As String 095 Dim strCmd As String 096 Dim strInput As String 097 Dim strWk 098 Dim i As Long 099 Dim lFileNo As Long 100 101 '初期化 102 For i = 0 To UBound(strOut) 103 strOut(i) = vbNullString 104 Next i 105 106 'エラーチェック 107 If Dir(strPdfFilePath) = "" Then 108 strErr = strPdfFilePath & vbCrLf & _ 109 "このファイルは存在しません" 110 Exit Sub 111 End If 112 113 strXpdfPath = CON_PDFINFO_PATH 114 With CreateObject("Scripting.FileSystemObject") 115 If .FileExists(strXpdfPath) = False Then 116 strErr = strXpdfPath & vbCrLf & _ 117 "このファイルは存在しません" 118 Exit Sub 119 End If 120 End With 121 122 strOutFilePath = Application.ActiveWorkbook.Path & _ 123 "¥" & Format(Now(), "yyyymmdd-hhmmss") & ".txt" 124 125 'オプションは -meta -rawdates -box どれでもOK。 126 '標準出力をリダイレクトに変更する。 127 '注意:strXpdfPathの前後に”を入れると動かない。 128 strCmd = "cmd /c " & strXpdfPath & " -rawdates """ & _ 129 strPdfFilePath & """ > """ & strOutFilePath & """" 130 131 'コマンドラインの実行 132 Call RunCommandLine(strCmd, strErr) 133 If strErr <> "" Then Exit Sub 134 135 '標準出力のテキストを読み込む 136 lFileNo = FreeFile 137 Open strOutFilePath For Input As #lFileNo 138 Do Until EOF(lFileNo) 139 Line Input #lFileNo, strInput 140 If Left$(strInput, 10) = "Encrypted:" Then 141 strWk = Split(Mid(strInput, 17), " ") 142 For i = 0 To UBound(strWk) 143 strWk(i) = Replace(strWk(i), "(", "") 144 strWk(i) = Replace(strWk(i), ")", "") 145 strOut(i) = strWk(i) 146 Next i 147 Exit Do 148 End If 149 Loop 150 Close #lFileNo 151 152 Kill strOutFilePath 153 strErr = "" 154 Exit Sub 155 Err_xpdfGetPdfSecurity: 156 strErr = "xpdfGetPdfSecurity:" & Err.Number & vbCrLf & _ 157 Err.Description 158 End Sub 159 160 ' shell関数の終了を待つ 161 162 Sub RunCommandLine(ByVal strCmd As String, _ 163 ByRef strErr As String) 164 On Error GoTo Err_RunCommandLine: 165 166 Dim hProcess As Long 167 Dim lpdwExitCode As Long 168 Dim dwProcessID As Long 169 Dim retVal As Long 170 Dim lCnt As Long 171 lCnt = 0 172 dwProcessID = Shell(strCmd, vbHide) 173 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, _ 174 True, dwProcessID) 175 Do 176 Sleep 20 177 DoEvents 178 retVal = GetExitCodeProcess(hProcess, lpdwExitCode) 179 lCnt = lCnt + 1 180 If lCnt > 250 Then 181 strErr = "Error:Time Orver 5000ms" 182 Exit Sub 183 End If 184 'shell関数で実行したアプリが終了するまでループ 185 Loop While lpdwExitCode <> 0 186 strErr = "" 187 Exit Sub 188 Err_RunCommandLine: 189 strErr = "RunCommandLine:" & Err.Number & vbCrLf & _ 190 Err.Description 191 End Sub


 Highlight:プログラミング言語のソースコードを構文で色分け (GUI編)
 

出力結果

001 strOut(0)=[yes] 002 strOut(1)=[print:no] 003 strOut(2)=[copy:no] 004 strOut(3)=[change:no] 005 strOut(4)=[addNotes:no] 006 strOut(5)=[algorithm:RC4]  ※<- Poppler を使うと出る 007 strOut(6)=[] 008 strOut(7)=[] 009 strOut(8)=[] 010 strOut(9)=[] 011 strOut(10)=[]


 Highlight:プログラミング言語のソースコードを構文で色分け (GUI編)
 

補足:

  • strOut(0) セキュリティー設定が
    • [yes] :有る
    • [no]  :無い。この時はstrOut(1)以降に値は無い。
  • strOut(1) 「印刷」は
    • [print:yes] :「許可する」 と思われます。
    • [print:no] :「許可しない」 と思われます。 
  • sstrOut(2) 「テキストや画像の抽出」は
    • [copy:yes] :「許可する」 と思われます。
    • [copy:no] :「許可しない」 と思われます。
  • strOut(3) 「内容の変更」は
    • [change:yes] :「許可する」 と思われます。
    • [change:no] :「許可しない」 と思われます。
  • strOut(4) 「テキスト注釈の追加・変更と対話式フォームフィールドを埋め込む」   「change:noならば、新しい対話式フォームフィールドを作成と変更」 に対して
    • addNotes:yes] :「許可する」 と思われます。
    • [addNotes:no] :「許可しない」 と思われます。

備考

  • 上記の出力結果の内容については全て検証はしていません。
  • Poppler の pdfinfo を使う時はCON_PDFINFO_PATHの内容を事前に変更します。
  • pdfinfo.exe のオプションは -meta -rawdates -box どれを使ってもOKです。どれも「Encrypted:」を出力します。
  • pdfinfo.exe からの出力はセキュリティ・ハンドラのリビジョン2の内容です。リビジョン3又は4の内容が欲しい時はQpdf の「例:qpdf --show-encryption PS-2.pdf」を使います。以下は出力例。括弧はビット位置(勘。 001 R = 3 002 P = -3392 003 User password = 004 extract for accessibility: allowed :(?)アクセシビリティを抽出 005 extract for any purpose: not allowed :(5) 任意の目的での抽出 006 print low resolution: not allowed :(3) 低解像度の印刷 007 print high resolution: not allowed :(12) 高解像度の印刷 008 modify document assembly: not allowed :(?) 文書アセンブリ? 009 modify forms: not allowed :(7) フォームを変更 010 modify annotations: not allowed :(6)注釈を変更 011 modify other: not allowed :(?) その他の変更? 012 modify anything: not allowed :(?) 何かを変更?
  • pdfinfo.exe のパス中に空白文字が入らないようにして下さい。入るようでしたら入らないフォルダに移動してご使用ください。理由:この様な場合はパスをダブルクオーテーションでくくればイイのですが、コマンドラインの場合はこの位置でのダブルクオーテーションは有効に働きません。ご注意ください。
  • Poppler を使うと処理時間では4倍も掛かる結果が出ています。参考までに。

動作環境

  • Windows 10 64bit Pro
  • Office 2007 Excel  32bit

< Xpdf へ戻る >

「Xpdf:PDFのセキュリティ情報を取得するVBA関数」への2件のフィードバック

  1. 正確な処理時間を測定していなかったですが、「vbHide」の指定、「Sleep」時間の調整で速くなったように思います。
    ありがとうございます!

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA



SAMURAI Plugin

コメントをする時は出来れば以下もお願いします。

  • OS名 バージョン
  • Acrobat バージョン
  • ツール(Excel等) バージョン
コメントにサンプルコードを入れる時はコードを全て全角文字列にしてください。コチラで半角に戻します。それでもエラーが回避できない時はコメント下さい。個別に対処します。



お仕事で当サイトを見ている方へ
考え込んだら、ご質問下さい。
一緒に解決策を考えましょう。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください