2

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

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

那么在使用 32 位 perl 时如何启动 x64cmd来运行命令?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 来执行启动?

4

2 回答 2

1

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

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

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

要从 x86 perl 实例启动 x64 cmd shell,您需要通过以下方式显式指定 64 位 cmd.exe 的路径%SystemRoot%\SysNative\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' );
于 2019-07-27T11:58:46.067 回答
1

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

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

解决方案是创建一个指向 的链接,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
于 2019-07-26T18:11:58.083 回答