我使用 perl 调用system start
,我需要指定我希望我的程序绑定到的 cpu 编号。
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