我在Windows机器上有一个开发/测试设置,需要测试调用后台进程。我使用http://www.somacon.com/p395.php作为运行后台服务的选项列表。
以下是我尝试运行的示例代码:
$string = "PsExec.exe -d cmd /c \"mspaint\"";
echo $string;
exec($string, $data);
当我在命令行中键入它时,这是有效的。
我还没有尝试在Windows上做过很多操作,但是在移动到Linux机器之前能够在本地测试它会很不错。
现在,我认为它与psexec打开一个新窗口的事实有关?但是,我不知道如何解决这个问题。
没有生成apache或PHP错误日志,页面永远不会停止。这似乎也超越了PHP的最大执行时间。
答案 0 :(得分:1)
这不是完全正确的答案。命令psexec \\machine cmd.exe /C 1 & dir
不会挂起,因为psexec
首先返回说远程计算机中不存在命令1
,然后在本地计算机中评估dir
。我被cmd操作员命令欺骗了。正在本地&
进程中调用cmd.exe
运算符,而不是远程运算符。但是,如果引用命令psexec \\machine cmd.exe /C "1 & dir"
。
在Windows中调用PHP中的psexec时会发生一些奇怪的事情。无论您使用的是shell_exec()
,exec()
,popen()
还是proc_open()
。无论如何它都会挂起。
老实说,我不知道发生了什么,你也可以下载PsExplorer来跟踪你的进程命令行,参数等。你会发现这个工具非常有用。
我在Windows上使用XAMPP,经过一定的测试后我发现了这个:
首先创建一个测试文件(即test.php
)并将其放在您的网络服务器中,以便您可以使用此内容访问它:
<?php
echo "<pre>".shell_exec("psexec \\\\machine <options> cmd.exe /C dir")."</pre>";
?>
请注意,您可以使用GET
参数来创建更灵活的示例。要在测试网页之前确认这确实有效,请发出命令php <path-to-the-file>\test.php
。这将完美地运作。但是,它不适用于网络浏览器。
如果您终止了该过程,您将获得第一行:El volumen de la unidad C no tiene etiqueta.
。下一行,在我的语言中有一个重音包括所以我认为它可能是编码(或代码页)问题。因此我测试cmd.exe /C dir
而不是cmd.exe /C chcp 850 && dir
。令我惊讶的是,这是有效的。
然后,我意识到无论你在它之前设置什么命令也会工作,例如,cmd.exe /C 123 & dir
(注意单&
,因为我没有评估命令输出)。
老实说,我不知道psexec
和PHP通过网络浏览器发生了什么。更令人惊讶的是,像cmd.exe /C copy cmd.exe cmd.exe.deleteme
和cmd.exe /C mkdir deletethis
这样的命令会起作用!
所以,你可以试试cmd.exe /C 1 & \"mspaint\"
作为你的问题,而我似乎是同样的。对于单个命令可能是一种解决方法,但我正在开发一个无人值守的框架来安装软件,我的所有文件都是.cmd
或.exe
或.bat
个文件。
让我知道如果你发现了一些有趣的东西:)
答案 1 :(得分:0)
我目前的解决方案是使用WScript.Shell:
$string = "cmd /c \"cd {$full_base}{$newSource} && ant release > compile.txt\"";
$Shell = new COM("WScript.Shell");
$exec = $Shell->Run($string, 0, false);
答案 2 :(得分:0)
不确定这是否得到了明确的回答,但我遇到了与PSEXEC悬挂相同的问题,不过在我的情况下,它在某些机器上做了,而其他机器没有。原来是接受了EULA。在我从命令行运行它的机器上,使用与我的PHP脚本相同的用户名/密码,它在没有挂起的情况下运行。
进一步的研究表明,我可以通过将其包含在从PHP执行的命令中来指定EULA接受度:
此DID挂起:psexec \\MACHINENAME ...
这不是: psexec /accepteula \\MACHINENAME ...
答案 3 :(得分:0)
答案 4 :(得分:0)
另外,请务必仔细检查您输入exec命令的字符串。看起来微不足道,但让我难过了一会儿。在许多情况下,PHP会逃避机器地址中的双反斜杠,从而导致所有内容丢失。要解决此问题,请创建如下字符串:
$string = 'PSExec /accepteula \\\\MACHINENAME ...'
答案 5 :(得分:0)
我有一个解决方案!
此主题已陈旧但仍然相关。我想使用PsExec 2.2和PHP 7.2.0 RC3远程执行脚本。我需要脚本的输出,因此我使用PsExec.exe -accepteula \\HOST -u xxx -p xxx
与>> LOGFILE 2>&1
。
因为我不想等待脚本完成,所以我使用exec()
这样:exec('start /p cmd /c PsExec.exe -accepteula \\HOST -u xxx -p xxx >> LOGFILE 2>&1')
。
我的php脚本继续工作,PsExec也完成了他的工作。
一切正常但我的LOGFILE
始终只包含STDOUT
输出的第一行。
我尝试了很多这里提到的解决方案,但没有一个能为我工作。直接在CMD
中执行命令,PsExec返回STDOUT
的所有行,但在PHP内部则不返回。
在exec()
的php文档中,我发现了一些注释,其中有些人使用PsExec运行程序而无需等待(http://php.net/manual/de/function.exec.php#86438)。作为最后一次机会,我尝试了以下方法:exec('PsExec.exe -accepteula -i -d cmd /c PsExec.exe -accepteula \\HOST -u xxx -p xxx >> LOGFILE 2>&1')
......它有效!
PsExec现在返回到我的LOGFILE
。我希望我可以帮助你并节省你一些时间。