PHP Exec不会启动可执行文件

时间:2013-07-09 22:50:46

标签: php exec executable

作为我对being unable to launch SRCDS(源游戏引擎的专用服务器)进行故障排除的一部分,我决定尝试启动其他一些可执行文件(特别是Chrome和Firefox)。然而,这些都没有发布。页面已加载(不像SRCDS那样挂起),但在检查Windows任务管理器时,进程从未实际启动过。 $ output是一个0长度的数组,$ return_var是1(给我没有关于实际错误发生的信息。

我使用的代码是(使用systempassthru代替exec时没有变化):

<?php
// Save the current working directory, then set it to SRCDS' directory
$old_path = getcwd();
chdir("C:/Users/Johan/Desktop/SteamCMD/tf2/");

// Launch SRCDS. Only the 3rd exec allows the page to load.
//$tmp = exec("srcds -console -game tf +map ctf_2fort 2>&1",$output,$output2);
//$tmp = exec("srcds -console -game tf +map ctf_2fort >> tmp.txt",$output,$output2);
$tmp = exec("srcds -console -game tf +map ctf_2fort 1>/dev/null/ 2/&1",$output,$output2);
echo "<p>SRCDS Output: ".sizeof($output)."</p>";
echo "<p>SRCDS Output2: ".$output2."</p>";

// Test execution of other files
// test.bat echoes %time%
$tmp2 = exec("test.bat");
echo $tmp2;
// Trying to launch another executable
chdir("C:\Program Files (x86)\Mozilla Firefox");
$tmp2 = exec("firefox", $output, $output2);
echo $tmp2;
echo "<p>FF Output:".sizeof($output)."</p>";
echo "<p>FF Output2:".$output2."</p>";

// End
chdir($old_path);
echo "Done.";
?>

输出:

SRCDS Output: 0

SRCDS Output2: 1

0:47:59,79
FF Output:0

FF Output2:1

Done.

我的问题是,这有什么理由吗?我做错了吗?

1 个答案:

答案 0 :(得分:0)

看起来像是:

  • 在Windows上
  • 尝试异步启动外部程序

这是允许你这样做的秘诀:

function async_exec_win($cmd)
{
    $wshShell = new COM('WScript.Shell');
    $wshShell->Run($cmd, 0, false); // NB: the second argument is meaningless
                                    // It just has to be an int <= 10
}

这需要COM类可用于PHP实例,您可能需要在php.ini中启用extension=php_com_dotnet.dll(自PHP 5.3.15 / 5.4.5起)才能使其成为可能可用。

另请注意,这将需要您要执行的文件的完整文件名,因为扩展名搜索列表不会在cmd.exe外部使用。所以不是srcds -console ...你需要srcds.exe -console ... - 我个人不喜欢chdir()方法,我宁愿将exe的完整路径传递给函数 - 而是为此,您需要确保目录分隔符的操作系统类型正确。 PHP会让你随心所欲地使用任何你喜欢的东西,操作系统也不会如此宽容。

为了完整性,这里是如何在* nix上做类似的事情。这实际上比Windows版本更好,因为它还返回创建的进程的PID:

function async_exec_unix($cmd)
{
    return (int) exec($cmd . ' > /dev/null 2>&1 & echo $!');
}

需要注意的事项:您的命令必须正确转义。这些实现都没有对正在执行的命令执行任何验证,它们只是盲目地运行它。 从不将用户输入传递给外部程序,而不必根据主机操作系统进行转发!