Feedback
 
Did this article resolve your question/issue?

   

Your feedback is appreciated.

Please tell us how we can make this article more useful. Please provide us a way to contact you, should we need clarification on the feedback provided or if you need further assistance.

Characters Remaining: 1025

 


Article

Running "OS-COMMAND LPR.EXE" from within 32-bit OpenEdge the Procedure Editor fails on 64-bit Windows.

« Go Back

Information

 
Article Number000035550
EnvironmentProduct: OpenEdge 32-bit
Version: 10.x, 11.x
OS: Windows 64-bit
Question/Problem Description
When running the LPR.EXE command from a normal Windows command prompt (Start->Run->Command Prompt) the command works but when running the same command from within the Procedure Editor using "DOS LPR.EXE" or OS-COMMAND LPR.EXE" the command will fail with an unknown command error.

The same happens when the command is called from within a .bat batch file.
Steps to Reproduce
Clarifying Information
This also affects other standard Windows tools, including but are not limited to: msg.exe and tskill.exe
Same errors are seen if cmd.exe is run directly from C:\Windows\SysWOW64 folder, instead of from Start menu
Error Message'LPR' is not recognized as internal or external command, operable program or batch file.
Defect/Enhancement NumberDefect PSC00248979 / OE00226363
Cause
This issue is caused by how any 64-bit Windows operating system handles 32-bit processes. All 32-bit processes run under what is called the WOW layer (Windows on WIndows). 
The WOW layer redirects any reference to the %WINDIR%\system32 directory to the %WINDIR%\SysWow64 directory.

In the case of the LPR.EXE, the command was located in %WINDIR%\system32 which means that running a command prompt from the Start menu would cause the 64-bit version of CMD.EXE to run and since this is a 64-bit process it can access the %WINDIR%\system32 directory so the LPR.EXE executable would be found and executed.
When the "DOS LPR.EXE" or "OS-COMMAND LPR.EXE" commands were run from the Procedure Editor the 32-bit version of CMD.EXE was loaded from the %WINDIR%\SysWow64 directory and it attempted to run LPR.EXE and failed because there was no LPR.EXE found in the %WINDIR%\SysWow64 directory nor in any other directory referenced by the OS PATH environment variable.

While this issue affects OpenEdge, the issue is not specific to OpenEdge. Other 32-bit programs that invoke the CMD.EXE on 64-bit Windows will also be affected.
Resolution
Change the application code to detect if you're running 32-bit OpenEdge on 64-bit Windows.
If yes, prefix the command to execute with "%WINDIR%\Sysnative\". The prefix will force the WOW layer to not redirect, and to run the 64-bit programs.

The checks are required because the Sysnative reference will NOT exist if the WOW layer is not used. In other words: if Windows and OpenEdge match bit-level, the '%WINDIR%\Sysnative\' will be an invalid path and it will cause the issue instead of solving it.

On Windows XP Sp2, Windows Vista and later / Windows 2003 SP1 and later, Microsoft introduced the IsWow64Process API function to perform this check. Sample code:
DEFINE VARIABLE hProcess AS INTEGER NO-UNDO.
DEFINE VARIABLE Wow64Process AS INTEGER NO-UNDO.
DEFINE VARIABLE resultValue AS INTEGER NO-UNDO.
DEFINE VARIABLE commandtorun AS CHARACTER NO-UNDO INITIAL "msg".

RUN GetCurrentProcess(OUTPUT hProcess).
RUN IsWow64Process(hProcess, INPUT-OUTPUT Wow64Process, OUTPUT resultValue).
IF Wow64Process > 0 THEN DO:
                        MESSAGE "32-bit OpenEdge running on 64-bit Windows".
                        commandtorun = "%WINDIR%\Sysnative\" + commandtorun.
                    END.
                    ELSE MESSAGE "OpenEdge & Windows match bit-level".

OS-COMMAND VALUE(commandtorun).

/* Wow64Process = 0 if both Windows and OpenEdge are 64-bit, or if both are 32-bit */
/* Use PROCESS-ARCHITECTURE function to distinguish between those cases if needed. */

PROCEDURE GetCurrentProcess EXTERNAL "kernel32.dll":
   DEFINE RETURN PARAMETER hProcess AS LONG.
END.

PROCEDURE IsWow64Process EXTERNAL "kernel32.dll":
   DEFINE INPUT PARAMETER hProcess AS LONG.
   DEFINE INPUT-OUTPUT PARAMETER Wow64Process AS HANDLE TO LONG.
   DEFINE RETURN PARAMETER resultValue AS LONG.
END.

In OpenEdge 11.0 and later, the checks can also be performed by using the System.Environment:Is64BitOperatingSystem and System.Environment:Is64BitProcess properties of the .NET 4.x framework.

Sample code assuming OpenEdge 11:
DEFINE VARIABLE commandtorun AS CHARACTER NO-UNDO INITIAL "msg".
DEFINE VARIABLE prefix       AS CHARACTER NO-UNDO.

prefix = IF System.Environment:Is64BitOperatingSystem AND NOT System.Environment:Is64BitProcess THEN "%WINDIR%\Sysnative\" ELSE "". 
OS-COMMAND VALUE(prefix + commandtorun).

If neither of those alternatives can be used, refer to articles 000020085, How to detect which Windows edition you are using ? and 000054631, How to detect 32-bit or 64-bit OpenEdge versions in ABL code running on Windows for further examples on how to implement those checks.


Other alternatives:
  • Put the files you want to access into the %WINDIR%\SysWow64 directory.
  • Put the files you want to access into some other directory and ensure that the directory is included in the OS PATH environment variable.
  • Use 64-bit OpenEdge client (note: Full 64-bit support for OpenEdge is available since OpenEdge 11.3)
Workaround
Notes
This only affects 32-bit OpenEdge clients running on 64-bit WIndows.
When running 32-bit clietnts on 32-bit WIndows or when running 64-bit clients on 64-bit Windows, the issue is not seen because the WOW layer isn't involved.

Progress Article(s):
000035556, What does the File System Redirection functionality on 64-bit Windows mean to application developers?
000020085, How to detect which Windows edition you are using ?
000054631, How to detect 32-bit or 64-bit OpenEdge versions in ABL code running on Windows
Attachment 
Last Modified Date9/13/2015 3:20 AM