【问题标题】:How to launch a x64 shell using x86 perl system on windows如何在 Windows 上使用 x86 perl 系统启动 x64 shell
【发布时间】:2019-12-04 09:08:44
【问题描述】:

我使用 perl 调用 system start,我需要指定我希望我的程序绑定到的 cpu 编号。

当我使用 x86 perl 时,它将启动 x86 cmd 来运行启动命令。这个 x86 start 不接受参数 0x100000000,因为它超过了 32 位长度。如果我使用 x64 perl,整个事情都可以正常工作,因为 x64 perl 启动 x64 cmd,它接受 0x100000000

那么在使用 32 位 perl 时如何启动 x64 cmd 来运行 start 命令?

详情:

首先,我验证了 32 位 cmd shell 不接受 start /affinity 100000000 而 64 位 cmd shell 接受。在 32 位 cmd shell 中,它会抛出错误 The system cannot accept the START command parameter 100000000.

然后我分别尝试了x64 perl和x86 perl,发现x86 perl会得到同样的错误。请参阅下面的命令。

path/to/x64/perl.exe -e "system qq{start /b /wait /affinity 100000000 my.exe}"
path/to/x86/perl.exe -e "system qq{start /b /wait /affinity 100000000 my.exe}"

有没有什么方法可以使用 x86 perl 启动 x64 shell 来执行启动?

【问题讨论】:

  • 我不熟悉 Windows,但this 有什么价值吗?或者使用像Win32::Process这样的模块?
  • @HåkonHægland 感谢您的链接,我使用 Process Explorer 检查了 cmd 图像类型(32 位或 64 位)是否与我的描述相符。我只能使用一行 perl,所以我不知道 win32::Process 是否可以工作。

标签: windows perl cmd syswow64


【解决方案1】:

File System Redirector WOW64 模拟器将%SystemRoot%\system32 的文件系统路径重定向到%SystemRoot%\SysWOW64,其中%SystemRoot% 是指Windows 目录的系统环境变量,例如C:\Windows.

所以通常情况下,WOW64 进程(在 64 位窗口上运行的 32 位进程)无法访问system32 目录。

但是,从 Windows Vista 开始,32 位进程可以通过将文件路径中的 system32 替换为特殊别名 SysNative 来引用和访问 sysetm32 目录中的文件和文件夹。

要从 x86 perl 实例启动 x64 cmd shell,您需要通过 %SystemRoot%\SysNative\cmd.exe 显式指定 64 位 cmd.exe 的路径

Path_to_x86_perl\perl -e "system $ENV{SystemRoot}.'\sysnative\cmd.exe /x /d /c start /b /wait /affinity 100000000 my.exe'"

但是请注意,这仅适用于 WOW64 进程,因此它不能用作 Windows 下 x86 和 x64 版本的 perl 的单一单行解决方案。但是,您可以在程序中使用以下内容:

use Config qw( %Config );
my $system = $ENV{SystemRoot} . '\\' . ( $Config{ptrsize} == 4 ? 'SysNative' : 'System32' );

【讨论】:

  • 这真的解决了我的问题!我不必用相同的语句调用 x86 perl 和 x64 perl,所以这对我来说已经足够了。更清楚地说,选项/x /d /c 对 cmd.exe 意味着什么?
  • @lionel,见help cmdcmd /?(两者都做同样的事情)
【解决方案2】:

下面简单演示了这个问题:

>sp5300-x64\perl\bin\perl -e"system 'set'" | perl -ne"print if /^ProgramFiles=/i"
ProgramFiles=C:\Program Files

>sp5300-x86\perl\bin\perl -e"system 'set'" | perl -ne"print if /^ProgramFiles=/i"
ProgramFiles=C:\Program Files (x86)

差异是由于 Windows 运行 C:\Windows\SysWOW64\cmd.exe 而不是 C:\Windows\System32\cmd.exe。这是透明内部翻译的结果,而不是 PATH 中的差异,因此更明确的路径无济于事。

>sp5300-x86\perl\bin\perl -e"system 'C:\Windows\System32\cmd /x /d /c set'" | perl -ne"print if /^ProgramFiles=/i"
ProgramFiles=C:\Program Files (x86)

solution 是创建一个指向cmd.exe 的链接,并使用它来代替。这绕过了 Windows 的恶作剧。

>mklink cmd64.exe "C:\Windows\System32\cmd.exe"
symbolic link created for cmd64.exe <<===>> C:\Windows\System32\cmd.exe

>sp5300-x86\perl\bin\perl -e"system 'cmd64 /x /d /c set'" | perl -ne"print if /^ProgramFiles=/i"
ProgramFiles=C:\Program Files

【讨论】:

    猜你喜欢
    • 2015-01-20
    • 2015-09-25
    • 1970-01-01
    • 1970-01-01
    • 2013-07-15
    • 2015-09-20
    • 2020-07-14
    • 2010-11-28
    • 1970-01-01
    相关资源
    最近更新 更多