Feedback
Did this article resolve your question/issue?

   

Article

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

« Go Back

Information

 
TitleRunning "OS-COMMAND LPR.EXE" from within 32-bit OpenEdge the Procedure Editor fails on 64-bit Windows.
URL NameRunning-OS-COMMAND-LPR-EXE-from-within-32-bit-OpenEdge-the-Procedure-Editor-fails-on-64-bit-Windows
Article Number000159472
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
Last Modified Date9/13/2015 3:20 AM
Attachment 
Files
Disclaimer The origins of the information on this site may be internal or external to Progress Software Corporation (“Progress”). Progress Software Corporation makes all reasonable efforts to verify this information. However, the information provided is for your information only. Progress Software Corporation makes no explicit or implied claims to the validity of this information.

Any sample code provided on this site is not supported under any Progress support program or service. The sample code is provided on an "AS IS" basis. Progress makes no warranties, express or implied, and disclaims all implied warranties including, without limitation, the implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample code is borne by the user. In no event shall Progress, its employees, or anyone else involved in the creation, production, or delivery of the code be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample code, even if Progress has been advised of the possibility of such damages.