概要
PDFのセキュリティ設定の内容をVBA関数から取得します。
Acrobat OLE を使わずに Qpdf を使用します。
▽ Acrobat XI のセキュリティ設定の画面
▽ Dos画面でのQpdf の実行例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
>I:¥Tools¥Run¥Qpdf-6.0.0¥bin¥qpdf.exe --show-encryption in3.pdf --password=in3u R = 4 P = -300 User password = in3u extract for accessibility: allowed extract for any purpose: allowed print low resolution: allowed print high resolution: allowed modify document assembly: allowed modify forms: not allowed modify annotations: not allowed modify other: not allowed modify anything: not allowed stream encryption method: AESv2 string encryption method: AESv2 file encryption method: AESv2 > |
▽Acrobat での文書のプロパティ画面
Qpdf とは
フリーソフト Qpdf を知らない人は先にコチラを御覧ください。
使用上の注意
当関数はQPDFの旧バージョンでの使用を想定しています。新バージョンのQPDFで追加された新オプションを使用すると、エラー扱いになるので、その部分は各自で手修正してご利用下さい。
形式
1 2 3 4 5 |
Public Sub qpdfGetEncryption( _ ByVal qpdfPara_InPdfPath As String, _ ByVal qpdfPara_InPdfPassword As String, _ ByRef strMsg As String, _ ByRef strErr As String) |
引数
- 第1引数:qpdfPara_InPdfPath As String (In)
入力のPDFファイルのフルパス - 第2引数:qpdfPara_InPdfPassword As String (In)
入力のPDFファイルのユーザーパスワード。無ければ""。 - 第3引数:strMsg As String (Out)
コマンドライン上で表示された内容 - 第4引数:strErr As String (Out)
エラーメッセージ: エラー無しは ""
戻り値
無し。
関数 / サンプル
事前設定
- コチラを参考にQpdf のダウンロードとインストールを行う。
- Qpdf.exe のフルパスをCON_QPDF_PATHにセット。
- gDebugMode = True のデバッグモードをFalseにセット。
サンプル
in2.pdf からセキュリティ情報を抜き出し strMsg に取得します。Qpdf.exe に「 --show-encryption 」オプションを使います。
Download:cLine-qpdfGetEncryption.xls
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 |
Option Explicit Declare Function WaitForSingleObject Lib "kernel32" _ (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long Declare Function CloseHandle Lib "kernel32" _ (ByVal hObject As Long) As Long Declare Function GetExitCodeProcess Lib "kernel32" _ (ByVal hProcess As Long, lpExitCode As Long) As Long Declare Function OpenProcess Lib "kernel32" _ (ByVal dwDesiredAccess As Long, _ ByVal bInheritHandle As Long, _ ByVal dwProcessID As Long) As Long Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) Const SYNCHRONIZE = 1048576 Const PROCESS_QUERY_INFORMATION = &H400 'Qpdf-6.00 qpdf.exe Const CON_QPDF_PATH = "I:¥Tools¥Run¥Qpdf-6.0.0¥bin¥qpdf.exe" ' Teme File No Private gFileCnt As Long ' Debug Mode [ True=On | False=Off ] Private gDebugMode As Boolean ' テスト用呼び出し Sub Main_Demo() gDebugMode = True '実運用ではFalse Dim qpdfPara_InPdfPath As String Dim qpdfPara_InPdfPassword As String 'Qpdf.exe コマンドラインからの出力内容(エラーも含む) Dim strMsg As String 'プログラム内の実行エラーでのメッセージ Dim strErr As String If gDebugMode Then Debug.Print "Start:" & Now ' Dim j As Long ' For j = 0 To **** '入力PDFのフルパス qpdfPara_InPdfPath = Application.ActiveWorkbook.Path & _ "¥" & "in2.pdf" '入力PDFの(文書を開く時の)ユーザーパスワード qpdfPara_InPdfPassword = "" '関数の呼び出し strMsg = "" strErr = "" Call qpdfGetEncryption( _ qpdfPara_InPdfPath, _ qpdfPara_InPdfPassword, strMsg, strErr) '関数の結果を確認 If strErr <> "" Then If strMsg = "" Then 'プログラム内の実行エラーのみ MsgBox strErr, vbCritical, "実行エラー(1)" Else 'Qpdf.exe 起動時のエラーメッセージも含む MsgBox strErr & vbCrLf & vbCrLf & _ strMsg, vbCritical, "実行エラー(2)" End If Exit Sub ElseIf InStr(strMsg, "extract for accessibility:") > 0 Then MsgBox qpdfPara_InPdfPath & vbCrLf & vbCrLf & _ "セキュリティ情報を取得しました。" & vbCrLf & vbCrLf & _ strMsg, vbInformation, "お知らせ(1)" '■ココでstrMsgから文字列検索でセキュリティ情報を取得する ElseIf InStr(strMsg, "File is not encrypted") > 0 Then MsgBox qpdfPara_InPdfPath & vbCrLf & vbCrLf & _ "このファイルにセキュリティは設定されてません。", _ vbInformation, "お知らせ(2)" Exit Sub ElseIf strMsg = "" Then MsgBox "プログラムで何かしらの問題が発生しました。" & _ vbCrLf & vbCrLf & "プログラムを調査してください。", _ vbCritical, "実行エラー(3)" Exit Sub End If ' Next j If gDebugMode Then Debug.Print "End :" & Now End Sub '************************************************** ' ' Get any encryption parameters from the PDF file. ' ' 機能 : qpdf.exeを使ってセキュリティ設定を取得します。 ' Create : 2016/06/28 ' Update : 2016/06/28 ' Vertion : 1.0.0 ' ' 第1引数:qpdfPara_InPdfPath As String (In) ' 入力のPDFファイルのフルパス ' 第2引数:qpdfPara_InPdfPassword As String (In) ' 入力のPDFファイルのユーザーパスワード。無ければ""。 ' 第3引数:strMsg As String (Out) ' コマンドラインで表示された内容 ' 第4引数:strErr As String (Out) ' エラーメッセージ: エラー無しは "" ' 戻り値 : 無し ' ' 備考 : strErr<>""の時はエラー扱いとする。 ' URL : http://pdf-file.nnn2.com/?p=870 ' その他 : 著作権等は主張しません。 ' 上記URLにコメントを頂けると嬉しいです。 ' '************************************************** Public Sub qpdfGetEncryption( _ ByVal qpdfPara_InPdfPath As String, _ ByVal qpdfPara_InPdfPassword As String, _ ByRef strMsg As String, _ ByRef strErr As String) On Error GoTo Err_qpdfGetEncryption: Dim strTempFilePath As String Dim strCmd As String Dim objFileSystem As Object '初期化 Set objFileSystem = CreateObject("Scripting.FileSystemObject") strErr = "" 'エラーチェック If objFileSystem.FileExists(qpdfPara_InPdfPath) = False Then strErr = qpdfPara_InPdfPath & vbCrLf & _ "このファイルは存在しません" Exit Sub End If If objFileSystem.FileExists(CON_QPDF_PATH) = False Then strErr = CON_QPDF_PATH & vbCrLf & _ "このファイルは存在しません" Exit Sub End If 'コマンドラインの編集 strCmd = CON_QPDF_PATH & " --show-encryption " If qpdfPara_InPdfPassword <> "" Then strCmd = strCmd & "--password=" & _ qpdfPara_InPdfPassword & " " End If '一時ファイル gFileCnt = gFileCnt + 1 strTempFilePath = Application.ActiveWorkbook.Path & _ "¥" & Format(Now(), "yyyymmdd-hhmmss-") & gFileCnt & ".txt" '注意:ファイルパスの前後にダブルクォーテーションを入れる strCmd = strCmd & _ """" & qpdfPara_InPdfPath & _ """ > """ & strTempFilePath & """ 2>&1" 'コマンドラインの実行 strCmd = "cmd /c " & strCmd Call RunCommandLine(strCmd, strErr) If gDebugMode Then Debug.Print strCmd On Error GoTo Skip: '標準出力のテキストを読み込む Dim strInput As String Dim lFileNo As Long lFileNo = FreeFile Open strTempFilePath For Input As #lFileNo Do Until EOF(lFileNo) Line Input #lFileNo, strInput If strMsg = "" Then strMsg = Trim(strInput) Else strMsg = strMsg & vbCrLf & Trim(strInput) End If Loop Close #lFileNo '一時ファイルの削除 If strErr = "" Then Kill strTempFilePath Skip: Set objFileSystem = Nothing Exit Sub Err_qpdfGetEncryption: strErr = "(qpdfGetEncryption) Runtime Error :" & _ Err.Number & vbCrLf & Err.Description End Sub ' shell 関数の終了を待つ Sub RunCommandLine(ByVal strCmd As String, _ ByRef strErr As String) On Error GoTo Err_RunCommandLine: Dim hProcess As Long Dim lpdwExitCode As Long Dim dwProcessID As Long Dim retVal As Long Dim lCnt As Long Const CON_SLEEP = 20 Const CON_LOOP_CNT = 250 lCnt = 0 dwProcessID = Shell(strCmd, vbHide) hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, _ True, dwProcessID) Do Sleep CON_SLEEP DoEvents retVal = GetExitCodeProcess(hProcess, lpdwExitCode) lCnt = lCnt + 1 If lCnt > CON_LOOP_CNT Then If gDebugMode Then Debug.Print vbCrLf & strCmd strErr = "Shell Error : Time Orver " & _ CON_SLEEP * CON_LOOP_CNT & "ms" Exit Sub End If 'shell関数で実行したアプリが終了するまでループ Loop While lpdwExitCode <> 0 Exit Sub Err_RunCommandLine: strErr = "(RunCommandLine) Runtime Error :" & _ Err.Number & vbCrLf & Err.Description End Sub |
結果
▽PDFにセキュリティ情報が設定されている時。
▽PDFにセキュリティ情報が設定されてない時。
▽ユーザーパスワードが間違っている時。
一段目はプラグラム内からのエラーメッセージ。
二段目は Qpdf.exe からのエラーメッセージ。
結果の詳細
関数の引数のstrMsg にコマンドラインの内容が入っています。それを文字列分割(Split)や検索(Instr)で該当する情報を取得できます。以下がその内容の例です。
- R = 4
意味不明。 - P = -300
意味不明。 - User password = in3u
ユーザーパスワードです。無ければ「User password = 」と表示されます。コマンドの入力時に必要なので表示されても意味が無いです。 - extract for accessibility: allowed
アクセシビリティを抽出 : 許可します。 - extract for any purpose: allowed
いかなる目的のために抽出 : 許可します。
「テキスト、画像、およびその他の内容のコピーを有効にする」 - print low resolution: allowed
低解像度の印刷 : 許可します。 - print high resolution: allowed
高解像度の印刷 : 許可します。 - modify document assembly: allowed
ドキュメントのアセンブリを変更 : 許可します。 - modify forms: not allowed
フォームを変更 : 許可しません。 - modify annotations: not allowed
注釈を変更 : 許可しません。 - modify other: not allowed
その他の変更 : 許可しません。 - modify anything: not allowed
何かを変更 : 許可しません。(コレ何やねん!? - stream encryption method: AESv2
ストリームの暗号方式 : AESv2 - string encryption method: AESv2
文字列の暗号化方式 : AESv2 - file encryption method: AESv2
ファイルの暗号化方法 : AESv2
備考
- コマンドラインの実行結果が正常かの判定が少し面倒です。strMsg に文字列「extract for accessibility:」が含まれているかで正常終了かの判断としました。
- strMsg 内での文字列「File is not encrypted」は Qpdf.exe が出したエラーメッセージです。セキュリティ情報が設定されてないPDFファイルを読み込むと出します。エラー扱いにはしません。
- Xpsf でもセキュリティ情報は取得できますが、こちらの方が詳細に取れます。
PDFのセキュリティ
- Xpdf :PDFのセキュリティ情報を取得するVBA関数
- Qpdf :PDFにセキュリティを設定するVBA関数
- Qpdf :PDFにパスワードとセキュリティ設定をコピーするVBA関数
- Qpdf :PDFのパスワードとセキュリティ設定を解除するVBA関数
- PDFのパスワードは32文字まで
- Acrobat / PDFの暗号化とセキュリティの設定方法について(Acrobat X)
- Acrobat / PDF 文書にパスワードを設定する方法 (Acrobat XI/DC)
- Acrobat / パスワードによる PDF の保護
< Qpdf へ戻る >