41

I am trying to run a 64 bit executable (java.exe) from our 32-bit .NET application. I am using Process class and invoking cmd /c <command name> in order to support all possible commands (like dir, cd etc).

The problem is that on my machine I installed 64-bit version of JRE and java.exe is only available from C:\Windows\System32 folder (x64). I have tried explicily starting 64 bit version of cmd.exe by calling C:\Windows\System32\cmd.exe but it gets redirected to SysWOW64 due to calling process being 32 bit.

Is there anything else I can do to get this to work?

EDIT The whole cmd /c thing is a bit of a red herring. It is not part of the problem, being able to run 64 bit executables is.

Igor Zevaka
  • 74,528
  • 26
  • 112
  • 128
  • 1
    This answer might bring more light into this matter: http://stackoverflow.com/questions/9466850/the-specified-procedure-could-not-be-found-after-disabling-wow64-redirection – Dan Ochiana Oct 23 '14 at 09:42
  • 1
    This answer might help: http://stackoverflow.com/questions/9466850/the-specified-procedure-could-not-be-found-after-disabling-wow64-redirection – Dan Ochiana Oct 23 '14 at 09:45

7 Answers7

42

You can temporarily disable filesystem redirection around the call to Process.Start, the appropriate API's to P/Invoke are Wow64DisableWow64FsRedirection and Wow64RevertWow64FsRedirection.

Another option is to use %windir%\sysnative, which is available on Windows Vista and above.

Michael
  • 54,279
  • 5
  • 125
  • 144
  • Sounds scary, i'll give it a go :) – Igor Zevaka Jan 05 '10 at 01:59
  • Indeed this works. I can't believe this is the official way of doing it - http://msdn.microsoft.com/en-us/library/aa365743%28VS.85%29.aspx - MSDN demonstrates using this function for precisely this purpose. – Igor Zevaka Jan 05 '10 at 02:07
  • Cool, sysnative worked too, i ll probably use that in the final version. – Igor Zevaka Jan 05 '10 at 02:17
  • Use `sysnative`, definitely. Even though `Wow64DisableWow64FsRedirection` only affects the current thread, it's the more complicated way, and requires you to use P/Invoke (which also means you need full trust). How did Java end up in the system directory anyway? Shouldn't it be in program files, like all the well behaving applications? – Luaan Jul 16 '14 at 07:32
  • 3
    It's probably worth noting that `sysnative` only exists for 32-bit processes. If your process is 64-bit, you will get a File not found exception. So you have to check your bitness anyway before accessing `sysnative`, which is a shame because it would be so much better if it resolved to the same folder regardless of your own bitness. – GSerg Feb 26 '19 at 14:17
  • universal access to `sysnative` from 32-bit and 64-bit processes here: https://stackoverflow.com/a/67942292/1351740 – DrakonHaSh Jun 11 '21 at 19:18
17

What you do is you use %windir%\sysnative to resolve 64-bit CMD.EXE and then you launch your other 64-bit program via "/c" command line option.

Nikolai
  • 171
  • 1
  • 2
  • 2
    Thanks a lot! To further clarify use: C:\Windows\Sysnative\cmd.exe will run what is effectively in C:\Windows\System32 without redirection. Further info: http://www.samlogic.net/articles/sysnative-folder-64-bit-windows.htm – Diego Frehner Jul 28 '14 at 16:07
  • sysnative-Folder is not present in Windows10 – MHolzmayr Oct 07 '16 at 08:51
  • Nor Windows 7 or 8.1 – Brian THOMAS Nov 16 '16 at 10:07
  • You can't see it, but you can cd to c:\windows\sysnative in wnidows 10, or run c:\windows\sysnative\notepad.exe for example and get the 64-bit one, if you're in 32 bit cmd for example (or the 32 bit kace client). Good tip. – js2010 Apr 11 '17 at 18:44
7
c:\>set proc
PROCESSOR_ARCHITECTURE=x86
PROCESSOR_ARCHITEW6432=AMD64
PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 70 Stepping 1, GenuineIntel
PROCESSOR_LEVEL=6
PROCESSOR_REVISION=4601

c:\>c:\windows\sysnative\cmd
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

c:\>set proc
PROCESSOR_ARCHITECTURE=AMD64
PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 70 Stepping 1, GenuineIntel
PROCESSOR_LEVEL=6
PROCESSOR_REVISION=4601

c:\>
DenNukem
  • 8,014
  • 3
  • 40
  • 45
4

To run process/script via 64-bit cmd.exe you might use this:

%windir%\SysWOW64\cmd.exe /c %windir%\sysnative\cmd.exe /c ProgramToRun parameters

This solution works universally from both 32-bit and 64-bit processes.


p.s.
%windir%\sysnative exists only in 32-bit processes.
%windir%\SysWOW64 exists both in 32-bit and 64-bit processes.

DrakonHaSh
  • 831
  • 6
  • 7
  • When in 64-bit environment, the first cmd.exe (`%windir%\SysWOW64\cmd.exe`) is started as a 32-bit version. While in 32-bit environment, the first cmd.exe is started as 32-bit version of course. Eventually, the second cmd.exe (`%windir%\sysnative\cmd.exe`) is always started from a 32-bit envrionment and the `%windir%\sysnative` pointing to 64-bit version. Hope this explanation could help those who are not familiar with Windows file system redirection (e.g. like me). Anyway, what a nice and clean universal solution to start a 64-bit app. – Yingyu YOU Jun 08 '22 at 01:40
3

Just in case this might help.. http://msdn.microsoft.com/en-us/library/aa384187(VS.85).aspx

Note that if the application is manifested to show the UAC prompt, then redirection will not take place. And also some folders are exempt from redirection.

Santhosh
  • 6,547
  • 15
  • 56
  • 63
0

"sysnative" seems to have some drawbacks.

Example: When you start powershell.exe via C:\Windows\sysnative\WindowsPowerShell\v1.0\powershell.exe some CmdLets like Get-AppxProvisionedPackage" and "Get-WindowsCapability don't work / throw exceptions:

Get-AppxProvisionedPackage: "Error setting current directory to "C:\Windows\SysNative\WindowsPowerShell\v1.0": Part of the path "C:\Windows\SysNative\WindowsPowerShell\v1.0" could not be found"

(translated from German "Fehler beim Festlegen des aktuellen Verzeichnisses auf "C:\Windows\SysNative\WindowsPowerShell\v1.0": Ein Teil des Pfades "C:\Windows\SysNative\WindowsPowerShell\v1.0" konnte nicht gefunden werden.")

There might be similar problems running other processes than powershell (whenever the process source directory is important?) ...

Sneftel
  • 40,271
  • 12
  • 71
  • 104
Markus
  • 11
0

Here's a way inside a cmd window to switch to 64 bit cmd in the event you find yourself in the 32 bit version:

if %PROCESSOR_ARCHITECTURE%==x86 %windir%\sysnative\cmd

Or to conditionally execute in 64 bit from inside a 32 bit batch process:

if %PROCESSOR_ARCHITECTURE%==x86 "%windir%\sysnative\cmd" /c "someProgram"

Or even better:

set "commands=multiple commands & to execute"
if %PROCESSOR_ARCHITECTURE%==x86 ( "%windir%\sysnative\cmd" /c "%commands%" ) else ( %commands% )
BuvinJ
  • 10,221
  • 5
  • 83
  • 96