开发者

How to start a 64-bit process from a 32-bit process

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 th开发者_运维百科is 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.


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.


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.


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:\>


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.


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.


"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?) ...


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% )
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜