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>";
flush();
//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>";
flush();
}
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>
<?php
if(!empty($_GET['path1']) && !empty($_GET['path2']))
{
file_put_contents($_GET['path1'], "notify", LOCK_EX);
file_put_contents($_GET['path2'], "notify", LOCK_EX);
}
?>
pathmonitor.exe
#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
HANDLE h = CreateFileA(argv[1], (GENERIC_READ | GENERIC_WRITE), (FILE_SHARE_WRITE | FILE_SHARE_READ), 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
unsigned long bytes = 0;
FILE_NOTIFY_INFORMATION f[2000];
//Log start
MyFile << "start - " << argv[1] << " - " << argv[2] << "\n";
MyFile.flush();
//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";
MyFile.flush();
return 1;
}