locked
getting Adobe reader info RRS feed

  • Question

  • How to get pdf document file path that is running upon AcroRD32.exe(Adobe 10) process,
    as win7 opens 2 processes of AcroRD32.exe for all pdf documents so im unable to know
    how many pdf documents are running and i want to get the paths of pdf documents that
    are running.

    Thanks & Regards.

    Friday, August 29, 2014 5:27 AM

Answers

  • Adobe on my system displays the file it has open in its titlebar. So its windows text can be accessed to provide that information along with the other text in that window.

    This code I found at the link pasted into the top of the code window with the exception of the code I added to get the path to the file name. Unfortunately I have to set the first part of the path to C:\Users\myname\Desktop because the searcher will receive access denied to the recycle bin and my appdata folder and crash.

    Also the searcher will return all file paths for that .PDF file. So if you have multiple instances of the same .PDF file on your system then it would return all those paths if it didn't crash out from an access denied error.

    I do have code that for a file path and filename can get the process that has that file locked. I can post that code also if you'd like it. Then you could add that to this code and you will know which .PDF file of the same name is actually in use if you have more than one of the same name in different locations.

    There is code in this forum somewhere that someone wrote which can do a directory search and bypass protected directories without crashing. I doubt your .PDFs are in protected directories. But I don't have that code either.

    Option Strict On
    
    Imports System.Runtime.InteropServices
    Imports System.Text
    Imports System.IO
    
    Public Class Form1
    
        ' Code from link http://www.dreamincode.net/forums/topic/207233-get-a-list-of-active-windows-their-process-names/
        ' Process is AcroRD32.exe, name to use is AcroRD32
    
        <DllImport("USER32.DLL")> _
        Private Shared Function GetShellWindow() As IntPtr
        End Function
    
        <DllImport("USER32.DLL")> _
        Private Shared Function GetWindowText(ByVal hWnd As IntPtr, ByVal lpString As StringBuilder, ByVal nMaxCount As Integer) As Integer
        End Function
    
        <DllImport("USER32.DLL")> _
        Private Shared Function GetWindowTextLength(ByVal hWnd As IntPtr) As Integer
        End Function
    
        <DllImport("user32.dll", SetLastError:=True)> _
        Private Shared Function GetWindowThreadProcessId(ByVal hWnd As IntPtr, <Out()> ByRef lpdwProcessId As UInt32) As UInt32
        End Function
    
        <DllImport("USER32.DLL")> _
        Private Shared Function IsWindowVisible(ByVal hWnd As IntPtr) As Boolean
        End Function
    
        Private Delegate Function EnumWindowsProc(ByVal hWnd As IntPtr, ByVal lParam As Integer) As Boolean
    
        <DllImport("USER32.DLL")> _
        Private Shared Function EnumWindows(ByVal enumFunc As EnumWindowsProc, ByVal lParam As Integer) As Boolean
        End Function
    
        Private hShellWindow As IntPtr = GetShellWindow()
        Private dictWindows As New Dictionary(Of IntPtr, String)
        Private currentProcessID As Integer
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Me.CenterToScreen()
        End Sub
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            RichTextBox1.Clear()
            Dim PDFFile As String = ""
            For Each P As Process In Process.GetProcessesByName("AcroRD32")
                Dim windows As IDictionary(Of IntPtr, String) = GetOpenWindowsFromPID(P.Id)
                For Each kvp As KeyValuePair(Of IntPtr, String) In windows
                    RichTextBox1.AppendText(P.ProcessName & " # " & kvp.Value & " # " & P.Id & vbCrLf)
                    PDFFile = kvp.Value.Substring(0, kvp.Value.ToUpper.IndexOf(".PDF") + 4)
                    Dim dir As New DirectoryInfo("C:\Users\John\Desktop")
                    Dim files As FileInfo() = dir.GetFiles(PDFFile, SearchOption.AllDirectories)
                    For Each Item In files
                        RichTextBox1.AppendText(Item.FullName & vbCrLf & vbCrLf)
                    Next
                Next
            Next
        End Sub
    
        Public Function GetOpenWindowsFromPID(ByVal processID As Integer) As IDictionary(Of IntPtr, String)
            dictWindows.Clear()
            currentProcessID = processID
            EnumWindows(AddressOf enumWindowsInternal, 0)
            Return dictWindows
        End Function
    
        Private Function enumWindowsInternal(ByVal hWnd As IntPtr, ByVal lParam As Integer) As Boolean
            If (hWnd <> hShellWindow) Then
                Dim windowPid As UInt32
                If Not IsWindowVisible(hWnd) Then
                    Return True
                End If
                Dim length As Integer = GetWindowTextLength(hWnd)
                If (length = 0) Then
                    Return True
                End If
                GetWindowThreadProcessId(hWnd, windowPid)
                If (windowPid <> currentProcessID) Then
                    Return True
                End If
                Dim stringBuilder As New System.Text.StringBuilder(length)
                GetWindowText(hWnd, stringBuilder, (length + 1))
                dictWindows.Add(hWnd, stringBuilder.ToString)
            End If
            Return True
        End Function
    
    End Class


    La vida loca


    Friday, August 29, 2014 3:57 PM

All replies

  • Adobe on my system displays the file it has open in its titlebar. So its windows text can be accessed to provide that information along with the other text in that window.

    This code I found at the link pasted into the top of the code window with the exception of the code I added to get the path to the file name. Unfortunately I have to set the first part of the path to C:\Users\myname\Desktop because the searcher will receive access denied to the recycle bin and my appdata folder and crash.

    Also the searcher will return all file paths for that .PDF file. So if you have multiple instances of the same .PDF file on your system then it would return all those paths if it didn't crash out from an access denied error.

    I do have code that for a file path and filename can get the process that has that file locked. I can post that code also if you'd like it. Then you could add that to this code and you will know which .PDF file of the same name is actually in use if you have more than one of the same name in different locations.

    There is code in this forum somewhere that someone wrote which can do a directory search and bypass protected directories without crashing. I doubt your .PDFs are in protected directories. But I don't have that code either.

    Option Strict On
    
    Imports System.Runtime.InteropServices
    Imports System.Text
    Imports System.IO
    
    Public Class Form1
    
        ' Code from link http://www.dreamincode.net/forums/topic/207233-get-a-list-of-active-windows-their-process-names/
        ' Process is AcroRD32.exe, name to use is AcroRD32
    
        <DllImport("USER32.DLL")> _
        Private Shared Function GetShellWindow() As IntPtr
        End Function
    
        <DllImport("USER32.DLL")> _
        Private Shared Function GetWindowText(ByVal hWnd As IntPtr, ByVal lpString As StringBuilder, ByVal nMaxCount As Integer) As Integer
        End Function
    
        <DllImport("USER32.DLL")> _
        Private Shared Function GetWindowTextLength(ByVal hWnd As IntPtr) As Integer
        End Function
    
        <DllImport("user32.dll", SetLastError:=True)> _
        Private Shared Function GetWindowThreadProcessId(ByVal hWnd As IntPtr, <Out()> ByRef lpdwProcessId As UInt32) As UInt32
        End Function
    
        <DllImport("USER32.DLL")> _
        Private Shared Function IsWindowVisible(ByVal hWnd As IntPtr) As Boolean
        End Function
    
        Private Delegate Function EnumWindowsProc(ByVal hWnd As IntPtr, ByVal lParam As Integer) As Boolean
    
        <DllImport("USER32.DLL")> _
        Private Shared Function EnumWindows(ByVal enumFunc As EnumWindowsProc, ByVal lParam As Integer) As Boolean
        End Function
    
        Private hShellWindow As IntPtr = GetShellWindow()
        Private dictWindows As New Dictionary(Of IntPtr, String)
        Private currentProcessID As Integer
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Me.CenterToScreen()
        End Sub
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            RichTextBox1.Clear()
            Dim PDFFile As String = ""
            For Each P As Process In Process.GetProcessesByName("AcroRD32")
                Dim windows As IDictionary(Of IntPtr, String) = GetOpenWindowsFromPID(P.Id)
                For Each kvp As KeyValuePair(Of IntPtr, String) In windows
                    RichTextBox1.AppendText(P.ProcessName & " # " & kvp.Value & " # " & P.Id & vbCrLf)
                    PDFFile = kvp.Value.Substring(0, kvp.Value.ToUpper.IndexOf(".PDF") + 4)
                    Dim dir As New DirectoryInfo("C:\Users\John\Desktop")
                    Dim files As FileInfo() = dir.GetFiles(PDFFile, SearchOption.AllDirectories)
                    For Each Item In files
                        RichTextBox1.AppendText(Item.FullName & vbCrLf & vbCrLf)
                    Next
                Next
            Next
        End Sub
    
        Public Function GetOpenWindowsFromPID(ByVal processID As Integer) As IDictionary(Of IntPtr, String)
            dictWindows.Clear()
            currentProcessID = processID
            EnumWindows(AddressOf enumWindowsInternal, 0)
            Return dictWindows
        End Function
    
        Private Function enumWindowsInternal(ByVal hWnd As IntPtr, ByVal lParam As Integer) As Boolean
            If (hWnd <> hShellWindow) Then
                Dim windowPid As UInt32
                If Not IsWindowVisible(hWnd) Then
                    Return True
                End If
                Dim length As Integer = GetWindowTextLength(hWnd)
                If (length = 0) Then
                    Return True
                End If
                GetWindowThreadProcessId(hWnd, windowPid)
                If (windowPid <> currentProcessID) Then
                    Return True
                End If
                Dim stringBuilder As New System.Text.StringBuilder(length)
                GetWindowText(hWnd, stringBuilder, (length + 1))
                dictWindows.Add(hWnd, stringBuilder.ToString)
            End If
            Return True
        End Function
    
    End Class


    La vida loca


    Friday, August 29, 2014 3:57 PM
  • Hi,

     There is not a really reliable way to do this. You can try using the windows title to get the name of the pdf file and then search every drive that is accessible on the computer to try finding a file with that name but, if there is more than one copy of the pdf file on the computer then you will not know which one it has actually got opened.

     Another problem would be that if Adobe decides to change the way the window title is displayed in the window in there next version then your app will not work anymore without fixing it. For example, if you look at the way the title is in Mr. Monkeyboy`s picture and then compare it to the image below. It would not work on the one below.  8)


    If you say it can`t be done then i`ll try it

    Friday, August 29, 2014 11:47 PM
  • I don't know C++ Haroon Rafiq but so far the only app I've uncovered for getting a list of files in use by processes is in C++ from CodeProject at this link Listing Used Files.

    Perhaps I'm using the wrong terminology for the searches I am performing as this popped up as a link in a thread in a search result using Google for "pinvoke NtQuerySystemInformation".

    Anyhow I downloaded the VC8 project and loaded it in Visual Studio but some header file it's trying to use is missing.

    So I downloaded the 64 bit project demo and it works even though Windows doesn't like it cause it doesn't have a digitally signed signature the first time I ran it. The second time no issue appeared. But if you read the link the author says there's issues trying to use it above Vista. Probably due to Windows security updates in newer OS's.

    Below is an image of it running. I only have one .PDF file opened in Adobe Reader. It's highlighted. The rest I suppose are files Adobe Reader uses.

    And it doesn't really show all files in use by all processes I don't believe. As that would probably be alot more files than what it shows and it doesn't seem to show a lot of processes that are running.

    It's possible that an app in C#, which could be easily converted to VB, or in VB exist for this or something similar but I can't find it due to using inaccurate search methods.


    La vida loca


    Monday, September 1, 2014 4:39 AM
  • Thank you Mr.Monkeyboy and IronRazerz for your replies,

    I am working on the codes and guidance u guys provide and will get back to you :)

    Thanks & Regards,

    Haroon.

    Monday, September 1, 2014 9:48 AM