2

I use perl to call system start that I need to specify the cpu number which I want my program to bind to.

When I use x86 perl, it will launch x86 cmd to run the start command. This x86 start doesn't accept the parameter 0x100000000 as it exceeds 32 bit length. If I use a x64 perl, the whole thing works fine because x64 perl launch x64 cmd which accepts 0x100000000.

So how can I launch a x64 cmd to run the start command when using a 32-bit perl?

Details:

First, I verified that 32bit cmd shell doesn't accept start /affinity 100000000 while 64bit cmd shell does. In 32bit cmd shell, it throws error The system cannot accept the START command parameter 100000000.

Then I tried x64 perl and x86 perl respectively and find x86 perl will get the same error. See commands below.

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}"

Is there any method to launch a x64 shell using x86 perl to excute start?

ikegami
  • 367,544
  • 15
  • 269
  • 518
lionel
  • 415
  • 1
  • 5
  • 14
  • I am not familar with windows, but would [this](https://ss64.com/nt/syntax-64bit.html) be of any value? Or using a module like [Win32::Process](https://metacpan.org/pod/Win32::Process)? – Håkon Hægland Jul 26 '19 at 08:56
  • @HåkonHægland Thanks for the links, I used Process Explorer to check the cmd image type (32 bit or 64 bit)to be right as my description. I could only use one line perl as I showed so I don't know if win32::Process would work. – lionel Jul 26 '19 at 10:48

2 Answers2

1

The following demonstrates the problem simply:

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

The difference is due to Windows running C:\Windows\SysWOW64\cmd.exe instead of C:\Windows\System32\cmd.exe. This is the result of transparent internal translations, not differences in PATH, so being more explicit with the path doesn't help.

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

The solution is to create a link to cmd.exe, and use that instead. This bypasses Windows's shenanigans.

>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
ikegami
  • 367,544
  • 15
  • 269
  • 518
1

The File System Redirector of WOW64 emulator redirects file system paths of %SystemRoot%\system32 to %SystemRoot%\SysWOW64 where %SystemRoot% is the a system environment variable which refers to the Windows directory e.g. C:\Windows.

So normally, the WOW64 processes (32-bit processes running on 64-bit windows) can not access the system32 directory.

However, starting with windows Vista, the 32-bit processes can refer to and access the files and folder in the sysetm32 directory by replacing system32 with the special alias SysNative in the file path.

To launch the x64 cmd shell from a x86 perl instance, you need to explicitly specify the path to the 64-bit cmd.exe by %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'"

Note, however, that this only works on a WOW64 process, So it can not be used as a single one-liner solution for both x86 and x64 versions of perl under Windows. However, you could use the following in a program:

use Config qw( %Config );
my $system = $ENV{SystemRoot} . '\\' . ( $Config{ptrsize} == 4 ? 'SysNative' : 'System32' );
ikegami
  • 367,544
  • 15
  • 269
  • 518
sst
  • 1,443
  • 1
  • 12
  • 15
  • This really solved my problem! I don't have to call x86 perl and x64 perl with the same statement so this is enough for me. To make it more clear, what does the option `/x /d /c` mean for cmd.exe? – lionel Jul 28 '19 at 16:22
  • @lionel, See `help cmd` or `cmd /?` (both do the same thing) – ikegami Jul 29 '19 at 01:39