2

我在 Windows 盒子上有一个开发/测试设置,需要测试调用后台进程。我使用http://www.somacon.com/p395.php作为运行后台服务的选项列表。

这是我尝试运行的示例代码:

$string = "PsExec.exe -d cmd /c \"mspaint\"";
echo $string;
exec($string, $data);

当我在命令行中键入它时,这有效。

我没有尝试在 Windows 上做很多 exec,但是在迁移到 Linux 机器之前能够在本地测试它会很好。

现在,我认为这与 psexec 打开一个新窗口有关吗?但是,我不知道如何解决这个问题。

没有生成 apache 或 PHP 错误日志,页面永远不会停止。这似乎也覆盖了 PHP 的最大执行时间。

4

6 回答 6

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)并将其放在您的 Web 服务器中,以便您可以使用以下内容访问它:

   <?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 文件。

让我知道如果你发现了一些有趣的东西:)

于 2013-06-07T19:08:34.187 回答
1

我有办法!

这个话题很老,但仍然相关。我想使用 PsExec 2.2 和 PHP 7.2.0 RC3 来远程执行脚本。我需要脚本的输出,所以我使用PsExec.exe -accepteula \\HOST -u xxx -p xxxwith >> 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 内部却没有。

在我的 php 文档中,exec()我发现有些人使用 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. 我希望我能帮助你并节省你一些时间。

于 2017-10-19T12:53:03.863 回答
0

好的,这就是事情。我也陷入了与你类似的情况,希望我这么晚才发表评论,你一定也想出了一个办法。但是对于那些仍然在这个问题中的人,我建议他们一些提示。
1)贴出来的代码超级好,没问题。如果您的页面无限挂起,请尝试在源 exe 之前添加 -i -d 参数。(请参阅此处的文档)。您还可以在命令中添加 -accepteula (EULA) 标志以让页面加载而不是等待该命令完成(解决无限等待问题)。
2)对我来说,这些东西没有用。这并不意味着你们不要尝试这些事情。如果您的代码开始工作,那么这些是第一步,那对您来说很好。否则,创建另一个帐户作为管理帐户,在开始菜单中键入services.msc,您将看到页面在那里。搜索 wampapache 或 xammp 服务,不包括 mysqld 之一。然后只需单击该服务 .GO登录选项卡,选择此帐户。选择以前创建的管理员帐户,如果您设置,请键入其密码,否则将文本框留空。将该帐户的名称键入为 \\accname 的名称场地 。如果您不知道帐户名称,请单击浏览->高级->立即查找您将看到该名称帐户。选择,应用设置并重新启动 wamp 应用程序,您就可以开始了 :)

于 2014-08-12T21:26:03.037 回答
0

不确定这是否得到了明确的回答,但我在 PSEXEC 挂起时遇到了同样的问题,尽管在我的情况下,在某些机器上它确实如此,而在其他机器上却没有。结果证明是接受 EULA。在我从命令行运行它并使用与我的 PHP 脚本 相同的用户名/密码的机器上,它运行时没有挂起。

进一步的研究表明,我可以通过将 EULA 包含在从 PHP 执行的命令中来指定 EULA 接受:

这确实挂了:psexec \\MACHINENAME ...

这没有: psexec /accepteula \\MACHINENAME ...

于 2013-10-15T17:11:02.647 回答
0

还要确保仔细检查您输入 exec 命令的字符串。看似微不足道,但让我难倒了一段时间。在许多情况下,PHP 会转义机器地址中的双反斜杠,这会导致一切都失败。要解决这个问题,请创建您的字符串,如:

$string = 'PSExec /accepteula \\\\MACHINENAME ...'
于 2014-10-14T20:56:59.227 回答
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);
于 2013-06-07T18:45:36.173 回答