使用vba处理锁定的pdf

问题描述 投票:0回答:1

我正在尝试传递受密码保护的pdf,而我正努力使两个不同的代码段可以正常工作。首先是传递此函数的路径,该函数将打开pdf并查找密码框,如果没有密码框,则返回布尔值False。

    ShellExecute Application.hwnd, "Open", pdfPath, vbNullString, "P:\", SW_SHOWNORMAL
    parentwindow = 0
    DoEvents
    parentwindow = FindWindow("#32770", "Password")

        If parentwindow = 0 Then
            OpenLockedPdf = False
            'SendMessage Application.hwnd, WM_CLOSE, 0, 0
            'ShellExecute Application.hwnd, "Close", pdfPath, vbNullString, "P:\", SW_SHOWNORMAL orig
            Exit Function
        Else:
            OpenLockedPdf = True ' delete this if the function exits here
        End If
    If parentwindow <> 0 Then
        'Find the handle of the first child window (it is a group box).
        timeCount = Now()
        Do Until Now() > timeCount + TimeValue("00:00:05")
            firstChildWindow = 0
            DoEvents
            firstChildWindow = FindWindowEx(parentwindow, ByVal 0&, "GroupBox", vbNullString)
            If firstChildWindow <> 0 Then Exit Do
        Loop

        'Find the handle of the subsequent child window (it is the text box for filling the password).
        If firstChildWindow <> 0 Then
            timeCount = Now()
            Do Until Now() > timeCount + TimeValue("00:00:05")
                secondChildFirstWindow = 0
                DoEvents
                secondChildFirstWindow = FindWindowEx(firstChildWindow, ByVal 0&, "Button", "Cancel")
                If secondChildFirstWindow <> 0 Then Exit Do
            Loop

            'The handle was found, so...
            If secondChildFirstWindow <> 0 Then

                'Press the Cancel button
                SendMessage secondChildFirstWindow, BM_CLICK, 0, ByVal 0&

            End If
        End If
    End If
End Function

第二种尝试方法:How to check security of PDF file from excel?

首先存在的问题是,当我逐步执行它时,它会打开并进行检查,但是我必须再次手动单击vba控制台以单击下一步以继续执行该过程。当我单击Excel vba控制台上的播放按钮时,它不起作用!

[当我尝试第二种方法时,它实际上没有检测到pdf上的密码保护。

[如果有人对如何使第一个或第二个代码起作用有任何建议,请告诉我。

谢谢。

vba pdf shellexecute
1个回答
0
投票

请尝试以下操作:

Option Explicit

Private Declare PtrSafe Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As LongPtr, _
                        ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, _
                        ByVal lpDirectory As String, ByVal nShowCmd As Long) As LongPtr
Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" _
             (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
Private Declare PtrSafe Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As LongPtr, _
                            ByVal hWnd2 As LongPtr, ByVal lpsz1 As String, ByVal lpsz2 As String) As LongPtr
Private Declare PtrSafe Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As LongPtr, _
                                        ByVal wMsg As Long, ByVal wParam As LongPtr, lParam As Any) As Long
Private Declare PtrSafe Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hwnd As LongPtr) As Long
Private Declare PtrSafe Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As LongPtr, _
        ByVal lpString As String, ByVal cch As Long) As Long
Private Declare PtrSafe Function GetWindow Lib "user32" (ByVal hwnd As LongPtr, ByVal wCmd As Long) As Long


Private Const BM_CLICK = &HF5
Private Const SW_SHOWMAXIMIZED = 3
Private Const GW_HWNDNEXT = 2
Private Const WM_LBUTTON_DOWN = &H201

Sub testProtection()
   Debug.Print passwordProtected("C:\your protected pdf path")
   Debug.Print passwordProtected("C:\your unprotected pdf path")
End Sub
Private Function passwordProtected(pdfPath As String) As Boolean
  Dim readerDCHwnd As LongPtr, parentwindow As LongPtr, iCount As Long
  Dim groupBoxHwnd As LongPtr, butHwnd As LongPtr
  Const pdfApp As String = "Adobe Acrobat Reader DC"
  ShellExecute Application.hwnd, "Open", pdfPath, vbNullString, "P:\", SW_SHOWMAXIMIZED

  readerDCHwnd = findWindowByPartialTitle(pdfApp)
  If readerDCHwnd = 0 Then
    Do While readerDCHwnd = 0
        iCount = iCount + 1
        Application.Wait (Now + TimeValue("0:00:1"))
        DoEvents
        readerDCHwnd = findWindowByPartialTitle(pdfApp)
        If iCount >= 5 Then MsgBox pdfApp & " handler could not be obtained in 4 seconds..." & vbCrLf & _
                        "If your pdf application is not " & pdfApp & " then update pdfApp constant.", _
                        vbInformation, "No AR handler": Exit Function
    Loop
  End If

   iCount = 0
   Do While parentwindow = 0
        iCount = iCount + 1
        Application.Wait (Now + TimeValue("0:00:1"))
        DoEvents
        parentwindow = FindWindow("#32770", "Password")
        If iCount >= 4 Then passwordProtected = False: Exit Function
   Loop
   groupBoxHwnd = FindWindowEx(parentwindow, ByVal CLngPtr(0), "GroupBox", vbNullString)
     groupBoxHwnd = FindWindowEx(parentwindow, ByVal CLngPtr(0), "GroupBox", vbNullString)
        butHwnd = FindWindowEx(groupBoxHwnd, ByVal 0&, "Button", "Cancel")
         If butHwnd <> 0 Then
            SendMessage butHwnd, WM_LBUTTON_DOWN, 0&, 0&
            SendMessage butHwnd, BM_CLICK, 0, 0&
            passwordProtected = True
         Else
            passwordProtected = False
         End If
End Function

Function findWindowByPartialTitle(ByVal sCaption As String, Optional strSecond As String) As LongPtr
  Dim lhWndP As LongPtr
    Dim sStr As String
    findWindowByPartialTitle = CLngPtr(0)
    lhWndP = FindWindow(vbNullString, vbNullString) 'PARENT WINDOW
    Do While lhWndP <> 0
        sStr = String(GetWindowTextLength(lhWndP) + 1, Chr$(0))
        GetWindowText lhWndP, sStr, Len(sStr)
        If Len(sStr) > 0 Then sStr = left$(sStr, Len(sStr) - 1)
        If InStr(1, sStr, sCaption) > 0 And _
                IIf(strSecond <> "", InStr(1, sStr, strSecond) > 0, 1 = 1) Then
            findWindowByPartialTitle = lhWndP
            Exit Do
        End If
        lhWndP = GetWindow(lhWndP, GW_HWNDNEXT)
    Loop
End Function

我为Adobe Acrobat Reader DC测试了它。如果您的默认.pdf应用程序不同,则必须相应地修改常数pdfApp。我认为,实际上,它也可以从Registry获得。首次打开pdf应用程序后,将更改其标题,同时保留打开的文档的名称。这就是为什么FindWindow API将不返回任何内容,而您必须使用findWindowByPartialTitle的原因。这里不使用第二个参数,但是可以用于更复杂的搜索...

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.