if IsClassRegistered("Word.Application") declare long ShellExecute in "shell32.dll" ; long hwnd, string lpszOp, ; string lpszFile, string lpszParams, ; string lpszDir, long nShowCmd ShellExecute(0,'Open','winword.exe',0,0,1) endif function IsClassRegistered lparameters tcClass #DEFINE HKEY_CLASSES_ROOT -2147483648 #DEFINE ERROR_SUCCESS 0 && OK DECLARE Integer RegOpenKey IN Win32API ; Integer nHKey, String @cSubKey, Integer @nResult DECLARE Integer RegCloseKey IN Win32API ; Integer nHKey local lnKey lnKey = 0 llRetVal = ( RegOpenKey(HKEY_CLASSES_ROOT, tcClass, @lnKey) = ERROR_SUCCESS ) if llRetVal RegCloseKey(lnKey) endif return llRetValShellExecute has an advantage in that you can even run it if the exe is renamed (but .doc associated). ie:
StrToFile('','c:\temp\myDoc.doc') ShellExecute(0,'Open','c:\temp\myDoc.doc',0,0,1)Cetin
>DO DECL > >lcwordsparm = "" >*--Get the path to winword.exe from the registry >lcwordpath=readregistrykey("Winword.Exe") >IF TYPE('lcwordpath')<>"C" .or. EMPTY(lcwordpath) > RETURN >ENDIF > >lcwordsapp = lcwordpath+"WINWORD.EXE" >lcwordsdir = LEFT(lcwordsapp,RAT("\",lcwordsapp)-1) >lcwordsprg = "WINWORD.EXE" >lcwordsdef = SYS(2003) >SET DEFAULT TO LEFT(lcwordsapp,RAT("\",lcwordsapp)-1) > >*--Does the app exist? >IF ADIR(laDummy, lcwordsapp)=1 > *--Can we run it? > llivansok = RunAndWait(lcwordsprg, lcwordsparm, lcwordsdir) > CLEAR > WAIT WINDOW "Finished Running Word. >ENDIF >RETURN > >*---------------------------------------------------------------------------------- >PROCEDURE RunAndWait (lcApp, lcCmdLine, lcdir) >#DEFINE INFINITE 0xFFFFFFFF >LOCAL lcStartupInfo, lcProcInfo, hProcess, ; > lnPrio, lnIBelieve1 >lnIBelieve1 = 1 && Don't remember what that was >lnPrio = 32 && Priority of Process=Normal >lcStartupInfo = CHR(68) + REPLI(CHR(0), 67) >lcProcInfo = REPLI(CHR(0), 16) >IF CreateProcess(0, m.lcApp+" "+m.lcCmdLine+CHR(0), 0,0,; > m.lnIBelieve1, m.lnPrio,; > 0, 0, @lcStartupInfo, @lcProcInfo) <> 0 > * process and thread handles returned in ProcInfo structure > hProcess = buf2dword(SUBSTR(lcProcInfo, 1,4)) > hThread = buf2dword(SUBSTR(lcProcInfo, 5,4)) > * waiting until the termination > = WaitForSingleObject(hProcess, INFINITE) > = CloseHandle(hThread) > = CloseHandle(hProcess) >ELSE > RETURN .F. >ENDIF > >*---------------------------------------------------------------------------------- >PROCEDURE DECL >DECLARE INTEGER CreateProcess IN kernel32; > INTEGER lpAppName, STRING lpCmdLine, INTEGER lpProcAttr,; > INTEGER lpThrAttr, INTEGER bInhHandles, INTEGER dwCrFlags,; > INTEGER lpEnvir, INTEGER lpCurDir, ; > STRING @lpStInfo, STRING @lpProcInfo >DECLARE INTEGER GetLastError IN kernel32 >DECLARE INTEGER CloseHandle IN kernel32 INTEGER hObject >DECLARE INTEGER WaitForSingleObject IN kernel32; > INTEGER hHandle, INTEGER dwMilliseconds >RETURN > >*---------------------------------------------------------------------------------- >FUNCTION buf2dword(lcBuffer) >RETURN ASC(SUBSTR(lcBuffer, 1,1)) + ; > ASC(SUBSTR(lcBuffer, 2,1)) * 256 +; > ASC(SUBSTR(lcBuffer, 3,1)) * 65536 +; > ASC(SUBSTR(lcBuffer, 4,1)) * 16777216 >RETURN > > >*---------------------------------------------------------------------------------- >FUNCTION readregistrykey >LPARAMETERS qprogram > >#DEFINE HKEY_CLASSES_ROOT -2147483648 >#DEFINE HKEY_CURRENT_USER -2147483647 >#DEFINE HKEY_LOCAL_MACHINE -2147483646 >#DEFINE HKEY_USERS -2147483645 >#DEFINE REG_SZ 1 && String >#DEFINE REG_BINARY 3 && Binary data >#DEFINE REG_DWORD 4 && 32bits int >#DEFINE ERROR_SUCCESS 0 && OK > >LOCAL nKey, cSubKey, cValue, cValueRead >nKey = HKEY_LOCAL_MACHINE >cSubKey = "Software\Microsoft\Windows\CurrentVersion\App Paths\"+qprogram >cValue = "Path" > >cValueRead = ReadREG_SZ(nKey, cSubKey, cValue) >IF (EMPTY(cValueRead)) THEN > RETURN '' >ELSE > RETURN cValueRead >ENDIF > >FUNCTION ReadREG_SZ >* This function reads a REG_SZ value from the registry. If successful, >* it will return the value read. If not successful, it will return an empty string. >PARAMETERS nKey, cSubKey, cValue >* nKey The root key to open. It can be any of the constants defined below. >* #DEFINE HKEY_CLASSES_ROOT -2147483648 >* #DEFINE HKEY_CURRENT_USER -2147483647 >* #DEFINE HKEY_LOCAL_MACHINE -2147483646 >* #DEFINE HKEY_USERS -2147483645 >* cSubKey The SubKey to open. >* cValue The value that is going to be read. > >* Constants that are needed for Registry functions >* #DEFINE REG_SZ 1 > >* WIN 32 API functions that are used >DECLARE INTEGER RegOpenKey IN Win32API ; > INTEGER nHKey, STRING @cSubKey, INTEGER @nResult >DECLARE INTEGER RegQueryValueEx IN Win32API ; > INTEGER nHKey, STRING lpszValueName, INTEGER dwReserved,; > INTEGER @lpdwType, STRING @lpbData, INTEGER @lpcbData >DECLARE INTEGER RegCloseKey IN Win32API INTEGER nHKey > >* Local variables used >LOCAL nErrCode && Error Code returned from Registry functions >LOCAL nKeyHandle && Handle to Key that is opened in the Registry >LOCAL lpdwValueType && Type of Value that we are looking for >LOCAL lpbValue && The data stored in the value >LOCAL lpcbValueSize && Size of the variable >LOCAL lpdwReserved && Reserved Must be 0 > >* Initialize the variables >nKeyHandle = 0 >lpdwReserved = 0 >lpdwValueType = REG_SZ >lpbValue = "" > >nErrCode = RegOpenKey(nKey, cSubKey, @nKeyHandle) >* If the error code isn't 0, then the key doesn't exist or can't be opened. >IF (nErrCode # 0) THEN > RETURN "" >ENDIF > >lpcbValueSize = 1 >* Get the size of the data in the value >nErrCode=RegQueryValueEx(nKeyHandle, cValue, lpdwReserved, @lpdwValueType, @lpbValue, @lpcbValueSize) > >* Make the buffer big enough >lpbValue = SPACE(lpcbValueSize) >nErrCode=RegQueryValueEx(nKeyHandle, cValue, lpdwReserved, @lpdwValueType, @lpbValue, @lpcbValueSize) > >=RegCloseKey(nKeyHandle) >IF (nErrCode # 0) THEN > RETURN "" >ENDIF > >lpbValue = LEFT(lpbValue, lpcbValueSize - 1) >RETURN lpbValue >