概要
PDFのセキュリティ設定の内容をVBA関数から取得します。
Acrobat OLE を使わずに Qpdf を使用します。
▽ Acrobat XI のセキュリティ設定の画面
▽ Dos画面でのQpdf の実行例
001 >I:¥Tools¥Run¥Qpdf-6.0.0¥bin¥qpdf.exe --show-encryption in3.pdf --password=in3u
002 R = 4
003 P = -300
004 User password = in3u
005 extract for accessibility: allowed
006 extract for any purpose: allowed
007 print low resolution: allowed
008 print high resolution: allowed
009 modify document assembly: allowed
010 modify forms: not allowed
011 modify annotations: not allowed
012 modify other: not allowed
013 modify anything: not allowed
014 stream encryption method: AESv2
015 string encryption method: AESv2
016 file encryption method: AESv2
017
018 >
Highlight:プログラミング言語のソースコードを構文で色分け (GUI編)
▽Acrobat での文書のプロパティ画面
Qpdf とは
フリーソフト Qpdf を知らない人は先にコチラを御覧ください。
使用上の注意
当関数はQPDFの旧バージョンでの使用を想定しています。新バージョンのQPDFで追加された新オプションを使用すると、エラー扱いになるので、その部分は各自で手修正してご利用下さい。
形式
001 Public Sub qpdfGetEncryption( _
002 ByVal qpdfPara_InPdfPath As String, _
003 ByVal qpdfPara_InPdfPassword As String, _
004 ByRef strMsg As String, _
005 ByRef strErr As String)
Highlight:プログラミング言語のソースコードを構文で色分け (GUI編)
引数
- 第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
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 'Qpdf-6.00 qpdf.exe
019 Const CON_QPDF_PATH = "I:¥Tools¥Run¥Qpdf-6.0.0¥bin¥qpdf.exe"
020 ' Teme File No
021 Private gFileCnt As Long
022 ' Debug Mode [ True=On | False=Off ]
023 Private gDebugMode As Boolean
024
025 ' テスト用呼び出し
026 Sub Main_Demo()
027 gDebugMode = True '実運用ではFalse
028
029 Dim qpdfPara_InPdfPath As String
030 Dim qpdfPara_InPdfPassword As String
031 'Qpdf.exe コマンドラインからの出力内容(エラーも含む)
032 Dim strMsg As String
033 'プログラム内の実行エラーでのメッセージ
034 Dim strErr As String
035
036 If gDebugMode Then Debug.Print "Start:" & Now
037 ' Dim j As Long
038 ' For j = 0 To ****
039
040 '入力PDFのフルパス
041 qpdfPara_InPdfPath = Application.ActiveWorkbook.Path & _
042 "¥" & "in2.pdf"
043 '入力PDFの(文書を開く時の)ユーザーパスワード
044 qpdfPara_InPdfPassword = ""
045
046 '関数の呼び出し
047 strMsg = ""
048 strErr = ""
049 Call qpdfGetEncryption( _
050 qpdfPara_InPdfPath, _
051 qpdfPara_InPdfPassword, strMsg, strErr)
052
053 '関数の結果を確認
054 If strErr <> "" Then
055 If strMsg = "" Then
056 'プログラム内の実行エラーのみ
057 MsgBox strErr, vbCritical, "実行エラー(1)"
058 Else
059 'Qpdf.exe 起動時のエラーメッセージも含む
060 MsgBox strErr & vbCrLf & vbCrLf & _
061 strMsg, vbCritical, "実行エラー(2)"
062 End If
063 Exit Sub
064 ElseIf InStr(strMsg, "extract for accessibility:") > 0 Then
065 MsgBox qpdfPara_InPdfPath & vbCrLf & vbCrLf & _
066 "セキュリティ情報を取得しました。" & vbCrLf & vbCrLf & _
067 strMsg, vbInformation, "お知らせ(1)"
068 '■ココでstrMsgから文字列検索でセキュリティ情報を取得する
069 ElseIf InStr(strMsg, "File is not encrypted") > 0 Then
070 MsgBox qpdfPara_InPdfPath & vbCrLf & vbCrLf & _
071 "このファイルにセキュリティは設定されてません。", _
072 vbInformation, "お知らせ(2)"
073 Exit Sub
074 ElseIf strMsg = "" Then
075 MsgBox "プログラムで何かしらの問題が発生しました。" & _
076 vbCrLf & vbCrLf & "プログラムを調査してください。", _
077 vbCritical, "実行エラー(3)"
078 Exit Sub
079 End If
080
081 ' Next j
082 If gDebugMode Then Debug.Print "End :" & Now
083
084 End Sub
085
086 '**************************************************
087 '
088 ' Get any encryption parameters from the PDF file.
089 '
090 ' 機能 : qpdf.exeを使ってセキュリティ設定を取得します。
091 ' Create : 2016/06/28
092 ' Update : 2016/06/28
093 ' Vertion : 1.0.0
094 '
095 ' 第1引数:qpdfPara_InPdfPath As String (In)
096 ' 入力のPDFファイルのフルパス
097 ' 第2引数:qpdfPara_InPdfPassword As String (In)
098 ' 入力のPDFファイルのユーザーパスワード。無ければ""。
099 ' 第3引数:strMsg As String (Out)
100 ' コマンドラインで表示された内容
101 ' 第4引数:strErr As String (Out)
102 ' エラーメッセージ: エラー無しは ""
103 ' 戻り値 : 無し
104 '
105 ' 備考 : strErr<>""の時はエラー扱いとする。
106 ' URL : https://pdf-file.nnn2.com/?p=870
107 ' その他 : 著作権等は主張しません。
108 ' 上記URLにコメントを頂けると嬉しいです。
109 '
110 '**************************************************
111
112 Public Sub qpdfGetEncryption( _
113 ByVal qpdfPara_InPdfPath As String, _
114 ByVal qpdfPara_InPdfPassword As String, _
115 ByRef strMsg As String, _
116 ByRef strErr As String)
117
118 On Error GoTo Err_qpdfGetEncryption:
119
120 Dim strTempFilePath As String
121 Dim strCmd As String
122 Dim objFileSystem As Object
123
124 '初期化
125 Set objFileSystem = CreateObject("Scripting.FileSystemObject")
126 strErr = ""
127
128 'エラーチェック
129 If objFileSystem.FileExists(qpdfPara_InPdfPath) = False Then
130 strErr = qpdfPara_InPdfPath & vbCrLf & _
131 "このファイルは存在しません"
132 Exit Sub
133 End If
134 If objFileSystem.FileExists(CON_QPDF_PATH) = False Then
135 strErr = CON_QPDF_PATH & vbCrLf & _
136 "このファイルは存在しません"
137 Exit Sub
138 End If
139
140 'コマンドラインの編集
141 strCmd = CON_QPDF_PATH & " --show-encryption "
142 If qpdfPara_InPdfPassword <> "" Then
143 strCmd = strCmd & "--password=" & _
144 qpdfPara_InPdfPassword & " "
145 End If
146
147 '一時ファイル
148 gFileCnt = gFileCnt + 1
149 strTempFilePath = Application.ActiveWorkbook.Path & _
150 "¥" & Format(Now(), "yyyymmdd-hhmmss-") & gFileCnt & ".txt"
151
152 '注意:ファイルパスの前後にダブルクォーテーションを入れる
153 strCmd = strCmd & _
154 """" & qpdfPara_InPdfPath & _
155 """ > """ & strTempFilePath & """ 2>&1"
156
157 'コマンドラインの実行
158 strCmd = "cmd /c " & strCmd
159 Call RunCommandLine(strCmd, strErr)
160 If gDebugMode Then Debug.Print strCmd
161
162 On Error GoTo Skip:
163 '標準出力のテキストを読み込む
164 Dim strInput As String
165 Dim lFileNo As Long
166 lFileNo = FreeFile
167 Open strTempFilePath For Input As #lFileNo
168 Do Until EOF(lFileNo)
169 Line Input #lFileNo, strInput
170 If strMsg = "" Then
171 strMsg = Trim(strInput)
172 Else
173 strMsg = strMsg & vbCrLf & Trim(strInput)
174 End If
175 Loop
176 Close #lFileNo
177
178 '一時ファイルの削除
179 If strErr = "" Then Kill strTempFilePath
180 Skip:
181 Set objFileSystem = Nothing
182 Exit Sub
183 Err_qpdfGetEncryption:
184 strErr = "(qpdfGetEncryption) Runtime Error :" & _
185 Err.Number & vbCrLf & Err.Description
186 End Sub
187
188 ' shell 関数の終了を待つ
189
190 Sub RunCommandLine(ByVal strCmd As String, _
191 ByRef strErr As String)
192 On Error GoTo Err_RunCommandLine:
193
194 Dim hProcess As Long
195 Dim lpdwExitCode As Long
196 Dim dwProcessID As Long
197 Dim retVal As Long
198 Dim lCnt As Long
199 Const CON_SLEEP = 20
200 Const CON_LOOP_CNT = 250
201 lCnt = 0
202 dwProcessID = Shell(strCmd, vbHide)
203 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, _
204 True, dwProcessID)
205 Do
206 Sleep CON_SLEEP
207 DoEvents
208 retVal = GetExitCodeProcess(hProcess, lpdwExitCode)
209 lCnt = lCnt + 1
210 If lCnt > CON_LOOP_CNT Then
211 If gDebugMode Then Debug.Print vbCrLf & strCmd
212 strErr = "Shell Error : Time Orver " & _
213 CON_SLEEP * CON_LOOP_CNT & "ms"
214 Exit Sub
215 End If
216 'shell関数で実行したアプリが終了するまでループ
217 Loop While lpdwExitCode <> 0
218 Exit Sub
219 Err_RunCommandLine:
220 strErr = "(RunCommandLine) Runtime Error :" & _
221 Err.Number & vbCrLf & Err.Description
222 End Sub
Highlight:プログラミング言語のソースコードを構文で色分け (GUI編)
結果
▽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ファイルを読み込むと出します。エラー扱いにはしません。
- XPDF でもセキュリティ情報は取得できますが、こちらの方が詳細に取れます。
PDFのセキュリティ
- Xpdf :PDFのセキュリティ情報を取得するVBA関数
- Qpdf :PDFにセキュリティを設定するVBA関数
- Qpdf :PDFにパスワードとセキュリティ設定をコピーするVBA関数
- Qpdf :PDFのパスワードとセキュリティ設定を解除するVBA関数
- PDFのパスワードは32文字まで
- Acrobat / PDF 文書にパスワードを設定する方法 (Acrobat XI/DC)
- Acrobat / パスワードによる PDF の保護
< Qpdf へ戻る >