01 May 2013 - After the site upgrade, all passwords were reset and you will need to ask the site for a login reset on your first connection.

Running external aplication

Hello, I want to create a PHP-GTK application, which should be a frontend for some command-line utilities. Now my question is: How do I run an external (*.exe) application from my PHP-GTK program? And how do I know the application has finished? I've been searching for this in the documentation, but I couldn't find an answer. Thank you.

system, exec, popen...

Several mechanisms are available for this. The simplest one is probably to just invoke system('theprogram.exe');. If the program you invoke is a native windows program that detaches itself from its parent (like system('explorer');), you'll receive the return from system as soon as it is started. OTOH, if it is a simpler synchronous program (like system('cmd');), you'll receive the return from system when the program terminates.

This is mostly interesting to invoke short programs, like UNIX/Linux filters, because while the child process is running, your parent program doesn't return from system to the event loop, meaning the UI is frozen, and this is something you typically don't want to last over roughly one second, for fear the user thinks your program has crashed.

You can use several mechanisms of this type, like exec or popen. On Windows, using these with the start command can be used to open URLs works too, or you can use the COM extension to start OLE/COM/DCOM servers, which can provide finer-grained control.

For windows, this works fine

For windows, this works fine for me if you need to change to the executed applications directory:

// Create a comand string for dos commandline
// $start_ident should be "player" on OS=WINNT! or empty
$command = 'start '.$start_ident.' "'.escapeshellcmd($exeFileName).'" '.($filePath); #1
// backup your current workdir
$cwdBackup = getcwd(); #2
// change dir to the dir of the exe-file
// Otherwise, all configs of the executed file will be written in your application directory
chdir(dirname($exePath)); #3
// execute command
pclose(popen($command, "r")); #4
// change dir back to old dir!
chdir($cwdBackup); #5

The second possible way is to use an php-extension called win32std (http://pecl.php.net/package/win32std)
win_shell_execute($applicationPath, $action, $arguments, $directory);

Regards,
Andreas

emuControlCenter (php-gtk2)
http://www.camya.com/ecc/

Thank you Frédéric and

Thank you Frédéric and Andreas for your replies. In the beginning I was happy with just exec. Unfortunately the command I need to run now (a video processing script) takes more time and I don't want to let my program freeze without any notification. I'd like to display a window asking the user to wait until the process is finished.

Unfortunately if I create such window and then run exec, the window gets displayed but it is empty. I don't understand why. I have the same problem with popen(). I'm quite happy with exec(), but I'd like to solve the problem with empty Message box.

This is the code I use:

<?php
    $wait
= new GtkWindow();<br/>
   
$wait->set_title('Working...');<br/>   
   
$wait->set_position(Gtk::WIN_POS_CENTER);<br/>
   
$wait->set_size_request(400, 100);<br/>
   
$hbox = new GtkHBox();<br/>
   
$img = GtkImage::new_from_file('images\wait.png');<br/>
   
$hbox->pack_start($img, true, true);<br/>
   
$info = new GtkLabel(_('Checking file format, please wait...'));<br/>
   
$info->modify_font(new PangoFontDescription("Times New Roman Italic 12"));<br/>
   
$hbox->pack_start($info, true, true);<br/>
   
$wait->add($hbox);<br/>
   
$wait->show_all();<br/>
   
exec($command,$output);<br/>
   
$wait->destroy();<br/><br/>
?>
Why this code doesn't work. How would you improve it? I'm a beginner so please excuse me, if I'm asking about trivialities.

Thank you, Vladimír







exec command

exec command is not a fork. It is a blocking command. So you are waiting that command terminate before been able to get feedback to php-gtk.

you could try fork, or with pipe. I have writen to php classes for Pipe executions. It works fine for me. There is still some bug in PipeIO.

you can find it here : http://php-gtk.pastebin.ca/311410

Single Thread Pains

So if your $command is going to take a long time, you will need to force the GUI to update. Because PHP is single threaded meaning you can only do one productive thing at a time you need to get caught in a loop to call event processing. One (and I think the main way) to do this is to make sure first that your $command script is going to output a lot of new lines. Then you would use a combination of popen with fgets as a while loop, and inside forcing the check of GUI updates. This will also update timeouts which might stall during a long execution too.

A small example. (Linux file paths, but still relevant to the solution).

<?php
$pp
= popen("cp -rvf /home/bob/temp/* /home/bob/temp2","r");
while(
$file = fgets($pp)) {
    while(
gtk::events_pending()) { gtk::main_iteration(); }
}
pclose($pp);
?>

The "v" option tells `cp` to list every file copied on a new line, therefore setting off the while-fgets and running the event processor.

I tried execute/system and

I tried execute/system and even win_shell_execute() from the win32std php extension to open a special command line program (damo32.exe DATEV).. but everytime a command shell window would open.

The only solution was to use COM/Windows Scripting Host which worked perfectly.

<?php
$shell
= new COM('WScript.Shell');
$errorlevel = $shell->Run('some.exe /para:1', 0, TRUE);
?>

More info:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/script5... (page works only in IE :/ )

Opções de exibição de comentários

Escolha seu modo de exibição preferido e clique em "Salvar configurações" para ativar.