Page 1 of 1
Run Another Program
Posted: Thu Mar 12, 2009 8:05 am
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
Re: Run Another Program
Posted: Thu Mar 12, 2009 9:03 am
by Enrico Maria Giordano
Try:
Code: Select all
SHELLEXECUTE( 0, 0, cPdf, 0, 0, 1 )
EMG
Re: Run Another Program
Posted: Thu Mar 12, 2009 9:52 am
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
Re: Run Another Program
Posted: Thu Mar 12, 2009 10:07 am
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
Re: Run Another Program
Posted: Fri Mar 13, 2009 5:01 pm
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
Re: Run Another Program
Posted: Sat Mar 14, 2009 12:06 am
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
Re: Run Another Program
Posted: Sat Mar 14, 2009 12:29 am
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
Re: Run Another Program
Posted: Sat Mar 14, 2009 3:04 am
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
Re: Run Another Program
Posted: Sat Mar 14, 2009 6:29 pm
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
Re: Run Another Program
Posted: Sat Mar 14, 2009 11:50 pm
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
Re: Run Another Program
Posted: Sun Mar 15, 2009 12:24 am
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
Regards
Uwe
Re: Run Another Program
Posted: Sun Mar 15, 2009 4:20 pm
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
Re: Run Another Program
Posted: Sun Mar 15, 2009 11:09 pm
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