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

Posted

技术标签:

【中文标题】如何从 32 位进程启动 64 位进程【英文标题】:How to start a 64-bit process from a 32-bit process 【发布时间】:2011-01-01 11:50:30 【问题描述】:

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

问题是我在我的机器上安装了 64 位版本的 JRE,而 java.exe 只能从 C:\Windows\System32 文件夹 (x64) 获得。我已经尝试通过调用C:\Windows\System32\cmd.exe 来明确启动cmd.exe 的64 位版本,但由于调用进程是32 位,它被重定向到SysWOW64

我还能做些什么来让它工作吗?

编辑整个cmd /c 有点像红鲱鱼。这不是问题的一部分,能够运行 64 位可执行文件是。

【问题讨论】:

这个答案可能会给这个问题带来更多启示:***.com/questions/9466850/… 这个答案可能会有所帮助:***.com/questions/9466850/… 【参考方案1】:

您可以在调用 Process.Start 时暂时禁用文件系统重定向,P/Invoke 的适当 API 是 Wow64DisableWow64FsRedirection 和 Wow64RevertWow64FsRedirection。

另一种选择是使用 %windir%\sysnative,它适用于 Windows Vista 及更高版本。

【讨论】:

听起来很吓人,我试试看:) 确实有效。我不敢相信这是官方的做法 - msdn.microsoft.com/en-us/library/aa365743%28VS.85%29.aspx - MSDN 演示了使用这个函数来达到这个目的。 酷,sysnative 也可以,我可能会在最终版本中使用它。 绝对使用sysnative。尽管Wow64DisableWow64FsRedirection 只影响当前线程,但它是更复杂的方式,并且需要您使用 P/Invoke(这也意味着您需要完全信任)。无论如何,Java 是如何进入系统目录的?它不应该像所有表现良好的应用程序一样放在程序文件中吗? 可能值得注意的是,sysnative 仅存在于 32 位进程。如果您的进程是 64 位,您将收到 File not found 异常。所以你必须在访问sysnative之前检查你的位数,这很遗憾,因为不管你自己的位数如何,如果它解析到同一个文件夹会好得多。【参考方案2】:

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

【讨论】:

非常感谢!为了进一步阐明使用: C:\Windows\Sysnative\cmd.exe 将运行 C:\Windows\System32 中有效的内容,而无需重定向。更多信息:samlogic.net/articles/sysnative-folder-64-bit-windows.htm sysnative-Folder 在 Windows10 中不存在 也不是 Windows 7 或 8.1 看不到,但是可以在 wnidows 10 中 cd 到 c:\windows\sysnative,或者运行 c:\windows\sysnative\notepad.exe 例如获取 64 位一,例如,如果您使用的是 32 位 cmd(或 32 位 kace 客户端)。很好的提示。【参考方案3】:
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】:

以防万一这可能会有所帮助.. http://msdn.microsoft.com/en-us/library/aa384187(VS.85).aspx

请注意,如果应用程序显示为显示 UAC 提示,则不会发生重定向。还有一些文件夹免于重定向。

【讨论】:

【参考方案5】:

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

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

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


附言 %windir%\sysnative 仅存在于 32 位进程中。 %windir%\SysWOW64 存在于 32 位和 64 位进程中。

【讨论】:

【参考方案6】:

“sysnative”似乎有一些缺点。

示例: 当您通过 C:\Windows\sysnative\WindowsPowerShell\v1.0\powershell.exe 启动 powershell.exe 时,一些 CmdLets(如 Get-AppxProvisionedPackage" and "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" 了解 nicht gefunden werden。”)

运行除 powershell 之外的其他进程可能会出现类似问题(只要进程源目录很重要?)...

【讨论】:

【参考方案7】:

如果您发现自己处于 32 位版本,可以在 cmd 窗口中切换到 64 位 cmd:

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

【讨论】:

以上是关于如何从 32 位进程启动 64 位进程的主要内容,如果未能解决你的问题,请参考以下文章

如何从 32 位进程读取 64 位注册表项?

如何测量 32 位程序中 64 位进程的内存使用情况?

从 32 位进程获取 64 位进程的命令行字符串

检测目标程序ELF bit是32还是64

使用 C++ 从 32 位进程访问 64 位 dll

从 64 位进程调用 32 位代码