如何在Windows上使用x86 perl系统启动x64 shell



我使用 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 外壳中,它会抛出错误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}"

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

文件系统

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

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

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

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

Path_to_x86_perlperl -e "system $ENV{SystemRoot}.'sysnativecmd.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' );

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

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

差异是由于Windows运行C:WindowsSysWOW64cmd.exe而不是C:WindowsSystem32cmd.exe 。这是透明的内部翻译的结果,而不是PATH的差异,因此更明确地使用路径无济于事。

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

解决方案是创建一个指向cmd.exe的链接,并改用它。这绕过了Windows的恶作剧。

>mklink cmd64.exe "C:WindowsSystem32cmd.exe"
symbolic link created for cmd64.exe <<===>> C:WindowsSystem32cmd.exe
>sp5300-x86perlbinperl -e"system 'cmd64 /x /d /c set'" | perl -ne"print if /^ProgramFiles=/i"
ProgramFiles=C:Program Files

最新更新