Run Another Program

Post Reply
Colin Haig
Posts: 310
Joined: Mon Oct 10, 2005 5:10 am

Run Another Program

Post by Colin Haig »

Hi All

I use adobe acrobat reader to display pdf files from my program - usually I set in the path of the computer
c:\Program Files\Adobe\Reader 9.0\Reader; and then from my program I use WinExec("acrord32 " + (cPdf)) and
this works fine but when the user updates to the latest Adobe Reader I need to update the path - so using some
code I got the path to acrord32.exe and save the path to a database field - I can get the reader to start but not except the
file.


This works
WinExec("c:\Program Files\Adobe\Reader 9.0\Reader\acrord32.exe " + (cPdf))
but I have tried
1 - cAdobePath := system->adobepath
Winexec(cAdobePath + (cPdf))
2 bAdobepath := {|| system->adobepath }
WinExec(eval(bAdobePath) + (cPdf))
3 bAdobePath := {|cPdf| system->adobepath + (cPdf)}
WinExec(eval(bAdobePath,cPdf))

The acrobat bat reader starts but wont open the pdf.

Any Ideas

Regards

Colin
User avatar
jicorral
Posts: 47
Joined: Thu Jul 10, 2008 7:33 am
Contact:

Re: Run Another Program

Post by jicorral »

You can search the default pdf reader in registry:

Code: Select all

...
   cAplicacion := DiValorClave(HKEY_CLASSES_ROOT, DiValorClave(HKEY_CLASSES_ROOT, ".pdf") + "\Shell\Open\Command")
   cAplicacion := strtran(cAplicacion, '"')
   cAplicacion := cFileNoPar(cAplicacion)
...
function DiValorClave(hClave, cSubclave)
local cValText := ""

    RegQueryValue(hClave, cSubClave, @cValText)
    cValText := left(cValText, len(cValText) - 1)

return cValText
 
Jorge Ignacio Corral
Enjoy it :)
Colin Haig
Posts: 310
Joined: Mon Oct 10, 2005 5:10 am

Re: Run Another Program

Post by Colin Haig »

Hi Enrico

Thanks - that worked brilliantly - I should have asked earlier could have saved
a bit of time.

Hi Jorge

I have not ried your sample code yet but I will - even though Enrico's solution
was just what I needed.

Thanks to both of you for replying.

Regards

Colin
User avatar
James Bott
Posts: 4654
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA
Contact:

Re: Run Another Program

Post by James Bott »

Colin,

Since Enrico has provided a solution already you don't need this now. But if you do this later here is another solution.

You can find the path to any program that has an associated filename extension. For instance you can find what app is associated with PDF. This function finds this in the Windows registry.

Code: Select all

#INCLUDE "FIVEWIN.CH"
#define  HKEY_CLASSES_ROOT       2147483648

// Managing Register services from FiveWin
// cExt is the file extension
FUNCTION RegEd(cExt)
   LOCAL nHandler := 0
   LOCAL cVar1, cVar2
   cExt:=if(left(cExt,1)!=".","."+cExt,cExt)
   RegOpenkey(HKEY_CLASSES_ROOT,"",@nHandler)
   RegQueryValue(nHandler,cExt,@cVar1)
   RegCloseKey(nHandler)
   RegOpenKey(HKEY_CLASSES_ROOT,cVar1,@nHandler)
   RegQueryValue(nHandler,"DefaultIcon",@cVar2)
   RegCloseKey(nHandler)
   cVar2 := SubStr(cVar2,1,LEN(cVar2)-3)
RETURN (cVar2)
This will return the filename of the Acrobat EXE in your case. Then you could find the path to the EXE this way:

cPath:= cFilePath( RegEd( "PDF") )

James
Colin Haig
Posts: 310
Joined: Mon Oct 10, 2005 5:10 am

Re: Run Another Program

Post by Colin Haig »

Hi James

Yes I had already worked out how to get the path

if RegOpenKey( HKEY_LOCAL_MACHINE,"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths", @nHandle ) == 0
RegQueryValue( nHandle, "ACRORD32.EXE", @cFilePath )
RegCloseKey( nHandle )
endif
if ! empty(cFilePath)
if MsgYesNo('Save ' + cFilePath + ' to Company Information')
oCompany:adobepath := cFilePath
oCompany:save()
oSayAdobePath:bGet := {|| oCompany:adobepath }
oSayAdobePath:Refresh()
endif
else
MsgAlert('Cannot Find Acrobat Reader File - Please Install Acrobat Reader')
endif

I was trying to get the path to work with WinExec , I tried putting the path in
a codeblock and evaluating
bAdobePath := { || oSystem:abobepath }
WinExec(eval(bAdobePath) + (cPdf))

I could get the adobe reader to start but it would not open my pdf.

I am sure there must be away to do it but I could not find it.

Cheers

Colin
User avatar
ukoenig
Posts: 3981
Joined: Wed Dec 19, 2007 6:40 pm
Location: Germany
Contact:

Re: Run Another Program

Post by ukoenig »

Hello Colin,

Winexec works fine without problems. Your call of cPdf is wrong.

cPdf := "Test.pdf"
WinExec("c:\programme\adobe\reader 8.0\reader\acrord32.exe &cpdf")
or
WinExec("c:\programme\adobe\reader 8.0\reader\acrord32.exe Test.pdf")

Regards
Uwe :lol:
Since 1995 ( the first release of FW 1.9 )
i work with FW.
If you have any questions about special functions, maybe i can help.
Colin Haig
Posts: 310
Joined: Mon Oct 10, 2005 5:10 am

Re: Run Another Program

Post by Colin Haig »

Hi Uwe

I save the path to the adobe reader into a database field so if they update their
version of adobe reader they can reset the path in the database - this saves originally
setting the system path on each machine and subsequently change the system path when they
update.

database called system contains field adobepath
cAdobePath := oSystem:adobepath
My problem is calling that path and the pdf in winexec

eg
bAdobePath := {|| cAdobePath }
WinExec(eval(bAdobePath) + (cPdf))

The adobe reader will open but not with the pdf.

Cheers

Colin
User avatar
ukoenig
Posts: 3981
Joined: Wed Dec 19, 2007 6:40 pm
Location: Germany
Contact:

Re: Run Another Program

Post by ukoenig »

Hello Colin,

I created a test, looks the same like Your test working with a database-field.
Running it, I noticed as well, that WINEXEC calling the Acrobat-reader, but didn't show the pdf-document.
I found a hidden Char at the end of the Arcrobat-path-string comes from the registry.
My path-string was 49 Chars, Len(pathstring) from registry was 50 Chars.
That is the reason, the reader starts without Pdf-file.

My test :

Code: Select all

#include "FiveWin.ch" 
#include "xbrowse.ch" 
#define  HKEY_LOCAL_MACHINE      2147483650

REQUEST DBFCDX 

FUNCTION Main() 
local oDlg, oBrw , oCol, nFor, oBtn1, oBtn2, oBnd3, oGet, oSay 

c_dir   := GetModuleFilename(GetInstance(),"BACKGRD.EXE" + CHR(0), 255)
c_path  := left ( c_dir, rat( "\", c_dir) -1 )

DBSELECTAREA(1)
USE CUSTOMER NEW SHARED VIA "DBFCDX"
SET ORDER TO TAG FIRST
GO TOP

cPDF := SPACE(10)
cPDFPATH := SPACE(150)

DEFINE FONT oFont NAME "TAHOMA" SIZE 0,-12

DEFINE DIALOG oDlg RESOURCE "XBROWSE" FONT oFont

oBrw := TXBrowse():new( oDlg ) 
oBrw:SetRDD()
oBrw:nMarqueeStyle       := MARQSTYLE_HIGHLROW
oBrw:nColDividerStyle    := LINESTYLE_BLACK
oBrw:nRowDividerStyle    := LINESTYLE_BLACK
oBrw:nFreeze             := 1

oCol := oBrw:AddCol()
oCol:bStrData  := { || (1)->FIRST}
oCol:cHeader   := "First"
oCol:oDataFont := oFont

oCol := oBrw:AddCol()
oCol:bStrData := { || (1)->LAST}
oCol:cHeader  := "Last"

oCol := oBrw:AddCol()
oCol:bStrData := { || (1)->PDFPATH}
oCol:cHeader  := "PdfPath"

oBrw:bChange   := { || cPDFPATH := ALLTRIM( (1)->PDFPATH ), oSay:Refresh() }

oBrw:CreateFromResource( 110 )

// PDF-File
// -------------
REDEFINE GET oGet  VAR cPDF   ID 120  OF oDlg UPDATE

// PDF-Path
// -------------
REDEFINE GET oSAY  VAR cPDFPATH   ID 130  OF oDlg UPDATE

REDEFINE BUTTONBMP oBtn1  ID 30 OF oDlg ;
ACTION ( SAVE_PDF(), cPDFPATH := ALLTRIM( (1)->PDFPATH ), oSAY:Refresh() ) ;
BITMAP "Save" PROMPT "Save" TEXTRIGHT

// 49 Chars
// "e:\programme\adobe\reader 8.0\reader\acrord32.exe"
// 50 Chars from the registry ( 1 Hidden )
// ----------------------------------------------------------------------
REDEFINE BUTTONBMP oBtn2  ID 40 OF oDlg ;
ACTION (  oGet:Refresh(), ;
                 cRUNPDF := cPDFPATH + " " + ALLTRIM(cPDF) + ".PDF", ; 
                 WinExec( '&cRUNPDF' ) ) ;
BITMAP "Run" PROMPT "Run PDF" TEXTRIGHT

REDEFINE BUTTONBMP oBtn3  ID 50 OF oDlg ;
ACTION ( oDlg:End() ) ;
BITMAP "Quit" PROMPT "Exit" TEXTRIGHT

ACTIVATE DIALOG oDlg CENTER  

CLOSE DATABASE

RETURN NIL 

// ---------------------

FUNCTION SAVE_PDF()
local nHandle

IF RegOpenKey( HKEY_LOCAL_MACHINE, ;
   "SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths", @nHandle ) == 0
    RegQueryValue( nHandle, "ACRORD32.EXE", @cPdfPath )
   RegCloseKey( nHandle )
ENDIF
IF ! empty(cPdfPath)
   IF MsgYesNo('Save ' + cPdfPath + ' to Company Information')
      // Msgalert( LEN( cPdfPath ) )  shows 50 Chars !!!
      // My path : "e:\programme\adobe\reader 8.0\reader\acrord32.exe" = 49 Chars
      DBSELECTAREA(1)
      DBRLOCK()
      // 1 Hidden Char found !!!
      // ----------------------------
      (1)->PDFPATH := SUBSTR(cPDFPATH, 1, LEN(cPDFPATH) -1)
      DBUNLOCK()
      ENDIF
ELSE
      MsgAlert('Cannot Find Acrobat Reader File - Please Install Acrobat Reader')
ENDIF

RETURN( NIL )

*I was trying to get the path to work with WinExec , I tried putting the path in 
*a codeblock and evaluating 
*bAdobePath := { || oSystem:abobepath }
*WinExec(eval(bAdobePath) + (cPdf))
*I save the path to the adobe reader into a database field so if they update their
*version of adobe reader they can reset the path in the database - this saves originally
*setting the system path on each machine and subsequently change the system path when they
*update.
*database called system contains field adobepath
*cAdobePath := oSystem:adobepath
*My problem is calling that path and the pdf in winexec
*bAdobePath := {|| cAdobePath }
*WinExec(eval(bAdobePath) + (cPdf))
*The adobe reader will open but not with the pdf.

Regards
Uwe :lol:
Since 1995 ( the first release of FW 1.9 )
i work with FW.
If you have any questions about special functions, maybe i can help.
Colin Haig
Posts: 310
Joined: Mon Oct 10, 2005 5:10 am

Re: Run Another Program

Post by Colin Haig »

Hi Uwe

Thanks - it now works after removing the extra character.

Previously I used a database ( config.dbf ) to save the path for the data eg "e:\data\" - depending
what mapped drive letter was used but this required a database tool to be installed or called from another
machine - so I decided to use a text file to enter the path and by using memoread("net.txt") set the path
but I found that memoread(net.txt) returns 2 extra characters onto the end of "c:\dev\master\"
I tested this with both xHarbour and Clipper 5.2e and both had the same result.

I find it strange that these functions return extra characters on the end and alltrim does not remove them either.

Anyway thanks for making the effort.


Cheers

Colin
User avatar
ukoenig
Posts: 3981
Joined: Wed Dec 19, 2007 6:40 pm
Location: Germany
Contact:

Re: Run Another Program

Post by ukoenig »

Hello Colin,

I think, It is the structure of the registry, to define the end of line.
My complete needed information : "e:\programme\adobe\reader 8.0\reader\acrord32.exe"
msgalert( ASC( SUBSTR(cPDFPATH, 50, 1) ) ) Returns 0

// 49 Chars
Image

Regards
Uwe :lol:
Since 1995 ( the first release of FW 1.9 )
i work with FW.
If you have any questions about special functions, maybe i can help.
User avatar
James Bott
Posts: 4654
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA
Contact:

Re: Run Another Program

Post by James Bott »

Collin,

It would my suggestion not to store the path in a database. If you do, you end up with the problem you have when the user's machine is later changed to a different path.

I would read the path from the registry each time the application is run. This way you will never have a path problem that the user had to deal with--or worse, that you have to deal with.

Regards,
James
Colin Haig
Posts: 310
Joined: Mon Oct 10, 2005 5:10 am

Re: Run Another Program

Post by Colin Haig »

Hi James

I have an option that clears the path setting and then updates the new one
but the user or someone has to do this - so like you say checking everytime the
program starts may be a better idea.

Regards

Colin
Post Reply