I need to open a second Progress session from the current session in batch mode.
I used the session:display-type to run the _progres or the prowin32 executable. But I got an issue with this code because of the prowin executable (64 bits).
The code can be run on Windows or Linux/Unix OS, so no dll can be used.
Any suggestion?
Thanks.
Example
IF SESSION:DISPLAY-TYPE = "TTY"
THEN OS-COMMAND NO-WAIT VALUE("_progres").
ELSE OS-COMMAND NO-WAIT VALUE("prowin32").
But, OpenEdge 11.6 64 bits does not contain prowin32 executable. It contains the prowin executable.
I got an ugly solution searching for one or other executable:
IF SESSION:DISPLAY-TYPE = "TTY"
THEN OS-COMMAND NO-WAIT VALUE("_progres").
ELSE IF SEARCH("prowin.exe") <> ?
THEN OS-COMMAND NO-WAIT VALUE("prowin").
ELSE OS-COMMAND NO-WAIT VALUE("prowin32").
But I'm looking for a better way to do this.
I use the following logic to do the same thing, I use a single procedure makeProcess.p to execute the select binary from a specific working folder.
IF SESSION:WINDOW-SYSTEM = "TTY":U THEN
ASSIGN executableFile = SEARCH( "bin~/_progres":U ).
ELSE
&IF PROVERSION >= '11.4' &THEN
IF PROCESS-ARCHITECTURE = 64 THEN
ASSIGN executableFile = SEARCH( "bin~/prowin.exe":U ).
ELSE
&ENDIF
ASSIGN executableFile = SEARCH( "bin~/prowin32.exe":U ).
RUN makeProcess.r ( commandLine, "C:\WORKDIR", OUTPUT processId ).
/*------------------------------------------------------------------------
File : makeProcess.p
Purpose : Execute a commandline appropriately for windows or unix.
----------------------------------------------------------------------*/
/* *************************** Definitions ************************** */
DEFINE INPUT PARAMETER p-commandLine AS CHARACTER NO-UNDO.
DEFINE INPUT PARAMETER p-workingDir AS CHARACTER NO-UNDO.
DEFINE OUTPUT PARAMETER p-pid AS INTEGER NO-UNDO.
/* ******************** Preprocessor Definitions ******************** */
/* *************************** Main Block *************************** */
/* IF SESSION:WINDOW-SYSTEM <> "TTY":U THEN */
/* Spawn processes on WIN32 through API for GUI and TTY */
IF OPSYS <> "UNIX":U THEN
RUN makeGUIProcess(p-commandLine, p-workingDir, OUTPUT p-pid ).
ELSE
RUN makeTTYProcess(p-commandLine, p-workingDir, OUTPUT p-pid ).
RETURN.
FUNCTION GetLastErrors RETURNS INTEGER PRIVATE:
DEFINE VARIABLE dwMessageID AS INTEGER NO-UNDO.
RUN GetLastError (OUTPUT dwMessageID).
RETURN (dwMessageID).
END FUNCTION.
PROCEDURE makeGUIprocess PRIVATE:
DEFINE INPUT PARAMETER CommandLine AS CHARACTER NO-UNDO.
DEFINE INPUT PARAMETER WorkingDir AS CHARACTER NO-UNDO.
DEFINE OUTPUT PARAMETER PID AS INTEGER NO-UNDO.
DEFINE VARIABLE wShowWindow AS INTEGER NO-UNDO INITIAL 0.
DEFINE VARIABLE bResult AS INTEGER NO-UNDO.
DEFINE VARIABLE ReturnValue AS INTEGER NO-UNDO.
DEFINE VARIABLE lastError AS INTEGER NO-UNDO.
DEFINE VARIABLE lpStartupInfo AS MEMPTR NO-UNDO.
SET-SIZE(lpStartupInfo) = 68.
PUT-LONG(lpStartupInfo,1) = 68.
PUT-LONG (lpStartupInfo,45) = 1. /* = STARTF_USESHOWWINDOW */
PUT-SHORT(lpStartupInfo,49) = wShowWindow.
DEFINE VARIABLE lpProcessInformation AS MEMPTR NO-UNDO.
SET-SIZE(lpProcessInformation) = 16.
DEFINE VARIABLE lpWorkingDirectory AS MEMPTR NO-UNDO.
IF WorkingDir <> ? AND WorkingDir <> "":U THEN DO:
SET-SIZE(lpWorkingDirectory) = 256.
PUT-STRING(lpWorkingDirectory,1) = WorkingDir.
END.
RUN CreateProcessA
(
0,
CommandLine,
0,
0,
0,
0,
0,
IF WorkingDir = ? OR WorkingDir="" THEN 0 ELSE GET-POINTER-VALUE(lpWorkingDirectory),
GET-POINTER-VALUE(lpStartupInfo),
GET-POINTER-VALUE(lpProcessInformation),
OUTPUT bResult
).
RUN logVerbose( SUBSTITUTE ("MAKEPROCESS: CreateProcessA Result Code: &1", bResult)).
IF bResult = 0 THEN DO:
PID = 0.
END.
ELSE DO:
PID = GET-LONG(lpProcessInformation,9).
/* release kernel-objects hProcess and hThread: */
RUN CloseHandle (GET-LONG(lpProcessInformation,1), OUTPUT ReturnValue).
RUN CloseHandle (GET-LONG(lpProcessInformation,5), OUTPUT ReturnValue).
END.
ASSIGN lastError = getLastErrors().
IF lastError = 5 THEN
RUN logWarning (SUBSTITUTE("ERROR: &1 (OS Error: &2)", CommandLine, lastError)).
ELSE IF lastError > 0 AND lastError <> 1813 THEN DO:
IF bResult = 0 THEN
RUN logError (SUBSTITUTE("ERROR: &1 (&2)", CommandLine, lastError)).
ELSE
RUN logVerbose (SUBSTITUTE("MAKEPROCESS: CreateProcessA Error: &1 (&2)", CommandLine, lastError)).
END.
SET-SIZE(lpStartupInfo) = 0.
SET-SIZE(lpProcessInformation) = 0.
SET-SIZE(lpWorkingDirectory) = 0.
END PROCEDURE.
/* external procedures */
PROCEDURE CreateProcessA EXTERNAL "kernel32.dll":U :
DEFINE INPUT PARAMETER lpApplicationName AS LONG. /* NULL */
DEFINE INPUT PARAMETER lpCommandline AS CHAR.
DEFINE INPUT PARAMETER lpProcessAttributes AS LONG.
DEFINE INPUT PARAMETER lpThreadAttributes AS LONG.
DEFINE INPUT PARAMETER bInheritHandles AS LONG.
DEFINE INPUT PARAMETER dCreationFlags AS LONG.
DEFINE INPUT PARAMETER lpEnvironment AS LONG.
DEFINE INPUT PARAMETER lpCurrentDirectory AS LONG.
DEFINE INPUT PARAMETER lpStartupInfo AS LONG.
DEFINE INPUT PARAMETER lpProcessInformation AS LONG.
DEFINE RETURN PARAMETER bResult AS LONG.
END PROCEDURE.
PROCEDURE CloseHandle EXTERNAL "kernel32.dll":U :
DEFINE INPUT PARAMETER hObject AS LONG.
DEFINE RETURN PARAMETER ReturnValue AS LONG.
END PROCEDURE.
PROCEDURE GetLastError EXTERNAL "kernel32.dll":U :
DEFINE RETURN PARAMETER dwMessageID AS LONG.
END PROCEDURE.
PROCEDURE makeTTYProcess PRIVATE:
DEFINE INPUT PARAMETER CommandLine AS CHARACTER NO-UNDO.
DEFINE INPUT PARAMETER WorkingDir AS CHARACTER NO-UNDO.
DEFINE OUTPUT PARAMETER PID AS INTEGER NO-UNDO.
IF OPSYS = "UNIX":U THEN
OS-COMMAND VALUE(SUBSTITUTE("cd &1;&2":U, WorkingDir, CommandLine)).
ELSE
OS-COMMAND VALUE(SUBSTITUTE("cd &1 ~&~& &2":U, WorkingDir, CommandLine)).
END PROCEDURE.
Great, this process-architecture function is better than search.
Thanks sirs.