我目前面临的问题是,我希望实现一个在远程服务器上启动批处理文件的PHP脚本。
经过几个小时的想法,我最接近的解决方案是本地服务器上的一个批处理文件,它可以由PHP脚本启动。但是,批处理文件在通过PHP脚本启动时不知何故不会启动远程批处理文件。
如果批处理文件c:\directoryapps\sub\classes\actions\test.bat是通过双击在本地启动的,则执行远程批处理文件c:\directory\sub\test.bat时PsExec不会出现问题。
根据需要授予权限。
我使用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脚本中运行第一批文件代码,但效果更差。
发布于 2019-11-28 07:18:32
主要问题是决定将Sysinternals安装到%SystemRoot%\System32的子目录中。这不是一个好的决定,造成了这里的问题。
目录%SystemRoot%\System32用于在64位环境中执行的64位应用程序.
在32位环境中,%SystemRoot%\System32的使用通常扩展为C:\Windows\System32,这将导致Windows 文件系统重定向器向%SystemRoot%\SysWOW64扩展C:\Windows\SysWOW64的重定向。
%SystemRoot%\SysWOW64包含32位系统可执行文件,但不包含带有文件PsExec.exe的目录SysinternalsSuite .
python.exe是一个32位的可执行文件.由于这个原因,在Python %SystemRoot%\SysWOW64\cmd.exe (32位版本的%SystemRoot%\SysWOW64\cmd.exe命令处理器)中,只使用%SystemRoot%\SysWOW64\cmd.exe启动。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目录的子目录SysinternalsSuite中具有适当参数的32位可执行PsExec.exe。
特殊的重定向Sysnative只存在于32位环境中执行的32位应用程序.请注意,Sysnative既不是目录,也不是符号链接或硬链接。辅助文件系统不包含目录C:\Windows中的条目C:\Windows。由于这个原因,无法在批处理文件if exist %SystemRoot%\Sysnative或if exist %SystemRoot%\Sysnative\中使用这两种条件,因为这两种条件的计算结果总是为false。但是,if exist %SystemRoot%\Sysnative\cmd.exe可以在批处理文件中使用,以确定批处理文件是否由64位Windows上的32位Windows命令处理器处理,因为在此用例中条件计算为true。
我还建议阅读微软文档页面WOW64实现细节和受WOW64影响的注册表项,以了解32位Windows仿真如何在64位Windows上工作。
一个小问题是在Windows命令行的末尾追加&。shell脚本行末尾的符号只由Unix/Linux/Mac脚本解释器解释为指令,以运行在后台分离的可执行文件。因此,shell脚本解释器不会在脚本继续之前或在用户输入要执行的下一个命令之前等待已启动的可执行文件的终止。
Windows命令处理器cmd.exe将双引号参数字符串外的符号解释为和操作符,它们通常用于在一个命令行上指定多个命令,参见使用Windows批处理文件使用多条命令的单行。如果在&之后,cmd.exe解释的命令行中没有任何内容,则cmd.exe命令处理器将忽略和操作符。
因此,不要在Windows命令行上追加&。
命令行上的批处理文件中还有两个小问题:
"C:/Windows/System32/SysinternalsSuite/PsExec.exe" \\server -i -u **** -p **** c:\\directory\\sub\\test.batWindows上的目录分隔符是\,而不是/,微软在文档页命名文件、路径和命名空间上解释了这一点。默认情况下,Windows内核将文件/文件夹字符串中的所有/替换为\,然后将字符串传递给适当的文件系统函数。但是,使用Linux/Mac目录分隔符/可能会导致意外行为。
示例:
在Windows命令提示符窗口中运行:
for %I in (C:/Windows/*.exe) do @echo %I在Windows目录中找到的可执行文件是用C:和没有路径的文件名输出的。因此分配给循环变量I是一个字符串,它引用驱动器C:当前目录中的可执行文件。但是,在执行此命令行时,驱动器C:上的当前目录很可能不是C:\Windows,这将导致实际处理分配给循环变量I的文件名的问题,而不仅仅是将其打印到控制台窗口。
现在在同一个命令提示符窗口中运行:
for %I in (C:\Windows\*.exe) do @echo %I输出的文件名与前面相同,但这次是完全路径。
结论: Windows上的文件/文件夹字符串不使用/,而依赖于Windows内核的自动校正。/主要用于Windows选项的开头。
在批处理文件中,两个目录名之间以及目录名与目录名之间的\\用法也总是错误的,在删除一个反斜杠将文件/文件夹名称字符串传递给文件系统之前,必须由Windows内核进行更正。\\仅在UNC路径开始时有效。
https://stackoverflow.com/questions/59056066
复制相似问题