Exec启动bat文件,但不启动sub-bat文件

问题描述 投票:0回答:1

我目前面临的问题是我想实现一个在远程服务器上启动批处理文件的php脚本。

经过数小时的思考,我最接近解决方案的是本地服务器上的批处理文件,该文件可以由php脚本启动。但是,当通过php脚本启动时,批处理文件无法以某种方式启动远程批处理文件。在本地启动时,远程批处理文件可以正常启动。

根据需要授予权限。

我正在php中使用以下代码来启动第一个批处理文件:

$cmd = '"c:\\directoryapps\\sub\\classes\\actions\\test.bat"';
exec('cmd /c '.$cmd.' &');

该批处理文件的代码如下:

"C:/Windows/System32/SysinternalsSuite/PsExec.exe" \\server -i -u **** -p **** c:\\directory\\sub\\test.bat 

我如何实现此版本的工作版本?我也尝试过从php运行第一个批处理文件代码,但效果不佳。

php windows batch-file server remote-server
1个回答
0
投票

主要问题是决定将Sysinternals Suite安装到%SystemRoot%\System32的子目录中。这不是一个好的决定,并且会在这里引起问题。

目录%SystemRoot%\System32用于在64位Windows上的64位环境中执行的64位应用程序。

在32位环境中,[[通常]扩展为%SystemRoot%\System32C:\Windows\System32的用法,导致Windows File System Redirector分别重定向到%SystemRoot%\SysWOW64扩展的C:\Windows\SysWOW64[%SystemRoot%\SysWOW64包含32位系统可执行文件,但不包含带有文件SysinternalsSuite的目录PsExec.exe

python.exe是32位可执行文件。从Python脚本cmd中的%SystemRoot%\SysWOW64\cmd.exe开始,这是Windows命令处理器的32位版本。 32位cmd找不到C:\Windows\SysWOW64\SysinternalsSuite\PsExec.exe,因此根本不执行psexec.exe

完全不需要启动cmd.exe来运行批处理文件,该批处理文件仅包含一个命令行以用于32位环境的错误路径来运行psexec.exe

在Python脚本中使用就足够了:

$args = '\\\\server -i -u "****" -p "****" "C:\\directory\\sub\\test.bat"'; exec('C:\\Windows\\Sysnative\\SysinternalsSuite\\PsExec.exe '.$args.);

32位python.exe使用此代码运行带有适当参数的64位Windows系统目录的子目录PsExec.exe中的32位可执行文件SysinternalsSuite

特殊重定向Sysnative仅对于在32位环境中执行的32位应用程序存在。请注意,Sysnative既不是目录,也不是符号链接或硬链接。文件系统在目录Sysnative中不包含条目C:\Windows。因此,无法在批处理文件if exist %SystemRoot%\Sysnativeif exist %SystemRoot%\Sysnative\中使用,因为两个条件的评估结果始终为false。但是if exist %SystemRoot%\Sysnative\cmd.exe可以在批处理文件中使用,以查明该批处理文件是否由64位Windows上的32位Windows命令处理器处理,因为在这种情况下条件评估为true。

[我建议您还阅读Microsoft文章WOW64 Implementation DetailsRegistry Keys Affected by WOW64,以获得有关32位Windows仿真在64位Windows上如何工作的知识。


一个小问题是在Windows命令行末尾附加&。 Shell脚本行末尾的与号仅由Unix / Linux / Mac Shell脚本解释器解释为运行在后台分离的可执行文件的指令。因此,shell脚本解释器不会在脚本继续执行之前或在用户输入要执行的下一个命令之前等待启动的可执行文件的终止。

Windows命令处理器cmd.exe将双引号参数字符串之外的与号解释为

AND

运算符,通常用于在一个命令行上指定多个命令,请参见single line with multiple commands using Windows batch file。如果&后面的命令行没有任何内容,则Windows命令处理器将忽略AND运算符。因此,请勿在Windows命令行上附加cmd.exe。>>


在命令行上的批处理文件中还有两个较小的问题:

&

Windows上的目录分隔符是"C:/Windows/System32/SysinternalsSuite/PsExec.exe" \\server -i -u **** -p **** c:\\directory\\sub\\test.bat
,而不是Microsoft在有关\的文章中解释的/。默认情况下,Windows内核将文件/文件夹字符串中的所有Naming Files, Paths, and Namespaces替换为/,然后再将字符串传递给适当的文件系统功能。但是,使用Linux / Mac目录分隔符\仍可能导致意外行为。

示例:

在Windows命令提示符窗口中运行:

/

在Windows目录中找到的可执行文件以for %I in (C:/Windows/*.exe) do @echo %I
输出,文件名不带路径。因此,分配给循环变量C:的字符串是引用驱动器I当前目录中的可执行文件的字符串。但是执行此命令行时驱动器C:上的当前目录很可能不是C:,这将导致在真正处理分配给循环变量C:\Windows的文件名而不是仅将其打印到控制台窗口时出现问题。

立即在同一命令提示符窗口中运行:

I

与以前输出相同的文件名,但是这次具有完整路径。

结论:不要在Windows的文件/文件夹字符串中使用for %I in (C:\Windows\*.exe) do @echo %I ,而是取决于Windows内核的自动更正。 /在Windows上主要用于选项的开始。

在两个目录名之间以及在目录名和文件名之间的批处理文件中/的使用也总是错误的,并且必须通过Windows内核进行更正,然后再通过删除将文件/文件夹名称字符串传递给文件系统一个反斜杠。 \\仅在\\的开头有效。

© www.soinside.com 2019 - 2024. All rights reserved.