作为我对being unable to launch SRCDS(源游戏引擎的专用服务器)进行故障排除的一部分,我决定尝试启动其他一些可执行文件(特别是Chrome和Firefox)。然而,这些都没有发布。页面已加载(不像SRCDS那样挂起),但在检查Windows任务管理器时,进程从未实际启动过。 $ output是一个0长度的数组,$ return_var是1(给我没有关于实际错误发生的信息。
我使用的代码是(使用system
或passthru
代替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.
我的问题是,这有什么理由吗?我做错了吗?
答案 0 :(得分:0)
看起来像是:
这是允许你这样做的秘诀:
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 $!');
}
需要注意的事项:您的命令必须正确转义。这些实现都没有对正在执行的命令执行任何验证,它们只是盲目地运行它。 从不将用户输入传递给外部程序,而不必根据主机操作系统进行转发!