Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations biv343 on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Function FindExecutable not working under Windows 7 2

Status
Not open for further replies.

CaptainD

Programmer
Jul 13, 1999
644
US
Code:
Private Declare Function FindExecutable Lib "shell32.dll" Alias "FindExecutableA" (ByVal lpFile As String, ByVal lpDirectory As String, ByVal lpResult As String) As Long

I have a program that prints *.pdf files using DDE and must open Adobe Reader to work.

The program works on the XP machines but fails on the Windows 7's

It uses the "FindeExecutable" to locate "AcroRd32.exe"

AcroRd32.exe is located in the same location under both operating ("C:\Program Files\Adobe
Reader 9.0\AcroRd32.exe") systems but on the Windows 7 machines the Error code states that it can not find the file.

I've been searching for a fix but have not found anything of this nature. It appears to be a Windows 7 problem.

The files are viewable using ShellExecute via the Reader

Any ideas?
 
I'm using code I found a few years back that was posted at a VB site used for printing *.PDF files. Here is the code that calls it.

On Windows 7 Machines the lStatus returns 2 and sAcroPath returns nothing

Code:
Private Sub PrintPDFs(PDFArray As Variant)
'' Accepts one dimensional array PrintPDFs containing paths to .PDF files to be printed,
'' then silently prints them using DDE. Acrobat Reader does not support OLE, and silent
'' printing through the pdf.oxc has some issues in v5.1 and higher
''
'' pdf.ocx is an unsupported, non-developement tool that is subject to change in functionality.
'' Under Acrobat 5.1 and higher, a warning dialog is displayed each time printAllFit() is called.
'' If "Do not ask me again" is selected, printing from script will *fail* unless the user opens
'' acrobat reader, goes to tools>options and "Resets all warnings".
'' "Do not ask me again" is stored in:
''   HKCU\Software\Adobe\Acrobat Reader\5.0\AVAlert\cCheckbox\cEWH\iWarnScriptPrintAll
''   HKCU\Software\Adobe\Acrobat Reader\6.0\AVAlert\cCheckbox\cEWH\iWarnScriptPrintAll
''
'' This sub requires:
'' - PDFArray starts at row 0, not row 1
'' - TextBox txtAcrobatDDE
'' - declaration of API function FindExecutable
''
'' ** WILL NOT WORK FROM AN ACTIVEX DLL **
''

On Error GoTo ErrHandler
  
  Dim Error282Count As Integer  '' Count of "Can't open DDE channel" errors
  Dim AcroDDEFailed As Boolean  '' Set to true if a DDE connection cannot be established
  Dim sPDFPath As String        '' Path to a PDF file
  Dim sCmd As String            '' DDE command
  Dim lStatus As Long           '' response from ShellExecute command
  Dim n As Integer              '' for iterating
  Const Max282Errors = 6        '' Number of times we will ignore "Can't open DDE channel" errors
                                '' before accepting the fact that Acrobat is not started. We need
                                '' to test more than once, because it might just be busy loading
  Dim sAcroPath As String       '' Path to acrobat, determined by FindExecutable
  Dim bCloseAcrobat As Boolean  '' If we open acrobat, we will close it when we are done
  
  '' If acrobat is already running (and hidden), shelling it will cause it to be shown.
  '' We do not want that. So try a DDE connect, which will fail if acrobat is not running
  '' I have looked at other API means of testing this, but it may be running as a process (no window)
  '' and there does not seem to be many graceful ways of testing for this.
  Error282Count = Max282Errors      '' we only need to try once to see if it is already running.
  AcroDDEFailed = False             '' ErrHandler will set to true if Acro is not running
  txtAcrobatDDE.LinkMode = 0        '' Close any current DDE Link
  txtAcrobatDDE.LinkTopic = "acroview|control"    '' Acrobat's DDE Application|Topic
  txtAcrobatDDE.LinkMode = 2        '' Try to establish 'Manual' DDE Link. This will fail
                                    '' if Acrobat is not ready (or in this case, not running)
  
  If AcroDDEFailed = True Then
    '' We could not set our linkmode, so Acro is not running. Find it and launch it
    sPDFPath = PDFArray(0)  '' grab the first pdf path. We assume this file exists
    
[COLOR=green]    '' Use the FindExecutable API function to grab the path to our PDF handler.
    '' This should be Acrobat Reader or Acrobat, but it might be something else.
    '' When we try to DDE link to it, non-acrobat will error out. This is ok.[/color][COLOR=blue]
    sAcroPath = String(128, 32)
    lStatus = FindExecutable(sPDFPath, vbNullString, sAcroPath)
    If lStatus <= 32 Then
      MsgBox "Acrobat could not be found on this computer. Printing cancelled", vbCritical, "Problem" [/color]
[COLOR=green]
'Added to test values on Windows 7 machine[/color][COLOR=blue]
MsgBox "lStatus = " & lStatus & ", sAcroPath = " & sAcroPath

      Exit Sub

    End If [/color]

    '' Launch the PDF handler
    lStatus = Shell(sAcroPath, vbHide)
    
    If (lStatus >= 0) And (lStatus <= 32) Then
      MsgBox "An error occured launching Acrobat. Printing cancelled", vbCritical, "Problem"
      Exit Sub
    End If
    bCloseAcrobat = True  '' We will try to close Acrobat when we are done
  End If
  
  PauseFor 2  '' Lets take a break here to let Acrobat finish loading
  
  Error282Count = 0       '' This time, we will allow all acceptable tries, as
  AcroDDEFailed = False   '' Acrobat is running, but may be busy loading its modules
  txtAcrobatDDE.LinkMode = 0
  txtAcrobatDDE.LinkTopic = "acroview|control"
  txtAcrobatDDE.LinkTimeout = 2500 ' 3 minute timeout delay. Should be moer than enough
  txtAcrobatDDE.LinkMode = 2

  If AcroDDEFailed = True Then
    MsgBox "An error occured connecting to Acrobat. Printing cancelled", vbCritical, "Problem"
    Exit Sub
  End If
  
  '' Send the PDF's to the printer. In my testing, this was very immediate
  For n = 0 To UBound(PDFArray)
    '' We need to put the long filenames in quotes. Again, we assume these file exist
    sPDFPath = PDFArray(n)
    sCmd = "[FilePrintSilent(" & Chr(34) & sPDFPath & Chr(34) & ")]"
            

    txtAcrobatDDE.LinkExecute sCmd
  Next

  If bCloseAcrobat = True Then
    '' [AppExit()] causes memory errors with v6.0 and 6.1, so avoid closing these versions
    If InStr(sAcroPath, "6.0") = 0 Then
      sCmd = "[AppExit()]"
      txtAcrobatDDE.LinkExecute sCmd
    End If
  End If
  
  '' Close the DDE Connection
  txtAcrobatDDE.LinkMode = 0

Exit Sub

ErrHandler:
  If Err.Number = 282 Then '' Can't open DDE channel
    '' This error may happen because Acro is not fully loaded.
    '' Give it Max282Errors attempts before returning AcroDDEFailed = True
    Error282Count = Error282Count + 1
    If Error282Count <= Max282Errors Then
      PauseFor 3
      Resume
    Else
      AcroDDEFailed = True
      Resume Next
    End If
  End If
  
  MsgBox "Error in PrintPDFs sub of " & Me.Name & " form. Error# " & Err.Number & " " & Err.Description & "."
End Sub
 
This;

'Use the FindExecutable API function to grab the path to our PDF handler.
'This should be Acrobat Reader or Acrobat, but it might be something else.
'ref sAcroPath = String(128, 32)
If FindExecutable(Filename$, vbNullString, sAcroPath) <= 32 Then
MsgBox "Adobe Acrobat, Adobe Acrobat reader, or similar software could not be found on this computer.", vbCritical, "Cannot display pdf because ..."
Else
sAcroPath$ = Left$(sAcroPath$, InStr(sAcroPath$, Chr$(0)) - 1)
'ref ' On Error Resume Next
AdobeInstance& = Shell(sAcroPath$ & " /n /A " & q$ & "page=" & PageNumber% & q$ & " " & q$ & Filename$ & q$, vbNormalFocus)
If Err Then MsgBox "Unable to start a default pdf display program": AdobeInstance& = 0
End If
DisplayPdfReference& = AdobeInstance&

continues to run for me without problem in W7. I notice you are not stripping off the nulls as in my;

sAcroPath$ = Left$(sAcroPath$, InStr(sAcroPath$, Chr$(0)) - 1)

Have you tried that?
 
Hugh, Not sure at this stage that that is relevant? The code never get far enough to care. He's getting an lresult of less than 33

Mind you, like you, my FindExecutable test code works fine in finding the relvant executable for PDFs under Windows 7 64bit.

So something else is going on here... and it doesn't initially look to be a 32bit v 64bit issue, as the location of AcroRd32.exe indicates this is a 32bit installation of W7 (if it was 64bit I'd expect it to be in C:\Program Files (x86)\Adobe
Reader 9.0)
 
I think I found my problem.

I have a database where information on the "Map" that is in PDF format links to comments, gate codes etc. via the "Path".

My code passes the "Path" string and not necessarily the files true location. (On my work computer they are the same)

When I moved it off of my work computer to a public for others to use I did not update the path in the database.

I'm working on that now and looking to see if I need to change my tactic so this does not happen again.

Sorry to trouble you guys, thanks for looking into it.

I'll post back if I have other issues.

 
That was the problem.

Again, Thanks for looking.

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top