如何从32位进程启动64位进程

42

我正在尝试从我们的32位.NET应用程序中运行一个64位可执行文件(java.exe)。我正在使用Process类并调用cmd /c <command name>来支持所有可能的命令(如dircd等)。

问题是,在我的机器上,我安装了64位版本的JRE,并且java.exe仅在C:\Windows\System32文件夹(x64)中可用。我已经尝试通过调用C:\Windows\System32\cmd.exe显式启动64位版本的cmd.exe,但由于调用进程为32位,因此它被重定向到。

还有其他任何方法可以使它工作吗?

编辑整个cmd / c的事情有点转移注意力了。能够运行64位可执行文件才是问题所在。


1
这个答案可能会更加详细地解释这个问题:http://stackoverflow.com/questions/9466850/the-specified-procedure-could-not-be-found-after-disabling-wow64-redirection - Dan Ochiana
1
这个答案可能会有帮助:http://stackoverflow.com/questions/9466850/the-specified-procedure-could-not-be-found-after-disabling-wow64-redirection - Dan Ochiana
7个回答

42

听起来有点吓人,但我会尝试的 :) - Igor Zevaka
确实有效。我简直不敢相信这是官方的做法 - http://msdn.microsoft.com/en-us/library/aa365743%28VS.85%29.aspx - MSDN演示了使用此函数来实现这一目的。 - Igor Zevaka
很棒,sysnative 也可以工作,我可能会在最终版本中使用它。 - Igor Zevaka
一定要使用 sysnative。尽管 Wow64DisableWow64FsRedirection 只影响当前线程,但这是更复杂的方式,并需要您使用 P/Invoke(这也意味着您需要完全信任)。Java怎么会进入系统目录呢?难道它不应该像所有行为良好的应用程序一样在程序文件中吗? - Luaan
4
值得注意的是,sysnative 只存在于 32 位进程中。如果你的进程是 64 位的,你将会得到一个“文件未找到”的异常。因此,在访问 sysnative 之前,你必须先检查你的位数,这有些遗憾,因为如果它能够解析到相同的文件夹而不考虑位数将更好。 - GSerg
在此处可以从32位和64位进程普遍访问sysnative:https://dev59.com/fnI-5IYBdhLWcg3wI0p9#67942292 - DrakonHaSh

17

您需要做的是使用 %windir%\sysnative 来解析64位CMD.EXE,然后通过“/c”命令行选项启动其他64位程序。


2
非常感谢!为了进一步澄清,使用:C:\Windows\Sysnative\cmd.exe 将运行 C:\Windows\System32 中的有效内容而不进行重定向。更多信息请参见:http://www.samlogic.net/articles/sysnative-folder-64-bit-windows.htm - Diego Frehner
Windows10 中不存在 sysnative 文件夹。 - MHolzmayr
不支持Windows 7或8.1。 - Brian THOMAS
你看不到它,但是在Windows 10中你可以使用cd命令进入c:\windows\sysnative目录,或者运行c:\windows\sysnative\notepad.exe等程序,以获取64位版本,如果你在32位cmd或32位kace客户端中操作的话。这是一个好的技巧。 - js2010

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

4

通过64位cmd.exe运行进程/脚本,您可以使用以下方法:

%windir%\SysWOW64\cmd.exe /c %windir%\sysnative\cmd.exe /c ProgramToRun 参数

这个解决方案适用于32位和64位进程。


p.s.
%windir%\sysnative只存在于32位进程中。
%windir%\SysWOW64同时存在于32位和64位进程中。


在64位环境下,第一个cmd.exe(%windir%\SysWOW64\cmd.exe)会以32位版本启动。而在32位环境下,第一个cmd.exe当然会以32位版本启动。最终,第二个cmd.exe(%windir%\sysnative\cmd.exe)总是从32位环境启动,并且%windir%\sysnative指向64位版本。希望这个解释能够帮助那些不熟悉Windows文件系统重定向的人(比如我)。无论如何,这是一个很好、干净的通用解决方案来启动64位应用程序。 - Yingyu YOU

3

0
"

"sysnative"似乎有一些缺点。

例如: 当您通过C:\Windows\sysnative\WindowsPowerShell\v1.0\powershell.exe启动powershell.exe时,一些CmdLets(如Get-AppxProvisionedPackage"和"Get-WindowsCapability)不起作用/抛出异常:

Get-AppxProvisionedPackage:“将当前目录设置为“C:\Windows\SysNative\WindowsPowerShell\v1.0”时出错:路径的一部分“C:\Windows\SysNative\WindowsPowerShell\v1.0”无法找到”

(从德语翻译而来:“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.")

在运行除powershell之外的其他进程时可能会遇到类似的问题(每当进程源目录很重要时?)..."


0
以下是在cmd窗口中切换到64位cmd的方法,以防您发现自己处于32位版本中:
if %PROCESSOR_ARCHITECTURE%==x86 %windir%\sysnative\cmd

或者在32位批处理进程内以有条件地执行64位操作:

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

或者更好的是:

set "commands=multiple commands & to execute"
if %PROCESSOR_ARCHITECTURE%==x86 ( "%windir%\sysnative\cmd" /c "%commands%" ) else ( %commands% )

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接