***********************************************************
* Program : relRunAndBuildISE.PRG *
* Author : William GC Steinford *
* Date : Nov 2002 *
* Updated : Nov 2005 -- Use F7 instead of Click *
***********************************************************
PROCEDURE relRunAndBuildISE
LPARAMETERS tcIseFile
* Adjust this for the path to your ISE installation:
lcISE_Prog = "c:\Program Files\InstallShield\Express\IsIDE.exe"
DECLARE INTEGER CreateProcess IN kernel32;
INTEGER lpApplicationName, ;
STRING @ lpCommandLine, ;
INTEGER lpProcessAttributes,;
INTEGER lpThreadAttributes,;
INTEGER bInheritHandles,;
INTEGER dwCreationFlags,;
INTEGER lpEnvironment,;
STRING lpCurrentDirectory,;
STRING lpStartupInfo,;
STRING @ lpProcessInformation
DECLARE LONG WaitForSingleObject in win32api INTEGER hHandle, LONG dwMilliseconds
DECLARE INTEGER GetExitCodeProcess in win32api INTEGER hProcess, INTEGER @ nExitCode
#DEFINE SW_SHOW 5
#DEFINE STILL_ACTIVE 0x103
DECLARE INTEGER FindWindow in win32api as apiFindWindow ;
INTEGER nClass, STRING cName
DECLARE INTEGER FindWindowEx IN WIN32API as apiFindWindowEx ;
INTEGER hwndParent, ;
integer hwndChildAfter, ;
string @ lpszClass, ;
string @ lpszWindow
Declare INTEGER SendMessage in user32 as apiSendMessage ;
INTEGER hWnd, ;
INTEGER nMsg, ;
INTEGER nParam1, ;
INTEGER nParam2
LOCAL lcStartInfo, lcProcessInfo, lcCmd, lhProcess, lnExitCode, ;
llBuilt
lcStartInfo = GetStartupInfo()
lcProcessInfo = repl( chr(0), 12 )
*!* typedef struct _PROCESS_INFORMATION { HANDLE hProcess
*!* HANDLE hThread
*!* DWORD dwProcessId
*!* DWORD dwThreadId } PROCESS_INFORMATION
* MSDN Notes: If both AppName and CmdLine are provided, then they are both treated as *lp
* (ie: Pointer to Pointer to String, instead of just lp: Pointer to String)
* When I specify both, it seems that appname works but commandline doesn't.
* MSDN Notes also: If one is null (AppName or CmdLine) then both are expected to be
* given in the other parameter.
* So that's what we do. And it works.
lcCmd = ["]+lcISE_Prog+[" "]+tcIseFile+["]
if 0=CreateProcess( 0, @lcCmd, 0,0,0,0,0,0, ;
lcStartInfo, @lcProcessInfo )
*?"Could not create process"
RETURN -1
ENDIF
lhProcess = Buf2dword( left( lcProcessInfo, 4 ) )
lnExitCode = STILL_ACTIVE
lnRes = 1
llBuilt = .f.
do while lnExitCode=STILL_ACTIVE or lnRes=0
WaitForSingleObject(lhProcess, 500) && wait 1/2 second
IF NOT llBuilt
* Locate the ISE window
lnISE = apifindwindow(0,JUSTSTEM(tcIseFile)+' - InstallShield Express')
IF lnIse>0 && Found
llBuilt = .t.
* Send the F7 keystroke message:
apiSendMessage(lnISE,0x07e8,0,0)
ENDIF
ENDIF
* Find out if Installshield has been exited.
lnExitCode = -2
lnRes = GetExitCodeProcess(lhProcess, @lnExitCode) && non-zero means success.
if lnExitCode=STILL_ACTIVE
if InKey()=27 && user in VFP pressed ESC: Stop waiting
RETURN -3
endif
endif
enddo
RETURN iif(lnRes=0,-2,lnExitCode)
ENDPROC
PROCEDURE getStartupInfo
* creates the STARTUP structure to specify main window
* properties if a new window is created for a new process
*| typedef struct _STARTUPINFO {
*| DWORD cb; 4
*| LPTSTR lpReserved; 4
*| LPTSTR lpDesktop; 4
*| LPTSTR lpTitle; 4
*| DWORD dwX; 4
*| DWORD dwY; 4
*| DWORD dwXSize; 4
*| DWORD dwYSize; 4
*| DWORD dwXCountChars; 4
*| DWORD dwYCountChars; 4
*| DWORD dwFillAttribute; 4
*| DWORD dwFlags; 4
*| WORD wShowWindow; 2
*| WORD cbReserved2; 2
*| LPBYTE lpReserved2; 4
*| HANDLE hStdInput; 4
*| HANDLE hStdOutput; 4
*| HANDLE hStdError; 4
*| } STARTUPINFO, *LPSTARTUPINFO; total: 68 bytes
#DEFINE STARTF_USESHOWWINDOW 1
#DEFINE SW_SHOWMAXIMIZED 3
RETURN num2dword(68) +;
num2dword(0) + num2dword(0) + num2dword(0) +;
num2dword(0) + num2dword(0) + num2dword(0) + num2dword(0) +;
num2dword(0) + num2dword(0) + num2dword(0) +;
num2dword(STARTF_USESHOWWINDOW) +;
num2word(SW_SHOWMAXIMIZED) +;
num2word(0) + num2dword(0) +;
num2dword(0) + num2dword(0) + num2dword(0)
FUNCTION num2word (lnValue)
RETURN Chr(MOD(m.lnValue,256)) + CHR(INT(m.lnValue/256))
ENDFUNC
FUNCTION buf2word (lcBuffer)
RETURN Asc(SUBSTR(lcBuffer, 1,1)) + ;
Asc(SUBSTR(lcBuffer, 2,1)) * 256
ENDFUNC
FUNCTION num2dword (lnValue)
#DEFINE m0 256
#DEFINE m1 65536
#DEFINE m2 16777216
LOCAL b0, b1, b2, b3
b3 = Int(lnValue/m2)
b2 = Int((lnValue - b3*m2)/m1)
b1 = Int((lnValue - b3*m2 - b2*m1)/m0)
b0 = Mod(lnValue, m0)
RETURN Chr(b0)+Chr(b1)+Chr(b2)+Chr(b3)
ENDFUNC
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
ENDFUNC