Shell_exec starts a process, but does not return when the process ends

Hello. Hope everything is fine.

There is a problem in my program that I have not been able to troubleshoot. I can not use that code here because it gets too complicated, so I have used a simplified example that reproduces the problem.

I have three files test1.php, test2.php and test3.php. They all do the same thing, they start a process called pathmonitor.exe. Pathmonitor.exe monitors a folder and returns when a file in the folder has been edited.

There is a slight difference between test1.php, test2.php and test3.php. They each want to monitor their own folder. test1 specifies c:/folder1 as the folder to monitor, test2 specifies c:/folder2 and test3 specifies c:/folder3.

Insert.php is used to write in the folders. You can either choose to write in c:/folder1 and c:/folder2, or in c:/folder1 and c:/folder3. In other words, two folders at the same time.

So when you press one of the options, pathmonitor.exe should return from the folder it is monitoring, which means that shell_exec (which started pathmonitor.exe) also returns.

Here’s the problem. Shell_exec does not always return. It gets stuck and waits for pathmonitor.exe, but pathmonitor has already returned. I know this is true because pathmonitor.exe logs when it exits.

So it’s strange why shell_exec gets stuck. Maybe a bug?

The problem is demonstrated in this video. (You will need to pause the video when text message appears, otherwise you will not have time to read)

test1.php, test2.php and test3.php looks like below. The only difference is the "$folder variable".
//monitor path
$folder = "c:/folder1"; //test1.php
$folder = "c:/folder2"; //test2.php
$folder = "c:/folder3"; //test3.php

while(1) {  

    $id = uniqid();

    echo "start - $id<br>";

    //start pathmonitor.exe and tell it to monitor $folder. $id is used for logging
    shell_exec("pathmonitor.exe $folder $id");

    echo "end - $id<br><br>";


insert.php looks like this

<a href="?path1=c:/folder1/file.txt&path2=c:/folder2/file.txt">folder1 & folder2</a>
<a href="?path1=c:/folder1/file.txt&path2=c:/folder3/file.txt">folder1 & folder3</a>


  if(!empty($_GET['path1']) && !empty($_GET['path2']))
    file_put_contents($_GET['path1'], "notify", LOCK_EX);
    file_put_contents($_GET['path2'], "notify", LOCK_EX);



#include "Windows.h"
#include <iostream>
#include <fstream>

using namespace std;

int main(int argc, char* argv[])

    // Create and open a text file

    ofstream MyFile("C:/xampp/htdocs/monitor-main/cpp.txt", ios::app);

    //Setup monitor

    unsigned long bytes = 0;

    //Log start

    MyFile << "start - " << argv[1] << " - " << argv[2] << "\n";

    //Start monitor (waiting/blocking)

    ReadDirectoryChangesW(h, &f, 2000, false, FILE_NOTIFY_CHANGE_LAST_WRITE, &bytes, NULL, NULL);   

    // Log end

    MyFile << "stop  - " << argv[1] << " - " << argv[2] << "\n";

    return 1;


I’m not saying this is the issue, but in pathmonitor.exe shouldn’t your two arguments be argv[0] and argv[1] rather than as you have them, 1 and 2? I don’t do much C, but normally c arrays are zero-indexed. That said, I’m sure you would have noticed the incorrect information in the log file.

argv[0] contains always the program or batch name you executed. So the argv array is some kind of whole command line stored

1 Like

Of course it does. Sorry, it’s been a while.

1 Like

No one has a clue? No one gets worried? Quite serious after all if you have a system based on php

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.