Use Dialog WatchDir for a single file

I'm trying to use WatchDir from a script dialog, to monitor file changes. In order to identify exactly which file has changed, I used the i flag to watch each file individually. However, whenever I edit a file, all the files in the directory trigger the 'dirchange' event.
I expected only the edited file to trigger a single event, but that’s not the case.
What would be the correct way to achieve this?

For reference, here’s a small test:

// Called by Directory Opus to initialize the script
function OnInit(initData) {
	initData.name = "dlg_watchdir";
	initData.version = "1.0";
	initData.copyright = "(c) 2024 Cris";
	//	initData.url = "https://resource.dopus.com/c/buttons-scripts/16";
	initData.desc = "";
	initData.default_enable = true;
	initData.min_version = "13.0";

}

// Called to add commands to Opus
function OnAddCommands(addCmdData) {
	var cmd = addCmdData.AddCommand();
	cmd.name = "watchdir_test";
	cmd.method = "Onwatchdir_test";
	cmd.desc = "";
	cmd.label = "watchdir_test";
	cmd.template = "";
	cmd.hide = false;
	cmd.icon = "script";
}

// Implement the watchdir_test command
function Onwatchdir_test(scriptCmdData) {
	var FSU = DOpus.FSUtil();
	var dlg = {};
	dlg.main = scriptCmdData.func.Dlg();
	dlg.main.template = 'main';
	dlg.main.Create();
	dlg.listview = dlg.main.Control('listview');
	var dir = DOpus.Aliases('dopusdata').path + '\\Buttons';
	var dir_enum = FSU.ReadDir(dir);
	if (!dir_enum.complete && dir_enum.error == 0)
		var files_vector = dir_enum.Next(-1);
	dir_enum.Close();
	for (var i = 0; i < files_vector.length; i++) {
		dlg.listview.AddItem(files_vector(i).name);
		if (dlg.main.WatchDir(files_vector(i).name, files_vector(i), 'si') == 0) { //create a watchdir for a single file, check size change
			DOpus.Output('Adding a watch event for ' + files_vector(i).name);
		}
		else DOpus.Output('Unable to set watch event for ' + files_vector(i).name);
	}
	dlg.listview.columns.autosize();
	dlg.main.Show();
	var msg;
	while (true) {
		msg = dlg.main.GetMsg();
		if (!msg.result) break;
		if (msg.event == 'dirchange') {
			DOpus.Output('File ' + msg.name + ' has changed');
			var row = dlg.listview.GetItemByName(msg.name);
			if (row) {
				row.subitems(0) = DOpus.Create().Date().Format('', 'nSP');
				dlg.listview.columns.autosize();
			}
		}

	}
}

dlg_watchdir.opusscriptinstall (1.5 KB)

To reproduce:

  1. Run watchdir_test. It will list all the toolbar files and create a watch event for each one.
  2. With the dialog open, edit any existing toolbar. This will trigger multi 'dirchange' events.
  • What I expected was just one event, corresponding to the edited file. The dialog should then update the Last Change column for that item with the current date/time.
  • Instead, all the watched events are triggered. (Check the Script Log to verify.)

Many thanks for the report and script. Made it easy to reproduce.

This has been fixed for the next beta.