Le script PHP se bloque si une application externe appelée via Wscript.shell lève une exception

Je appelle l’application de la console, TPDF.exe faite en C # avec le code PHP suivant.

 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"); ?> 

Tout fonctionne bien. Mais le problème auquel je suis confronté est que si l’application TPDF.exe lève une exception (que j’ai capturée et consignée), cela rend le serveur Apache irresponsable, littéralement, il bloque l’APACHE. Je dois arrêter et redémarrer l’APACHE pour le faire fonctionner à nouveau.

Alors, quelle serait la solution réalisable pour éviter ce problème? Peut-être que je dois apporter quelques modifications au code PHP ou au code source de l’application c #?

PS Je n’ai pas posté de code C # ici parce que ça fonctionne bien, le seul problème est qu’Apache se fait pendre lorsque l’application lance une exception.

MODIFIER:

En fait, ce n’est pas Apache Server qui se bloque, c’est un script PHP qui se bloque. Lorsque j’ouvre un nouvel onglet dans un navigateur et navigue sur le même site, il s’ouvre correctement. Mais dès qu’une requête est lancée pour exécuter une application de console externe et que cette application lève une exception, la page se bloque à nouveau.

Toute aide sera très appréciable.

Pourquoi utilisez-vous WShell? PHP possède des commandes intégrées pour exécuter des applications externes. Est-ce une option viable ou avez-vous une raison spécifique de ne pas le faire? Si oui, si vous pouvez partager cette raison, peut-être que quelqu’un peut vous aider à atteindre votre objective d’une manière complètement différente.

Je suppose que vous créez un fichier PDF, il existe des alternatives à une solution personnalisée:

Une raison quelconque pour ne pas les utiliser?

Ensuite, plus axé sur votre problème.

$oShellLink->WindowStyle = 1; évidemment, il semble que vous définissiez $oShellLink->WindowStyle = 1; où 1 signifie:

Active et affiche une fenêtre. Si la fenêtre est réduite ou maximisée, le système restaure sa taille et sa position d’origine. Une application doit spécifier cet indicateur lors de l’affichage de la fenêtre pour la première fois.

Je pense que ce n’est pas ce que vous cherchez, car il semble que vous exécutez la ligne de commande. Au lieu de cela, définissez-le sur $oShellLink->WindowStyle = 0; :

Masque la fenêtre et active une autre fenêtre.

J’ai quelques mauvaises expériences avec WShell.Run et WShell.Exec, c’est un tas de vapeur que vous ne devriez pas toucher avec un bâton à distance mais de toute façon, le voici ..

À propos de ces:

  • .Run(strCommand, intWindowStyle, bWaitOnReturn)

    Exécute un programme dans un nouveau processus. – Exécuter sur msdn

    Il faut deux arguments qui semblent avoir plus de sens pour l’exécution en ligne de commande, intWindowStyle (cachons la fenêtre ..) et bWaitOnReturn (PHP est un langage à exécution séquentielle, nous voulons donc l’exécuter de manière séquentielle, pas vraiment ..).

  • .Exec(strCommand)

    La méthode Exec renvoie un object WshScriptExec, qui fournit des informations sur l’état et les erreurs d’un script exécuté avec Exec, ainsi que l’access aux canaux StdIn, StdOut et StdErr . La méthode Exec permet l’exécution des applications en ligne de commande uniquement . La méthode Exec ne peut pas être utilisée pour exécuter des scripts distants. Ne confondez pas la méthode Exec avec la méthode Execute (de l’object WshRemote). – .Exec sur msdn

    Il ne prend que 1 argument, la commande, puis retourne un object avec des propriétés soignées qui vous permettent de contrôler le processus d’exécution de la ligne de commande mieux que .Run() .
    Cela semble plus utile pour les scripts de ligne de commande comme le vôtre. Il ouvre également stdErr etc., vous pouvez donc faire plus de débogage.

Essayez .Exec() Je pense que cela vous rapprochera au moins de la réponse à votre problème (grâce à de meilleures méthodes de débogage). Vous devrez créer une boucle avec une fonction de veille afin de pouvoir attendre la fin du processus. Vous pourrez ainsi facilement mettre en œuvre un délai d’attente et vérifier régulièrement stdErr, cela rendra votre application plus réactive et plus fiable.

Notez également que lorsque vous exécutez des applications de ligne de commande à partir de la ligne de commande avec .Run() vous devrez peut-être utiliser %comspec% /c [script] pour exécuter l’application dans une fenêtre d’invite de commandes.

En tout cas, j’ai trouvé le coupable. L’application de console crée un fichier texte vierge après avoir terminé l’opération … et le fichier PHP vérifie si ce fichier existe ou non. Le script php est suspendu en utilisant la fonction de veille, sauf si ce fichier existe. Étant donné que l’application de la console est tombée en panne en raison d’une exception, aucun fichier n’a été créé, le code PHP est passé en boucle infinie, ce qui a finalement bloqué le script.

PS Le code php n’a pas été fait par moi et ce n’est pas ma logique, alors s’il vous plaît ne demandez pas pourquoi je l’ai fait.