64-bit ScriptingLet’s say you’ve written a little 32-bit script that calls a Windows command such as nbtstat. When you try to run the script in x64 Windows, you get an annoying “File not found” error – even though you can see the command sitting in the \Windows\system32 folder.

What’s going on here?

x64 version of Windows have two system folders: \Windows\system32 and \Windows\SysWOW64.

The 32-bit commands are in the SysWOW64 folder, and the 64-bit commands are stored in the system32 directory. x64 Windows looks in system32 by default when you call a command line function, since it tries to call the 64-bit goodies (no, that’s not backwards!).

So, you might think that you can simply change your script to explicitly call, for example, \Windows\system32\nbtstat instead of just nbtstat, and you’ll be off and running, right? Wrong.

Fortunately, there is an easy way to solve this little problem…

The reason that calling your command line function with the full path doesn’t work is because Windows has a lovely little built-in “auto-redirect” to the SysWOW64 (32-bit stuff) folder. Since your script is 32-bit, the redirect kicks in.

If you’re writing an honest-to-god Windows application, there is a call you can make to disable this automatic redirection (Wow64DisableWow64FsRedirection). However, this won’t work for a simple Ruby script, such as my LAN Scanning Tool. In fact, this is exactly where I ran into this problem the other day. I hadn’t tested my little tool on an x64 version of Windows. After installing the x64 Windows 7 Release Candidate, I discovered the LANscan.exe app would throw the error I mentioned above.

Lucky for us, it is really easy to fix this little problem.

It turns out that x64 Windows includes a “virtual folder” called \Windows\sysnative. The sysnative folder cannot been seen in Explorer, or even from the command line. If you call a command in sysnative from within a normal application, it won’t work. But, if you call \Windows\sysnative\nbtstat from within a script – such as my Ruby-based LANscan app, Windows will automatically redirect the call to the \Windows\system32 directory instead of defaulting to the 32-bit stuff in \Windows\SysWOW64. Thus, your 32-bit app can access functions in the native 64-bit “system32” directory! Cool, eh?

Note that this redirection trick isn’t necessary for all system calls. For example, ping exists as both a 32-bit and 64-bit executable. In that case, redirection isn’t necessary. However, in my case, nbtstat is only available as a 64-bit function in \Windows\system32, and NOT as a 32-bit executable in \Windows\SysWOW64. That’s why I was getting the “not found” error: because Windows was automatically redirecting my call to the 32-bit SysWOW64 directory.

In order to make your script work on both 32-bit and 64-bit Windows, you might want to do something like the following in your scripts:

# Check for x64, call appropriate command
if File.directory? '\\Windows\\SysWOW64' then
  result = `\\Windows\\sysnative\\nbtstat.exe -A #{putername}`
else
  result = `nbtstat.exe -A #{putername}`
end

Of course, the above example is written in Ruby, so you’ll have to customize it for your chosen language. But the general idea remains the same:

  1. Check for \Windows\SysWOW64
  2. If the directory exists, you are running on x64 Windows, so call the command with the full \Windows\sysnative path
  3. If the directory does not exist, you’re running on 32-bit Windows, so call the command with no path and let Windows handle it

Pretty simple, eh?

I’ve released v1.3 of my LAN Scanning Tool, which you can download for free. It now fully supports XP, XP x64, Vista, Vista x64, Win7, and Win7 x64.

Have fun!

Get Scottie Stuff!