Executing a 64-Bit program from Windows' system folder

I Love Xbase++ (ILX)
The portal for Xbase++ developers worldwide

Pat France

New member
Staff member
I am here to help you!
Aug 9, 2022
23
3
3
Customer Identifier
E114627
This article pertains to Xbase++ applications running on a 64-Bit Windows operating system, such as Windows 11.

Windows performs a lot of tasks behind-the-scenes to allow 32-Bit and 64-Bit programs to coexist on a 64-Bit operating system. One of these tasks is to virtualize access to the Windows system folder, which for compatibility exists in two flavors on a 64-Bit platform:
  • %windir%\system32: contains 64-Bit binaries
  • %windir%\syswow64: contains 32-Bit binaries
Windows applications, regardless of whether it's 64-Bit or an application written for an older 32-Bit version of Windows, typically access the system folder in the same way: by specifying the "system32" folder as part of the path when executing a system program. In order to provide a compatible (32-Bit!) environment to 32-Bit applications, Windows automatically redirects the path to point to the 32-Bit Windows environment. In other words: instead of accessing "c:\windows\system32", a 32-Bit application is instead redirected to "c:\windows\syswow64"!

In cases where a 32-Bit program actually needs to run a 64-Bit system program, the implicit folder redirection must be disabled. The "Sysnative" virtual folder can be used to access the native (64-Bit) system folder from within a 32-Bit application.

The following example uses the RunShell() function to execute the nbtstat.exe system utility for exemplary purposes. nbtstat.exe is an example of a program which only exists as a 64-Bit program in the native "system32" directory.

Xbase++:
#include "fileio.ch"

PROCEDURE Main()
 LOCAL nAttribute
 LOCAL nHStdOut, nHStdErr
 LOCAL aStdHandles

      // Redirect the standard out and standard error streams to a file
      // to allow processing the output of the called program.
      nAttribute := FC_NORMAL+FC_AUTODELETE+FA_INHERITABLE
      nHStdOut   := FCreate( STDOUT_FILE, nAttribute )
      nHStdErr   := FCreate( STDERR_FILE, nAttribute )
      aStdHandles:= {NIL,nHStdOut,nHStdErr}

      // Use RunShell() to execute nbtstat.exe
      RunShell( "/C %windir%\system32\nbtstat.exe",,,, aStdHandles )
 
      // Print the output produced by nbstat.exe and clean up
      PrintFile( nHStdOut )
      PrintFile( nHStdErr )

      FClose( nHStdOut )
      FClose( nHStdErr )
RETURN

PROCEDURE PrintFile( nH )
   LOCAL cBuffer
   FSeek( nH, 0, FS_SET )
   cBuffer := Space( FSize( nH ) )
   FRead( nH, @cBuffer, Len(cBuffer) )
   ? cBuffer
RETURN

Since the "system32" folder is used in the path, access is automatically redirected to the "syswow64" (32-Bit) folder, in which nbtstat.exe does not exist. Consequently, the above program produces the following output in its StdErr stream when executed on a 64-Bit Windows operating system:

1727189936591.png


To correctly run nbtstat.exe in the platform's native system folder, change line #16 as follows:

Xbase++:
RunShell( "/C %windir%\sysnative\nbtstat.exe",,,, aStdHandles )

Afterwards, nbtstat.exe should be called correctly, and the command's help message should be output to StdOut:

1727189874430.png