php exec pid,在PHP中启动一个Windows进程,并得到它的PID?

我似乎无法得到这个工作。

所以我试图为我的游戏编写一个脚本,连接到服务器,传递游戏名称/types/玩家等的一些参数。 然后服务器脚本根据需要设置游戏服务器的新实例,运行服务器的新实例,find正在运行的端口,并将所有信息发送回游戏。

我已经到了脚本需要执行服务器游戏exe部分,并得到它的PID(所以我可以得到它使用的端口等)。

服务器脚本是一个PHP脚本,用来执行服务器的新实例。 (PHP似乎是一个不错的select,相对而言我的知识)。

脚本必须能够完成执行,同时保持游戏服务器在后台运行。

能够同时运行多个游戏服务器是必要的。

我试过使用proc_open但它给出了错误的PID过程,这使得它无用。 (不过,它确实执行了程序)

<?php $startDir = "C:/Torque/My Projects/Grim/game"; $runExe = "$startDir/Grimwood.exe"; $envars = " -dedicated -mission \"core/levels/Empty Terrain.mis\""; $runPath = $runExe . $envars; chdir($startDir); $descriptorspec = array( 0 => array("pipe", "r"), // stdin is a pipe that the child will read from 1 => array("pipe", "w"), // stdout is a pipe that the child will write to ); $prog = proc_open($runPath, $descriptorspec, $pipes, $startDir, NULL); sleep(4); if (is_resource($prog)) { $stats = proc_get_status($prog); $pid = $stats['pid']; $task = shell_exec("tasklist /fi \"PID eq $pid\""); echo("\nProcess: \n$task"); // echos cmd.exe, not process ran } ?>

它打印的PID属于它正在执行的控制台窗口,而不是它实际执行的程序。

接下来我尝试使用MS脚本宿主WScript.Shell及其exec / run方法。

<?php $startDir = "C:/Torque/My Projects/Grim/game"; $runExe = "$startDir/Grimwood.exe"; $envars = " -dedicated -mission \"core/levels/Empty Terrain.mis\""; $runPath = $runExe . $envars; chdir($startDir); try { $WshShell = new COM("WScript.Shell"); // gets right process ID // but process doesn't start properly with params $oExec = $WshShell->exec($runPath); echo("PID: " . $oExec->ProcessId); sleep(4); // executes properly // but doesn't return PID $oExec = $WshShell->run($runPath); echo("PID: " . $oExec->ProcessId); } catch (Exception $e) { // never gets hit echo("Failed to execute"); } ?>

运行exec命令,它给出了正确的PID,但程序无法正常启动(只显示一个空白的terminal窗口,什么都不做)。

运行运行命令,它会正确启动程序(显示它应该在terminal窗口中显示的所有文本),但是该命令不会返回PID。

任何帮助在这个问题将不胜感激。 我不知道我在做什么WScript.Shell->exec命令错误,因为它不能正确执行,所以在这方面的所有帮助将不胜感激。

如果可能的话,我想使用proc_open方法,因为如果我们想要把任何服务器的东西移动到* nix的话,它会更具跨平台性。

谢谢你的时间,我希望有一个聪明的头脑可以指向正确的方向。

PHP版本:5.4.3

开发机器:带有SP1的Windows 7旗舰版

服务器计算机:Windows Server 2008 R2

我设法得到它。 我用proc_open来执行,它会返回运行游戏服务器的PPID(cmd.exe可执行文件)。

作为start /b退出的cmd.exe一旦它执行了程序,唯一应该有这个PPID的是游戏服务器,因此其余的找到PID是比较容易的。

当同时创建多个实例,以及多个实例已经在运行时,这也是有效的。

这是用proc_open获取PID的最终脚本,如果其他人想知道这个线程可能需要它:

<?php $startDir = "C:/Torque/My Projects/Grim/game"; $runExe = "$startDir/Grimwood.exe"; $envars = " -dedicated -mission \"core/levels/Empty Terrain.mis\""; $runPath = $runExe . $envars; chdir($startDir); $descriptorspec = array ( 0 => array("pipe", "r"), 1 => array("pipe", "w"), ); if ( is_resource( $prog = proc_open("start /b " . $runPath, $descriptorspec, $pipes, $startDir, NULL) ) ) { $ppid = proc_get_status($prog)['pid']; } else { echo("Failed to execute!"); exit(); } $output = array_filter(explode(" ", shell_exec("wmic process get parentprocessid,processid | find \"$ppid\""))); array_pop($output); $pid = end($output); echo("\nProcess ID: $pid ; Parent's Process ID: $ppid\n"); // returns right process $task = shell_exec("tasklist /fi \"PID eq $pid\""); echo("\n\nProcess: \n$task\n\n"); // returns no process found $task = shell_exec("tasklist /fi \"PID eq $ppid\""); echo("\n\nParent Process: \n$task\n\n"); ?>

我相信你可以得到你想要的结果,因为你开发的Windows操作系统。

首先让你的.exe作为服务运行。 (我相信这是语法)

sc create SERVICENAME binpath=PATH_TO_EXE

那么我相信你可以:

win32_start_service('SERVICENAME'); sleep(4); $serviceStatus = win32_query_Service_status('SERVICENAME'); var_dump($serviceStatus); // or echo $serviceStatus[ProcessId];

PS – 请考虑到我没有测试这个。 但我相信这会起作用。 试一试。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值