为什么不由 PsExec 执行的远程批处理文件是从具有函数 exec 的 PHP 脚本中的批处理文件 运行 启动的?
Why is a remote batch file not executed by PsExec started from a batch file ran from within a PHP script with function exec?
我目前面临的问题是我想实现一个 PHP 脚本来在远程服务器上启动一个批处理文件。
经过几个小时的思考,我最接近的解决方案是本地服务器上的一个批处理文件,它可以由 PHP 脚本启动。但是,当通过 PHP 脚本启动时,批处理文件不会以某种方式启动远程批处理文件。
如果双击本地批处理文件 c:\directoryapps\sub\classes\actions\test.bat
,则 PsExec
可以毫无问题地执行远程批处理文件 c:\directory\sub\test.bat
。
根据需要授予权限。
我在 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 脚本的第一个批处理文件代码,但收效甚微。
主要问题是决定将 Sysinternals Suite 安装到 %SystemRoot%\System32
的子目录中。这不是一个好的决定,导致了这里的问题。
目录 %SystemRoot%\System32
用于在 64 位环境中在 64 位环境中执行的 64 位应用程序 Windows。
%SystemRoot%\System32
的用法,通常 扩展为 C:\Windows\System32
,在 32 位环境中导致重定向 Windows File System Redirector到%SystemRoot%\SysWOW64
分别展开C:\Windows\SysWOW64
.
%SystemRoot%\SysWOW64
包含 32 位系统可执行文件,但不包含文件 PsExec.exe
.
的目录 SysinternalsSuite
python.exe
是 32 位可执行文件。因此,在 Python 脚本 %SystemRoot%\SysWOW64\cmd.exe
中仅使用 cmd
启动,这是 Windows 命令处理器的 32 位版本。 32 位 cmd
无法找到 C:\Windows\SysWOW64\SysinternalsSuite\PsExec.exe
,因此根本不会执行 psexec.exe
。
好吧,从 cmd.exe
到 运行 只包含一个命令行到 运行 psexec.exe
的批处理文件不需要 32 位环境的错误路径完全没有。
在Python脚本中使用就足够了:
$args = '\\server -i -u "****" -p "****" "C:\directory\sub\test.bat"';
exec('C:\Windows\Sysnative\SysinternalsSuite\PsExec.exe '.$args.);
32 位 python.exe
运行s 带有此代码的 32 位可执行文件 PsExec.exe
在 64 位 Windows 系统目录的子目录 SysinternalsSuite
中使用适当的参数。
特殊重定向 Sysnative
仅适用于在 32 位环境中执行的 32 位应用程序。请注意 Sysnative
既不是目录也不是符号 link 或硬 link。文件系统在目录 C:\Windows
中不包含条目 Sysnative
。因此,无法在批处理文件中使用 if exist %SystemRoot%\Sysnative
或 if exist %SystemRoot%\Sysnative\
,因为这两个条件的计算结果始终为假。但是 if exist %SystemRoot%\Sysnative\cmd.exe
可以在批处理文件中使用,以查明批处理文件是否由 64 位 Windows 上的 32 位 Windows 命令处理器处理,因为条件计算结果为真在这个用例中。
我建议还阅读 Microsoft 文档页面 WOW64 Implementation Details and Registry 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。如果在 cmd.exe
解释的命令行上 &
之后没有任何内容,Windows 命令处理器将忽略 AND 运算符。
因此不要在 Windows 命令行上附加 &
。
命令行批处理文件中还有两个小问题:
"C:/Windows/System32/SysinternalsSuite/PsExec.exe" \server -i -u **** -p **** c:\directory\sub\test.bat
Windows 上的目录分隔符是 \
而不是 Microsoft 在文档页 Naming Files, Paths, and Namespaces 上解释的 /
。在将 file/folder 字符串传递给适当的文件系统函数之前,Windows 内核默认将所有 /
替换为 \
。但是使用 Linux/Mac 目录分隔符 /
仍然会导致意外行为。
示例:
运行 在 Windows 命令提示符下 window:
for %I in (C:/Windows/*.exe) do @echo %I
在Windows 目录中找到的可执行文件以C:
和不带路径的文件名输出。因此分配给循环变量 I
的是一个字符串,它引用驱动器 C:
当前目录中的可执行文件。但是执行此命令行时驱动器 C:
上的当前目录很可能不是 C:\Windows
,这会导致在真正处理分配给循环变量 I
的文件名时出现问题,而不仅仅是打印它安慰 window.
运行 在同一个命令提示符 window 现在:
for %I in (C:\Windows\*.exe) do @echo %I
输出与之前相同的文件名,但这次是完整路径。
结论:不要在Windows上的file/folder字符串中使用/
,依赖Windows内核的自动修正。 /
用于 Windows 主要用于选项的开头。
在两个目录名之间以及目录名和文件名之间的批处理文件中使用 \
也总是错误的,必须在传递 file/folder 通过删除一个反斜杠将名称字符串添加到文件系统。 \
仅在 UNC path.
开头有效
我目前面临的问题是我想实现一个 PHP 脚本来在远程服务器上启动一个批处理文件。
经过几个小时的思考,我最接近的解决方案是本地服务器上的一个批处理文件,它可以由 PHP 脚本启动。但是,当通过 PHP 脚本启动时,批处理文件不会以某种方式启动远程批处理文件。
如果双击本地批处理文件 c:\directoryapps\sub\classes\actions\test.bat
,则 PsExec
可以毫无问题地执行远程批处理文件 c:\directory\sub\test.bat
。
根据需要授予权限。
我在 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 脚本的第一个批处理文件代码,但收效甚微。
主要问题是决定将 Sysinternals Suite 安装到 %SystemRoot%\System32
的子目录中。这不是一个好的决定,导致了这里的问题。
目录 %SystemRoot%\System32
用于在 64 位环境中在 64 位环境中执行的 64 位应用程序 Windows。
%SystemRoot%\System32
的用法,通常 扩展为 C:\Windows\System32
,在 32 位环境中导致重定向 Windows File System Redirector到%SystemRoot%\SysWOW64
分别展开C:\Windows\SysWOW64
.
%SystemRoot%\SysWOW64
包含 32 位系统可执行文件,但不包含文件 PsExec.exe
.
SysinternalsSuite
python.exe
是 32 位可执行文件。因此,在 Python 脚本 %SystemRoot%\SysWOW64\cmd.exe
中仅使用 cmd
启动,这是 Windows 命令处理器的 32 位版本。 32 位 cmd
无法找到 C:\Windows\SysWOW64\SysinternalsSuite\PsExec.exe
,因此根本不会执行 psexec.exe
。
好吧,从 cmd.exe
到 运行 只包含一个命令行到 运行 psexec.exe
的批处理文件不需要 32 位环境的错误路径完全没有。
在Python脚本中使用就足够了:
$args = '\\server -i -u "****" -p "****" "C:\directory\sub\test.bat"';
exec('C:\Windows\Sysnative\SysinternalsSuite\PsExec.exe '.$args.);
32 位 python.exe
运行s 带有此代码的 32 位可执行文件 PsExec.exe
在 64 位 Windows 系统目录的子目录 SysinternalsSuite
中使用适当的参数。
特殊重定向 Sysnative
仅适用于在 32 位环境中执行的 32 位应用程序。请注意 Sysnative
既不是目录也不是符号 link 或硬 link。文件系统在目录 C:\Windows
中不包含条目 Sysnative
。因此,无法在批处理文件中使用 if exist %SystemRoot%\Sysnative
或 if exist %SystemRoot%\Sysnative\
,因为这两个条件的计算结果始终为假。但是 if exist %SystemRoot%\Sysnative\cmd.exe
可以在批处理文件中使用,以查明批处理文件是否由 64 位 Windows 上的 32 位 Windows 命令处理器处理,因为条件计算结果为真在这个用例中。
我建议还阅读 Microsoft 文档页面 WOW64 Implementation Details and Registry 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。如果在 cmd.exe
解释的命令行上 &
之后没有任何内容,Windows 命令处理器将忽略 AND 运算符。
因此不要在 Windows 命令行上附加 &
。
命令行批处理文件中还有两个小问题:
"C:/Windows/System32/SysinternalsSuite/PsExec.exe" \server -i -u **** -p **** c:\directory\sub\test.bat
Windows 上的目录分隔符是 \
而不是 Microsoft 在文档页 Naming Files, Paths, and Namespaces 上解释的 /
。在将 file/folder 字符串传递给适当的文件系统函数之前,Windows 内核默认将所有 /
替换为 \
。但是使用 Linux/Mac 目录分隔符 /
仍然会导致意外行为。
示例:
运行 在 Windows 命令提示符下 window:
for %I in (C:/Windows/*.exe) do @echo %I
在Windows 目录中找到的可执行文件以C:
和不带路径的文件名输出。因此分配给循环变量 I
的是一个字符串,它引用驱动器 C:
当前目录中的可执行文件。但是执行此命令行时驱动器 C:
上的当前目录很可能不是 C:\Windows
,这会导致在真正处理分配给循环变量 I
的文件名时出现问题,而不仅仅是打印它安慰 window.
运行 在同一个命令提示符 window 现在:
for %I in (C:\Windows\*.exe) do @echo %I
输出与之前相同的文件名,但这次是完整路径。
结论:不要在Windows上的file/folder字符串中使用/
,依赖Windows内核的自动修正。 /
用于 Windows 主要用于选项的开头。
在两个目录名之间以及目录名和文件名之间的批处理文件中使用 \
也总是错误的,必须在传递 file/folder 通过删除一个反斜杠将名称字符串添加到文件系统。 \
仅在 UNC path.