I m calling console application, TPDF.exe made in C# with following PHP code.
<?php
$myFile=".."; // This variable holds the xml contents
$folder=dirname(__FILE__);
$exe=dirname(dirname(__FILE__))."\\pdfexe\\TPDF.exe";
$args="\"\"$folder\\$outputfilename\"\" \"\"$folder\\$myFile\"\"";
$WshShell = new COM("WScript.Shell");
$oShellLink = $WshShell->CreateShortcut("$folder\\temp.lnk");
$oShellLink->TargetPath = $exe;
$oShellLink->Arguments = $args;
$oShellLink->WorkingDirectory = dirname($exe);
$oShellLink->WindowStyle = 1;
$oShellLink->Save();
$oExec = $WshShell->Run("$folder\\temp.lnk", 0, false);
//$WshShell->Quit();
$WshShell=null;
$oShellLink=null;
$oExec=null;
unset($WshShell,$oShellLink,$oExec);
unlink("$folder\\temp.lnk");
?>
Everything works fine. But the problem I m facing is if the application TPDF.exe throws exception (which I have catched and logged), it makes Apache server irresponsive, literally it hangs the APACHE. I have to stop and restart the APACHE to make it work again.
So what would be feasible solution to avoid this issue? May be I have to make some tweaks on above PHP code or in c# application source code??
P.S. I haven't posted C# code here because it just works fine, the only issue is apache gets hanged when the application throws exception.
EDIT:
Actually its not Apache Server that hangs, its a PHP script that hangs. When I open new tab in a browser and browse same site, it opens correctly. But as soon as a request is made to run external console application and this application throws exception, the page hangs again.
Any help will highly be appreciable.
Why do you use WShell? PHP has built-in commands for executing external applications. Is that a viable option or do you have a specific reason not to? If so if you can share that reason, maybe someone can help you achieve your goal in a different way entirely.
I'm assuming you are creating a PDF file there are alternatives to a custom solution:
Any reason no to use these?
Next, more aimed at your issue.
Most obviously it appears that you are setting $oShellLink->WindowStyle = 1; where 1 means:
Activates and displays a window. If the window is minimized or maximized, the system restores it to its original size and position. An application should specify this flag when displaying the window for the first time.
I think that is not what you are looking for because it appears you are doing command line execution. Instead set it to $oShellLink->WindowStyle = 0;:
Hides the window and activates another window.
I have some bad experiences with WShell.Run and WShell.Exec, it's a steaming pile you shouldn't touch with a stick from a distance but anyway, here it goes..
About these:
.Run(strCommand, intWindowStyle, bWaitOnReturn)
Runs a program in a new process. - .Run on msdn
It takes two arguments that seem to make more sense for command line execution, intWindowStyle (let's hide the window..) and bWaitOnReturn (PHP is a sequentially executing language so we want to execute this sequentially too right? not really..).
.Exec(strCommand)
The Exec method returns a WshScriptExec object, which provides status and error information about a script run with Exec along with access to the StdIn, StdOut, and StdErr channels. The Exec method allows the execution of command line applications only. The Exec method cannot be used to run remote scripts. Do not confuse the Exec method with the Execute method (of the WshRemote object). - .Exec on msdn
It only takes 1 argument, the command, then returns an object with neat properties that allow you to control the command line execution process better than .Run().
This is more useful for command line scripts like yours it seems. It also opens up stdErr etc., so you can do more debugging.
Try .Exec() I think it will at least bring you closer to the answer to your problem (because of better debugging methods). You will need to create a loop with a sleep function so you can wait for the process to finish, this way you can easily implement a timeout and regularly check stdErr etc., it makes your application more responsive and more reliable.
Also note that when running command line applications from the command line with .Run() you may need to use %comspec% /c [script] to run the application in a command prompt window, that can be hidden by setting intWindowStyle to 0.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With