The online racing simulator
executing lfs with php in windows
im trying to get lfs started up using php and windows but ive hit a snag with how lfs finds its files. when my code starts lfs, lfs thinks that its in the php binary folder (in my case C:\Apps\PHPEd\PHP5) and not the same folder as the lfs.exe.

im using com to load up lfs, get the process id and then use a tool to terminate a process using its id. ive tryed creating a shortcut to lfs.exe but the method im using to start lfs reads the .lnk as a file and not a shortcut (then it complains its not a valid win32 exe)

using chdir() php function doesnt work to change the folder lfs starts in.

here is code

<?php

$Base = "C:\\Documents and Settings\\Jon\\My Documents\\temp\\packages\\";
$LFS = "lfs_s2_full\\default\\";

$WshShell = new COM("WScript.Shell");


echo $Base . $LFS . 'LFS.exe /cfg=setup.cfg';
echo "<br>";


$oExec = $WshShell->Exec($Base . $LFS . 'LFS.exe /cfg=setup.cfg');


$PID = $oExec->ProcessID;
echo "PID: $PID<br>";

sleep(1);

$WshShell = new COM("WScript.Shell");
$oExec = $WshShell->Exec($Base . "pskill.exe $PID");

echo "terminated $PID";
?>

here is output

Quote :C:\Documents and Settings\Jon\My Documents\temp\packages\lfs_s2_full\default\LFS.exe /cfg=setup.cfg
PID: 2716
terminated 2716

Quote :---------------------------
Error
---------------------------
Config file not found : setup.cfg
---------------------------
OK
---------------------------

is there a way to execute lfs and tell it what folder to start in, or is this a bug in lfs? (should lfs be settings its working directory to the exe path?)
I've had a little play, but I can't see where you are getting that error message from, so this may or may not solve your problem

Before calling Exec, try setting the "CurrentDirectory" property of $WshShell to the LFS directory.

In addition, is there any particular reason you are terminating the process via pskill? The WshScriptExec object (which is what WshShell->Exec returns) has a "Terminate" method to kill the process via WM_CLOSE, or if that doesn't work it will force it to close.

More info here

http://msdn.microsoft.com/libr ... t56/html/wsoriobjects.asp

I get a 'no valid display mode' error in the debug.log whenever I try to launch it though, so unless you are launching with nogfx, I'm not sure you'll be able to do whatever it is you want to do.
ah it worked! thanks

i did see the CurrentDirectory property, but assumed it was read only.

im using pskill because im storing the PID and terminating lfs at another time. i should really try do a clean exit. but i cant seem to get a reference to the object using the PID, this will also cause trouble when i need to figure out if the process is still running...


i can send the keys "/exit{ENTER}" to the window, but im testing on xp, and if the window isnt active allready, trying to activate it makes the taskbar flash (the only time this isnt a usefull feature!) *goes to look for a reg key to disable that*
I think I might have an alternative solution to pskill for you.
*edit* sample was done in PHP5, so if you are working with less than that, you may have to find the equivalent, but I'm sure all of the functionality is available in lesser versions, just packaged differently *edit*

<?php 
php

$Base 
"C:\\Documents and Settings\\Jon\\My Documents\\temp\\packages\\";
$LFS "lfs_s2_full\\default\\";

    
$shell = new COM("WScript.shell");

    echo 
$Base $LFS 'LFS.exe';
    echo 
"<br>";
    
$WshShell->CurrentDirectory $Base $LFS;

    
$oExec $shell->Exec('LFS.exe /cfg=setup.cfg');
    
    
$PID $oExec->ProcessID;
    echo 
"PID: $PID<br>";

    
$WMIQ = new COM("winmgmts:");
    
$result $WMIQ->ExecQuery("Select * from Win32_Process Where ProcessID = $PID");

    
sleep(1); 

    foreach(
$result as $test)
    {
        if(
$test->Name="LFS.exe")
        {
            
$test->Terminate();
            break;
        }
    }

    echo 
"terminated $PID";

?>

$WMIQ is an SWbemServices object, and ExecQuery returns an SWbemObjectSet (hence $result is an object set). Because we selected from the Win32_Process thingy, $test will be a variant instance of Win32_Process.

I couldn't figure out how to get the SWbemObjectSet Item method to cooperate, hence the foreach loop to go through the result set (which there should only be one entry in anyway because we queried by process id).

This should now allow you to query the process, or terminate it, presuming it works for whatever application you have in mind.

Infos here
SWbemServices
SWbemObjectSet
Win32_Process
wow, thanks. i think that will do. but i wonder how much of a problem it is for lfsworld or connected clients if the process is terminated instead of closed.

are you a c++ programmer? i can never seem to find what im looking for on msdn (im wondering if theres a skill needed to trick the msdn search)
lol, no, I'm not a C++ programmer. The thing with MSDN is that you have to know exactly what you are looking for in order to find information on anything, otherwise it sends you around in circles pointing you to irrelevant crap. I found a little vbscript snippet on google that terminated all internet explorers, and saw the potential for adaptation. Hence I already had the basics of what I was looking for

I can't see lfsworld having any issues because I should imagine the stats stuff is sent via UDP which is connectionless, but I haven't looked in to that side of LFS before, so don't take it for gospel.

Clients however, will obviously get abruptly booted, or maybe sit there until LFS realizes the server has disappeared, then they'll get booted. Either way, there must be safe guards in place because a similar thing would happen if the pipe to a host should fail at some point.
it's always good practise to close applications 'nicely' and keep a straight forward kill only as last resort.
About stats, if you abruptly kill your host, it may fail to send some last minute stats and as such, some stats may get lost. Probably nothing seriously bad, but some stats may get lost

So I'd focus on exiting nicely first (even if it makes your taskbar flash - maybe you're able to work around that later on) and keep the kill for a last resort.
ive changed course completely and decided to put my recent c# learning to practice.

within 30 mins i came up with code that will start lfs and return the PID. i can then cleanly close lfs with the pid, or the filename. if that fails i kill the process.

im making a library of code and classes to do with lfs and i might release it when im done (if its any good).

FGED GREDG RDFGDR GSFDG