Can dopusrt.exe write error messages?

In a bat file that is called from the Windows Scheduler every night, I have the below code. The problem is that it doesn't always work and I have no idea why. I therefore added that STDERR (2>>) should be taken care of, but nothing is written to it from dopusrt. Is there a way to find out the reason when it doesn't go well?

FOR %%G IN ("%Mapp01%" "%Mapp02%" "%Mapp03%" "%Mapp04%" "%Mapp05%") 
    DO (
           ECHO Behandlar mapp %%G >>"Skapa filförteckning-Fel-logg.txt" 
           "C:\Program Files\Directory Opus\dopusrt.exe"/cmd Print FOLDER=%%G TO="Filförteckning.tmp" AS=tab ENCODING=UTF8 FLATVIEW=grouped FORMAT="För skapande av filförteckning" QUIET 2>>"Skapa filförteckning-Fel-logg.txt"
    )

"Mapp" means Folder.

DOpusRT.exe won't tell you anything about the command you ask it to run. It just passes the command to Opus and then exits, usually before the command has actually been run in the other process.

A better way to do things is to make a script add-in which does the equivalent of your batch file/loop, and then trigger that script somehow (either via Task Scheduler as you're doing now, or using the timer/events system that scripts can use, although that's only in Opus 13 not in 12).

Thanks for a quick reply!

Unfortunately, it will be too much for me to learn any of the supported scripting languages.

Trying to understand your issue : what sometimes fail is the dopusrt command (Print ...) ?
If so, and considering the Print command should be quite robust, it might have its source somewhere else.
When failing : does if fail for some of the folders you provide (through the %Mappxx% variables) or all of them ? If all of them, then your script might end before reaching that part.

Otherwise, could it be related with the fact that those folders contain spaces in their names ? (since you do not enclose the folder name between quotes in FOLDER=%%G ... even though I'm not sure it's necessary).

Looking at the documentation for Print it seems most of the = (FOLDER, TO, AS) are not the way to use them. I think Opus is allowing this anyway else it would never work :slight_smile: .

Thanks for trying to help!

Yes, it is possible that the source of the error is not with Dopus.

When it doesn't work, no folder is printed. But the rest of the batch routine continues. There are additional calls to Dopusrt outside of a FOR statement but I'm not sure if these have worked or not. I can keep track of the nearest night runs and maybe get back to you?

In the FOR statement the folder names are surrounded by quotes so it seems to work. Looked to see how "FOLDER=%%G" is expanded but unfortunately it doesn't show.

Yeah, sure, do not hesitate to come back.
For the FOLDER quotes, I was more thinking of FOLDER="%%G".
The quotes are necessary in the for loop to ensure each variable, even when containing spaces, will be treated as one item to iterate. After that, I don't know if the quotes are "propagated". Will do a test.

Is your loop exactly formatted as in your post ?
I think DO needs to be on the same line as the FOR, like this :

FOR %%G IN ("%Mapp01%" "%Mapp02%" "%Mapp03%" "%Mapp04%" "%Mapp05%") DO (
	ECHO Behandlar mapp %%G >>"Skapa filförteckning-Fel-logg.txt" 
	"C:\Program Files\Directory Opus\dopusrt.exe"/cmd Print FOLDER=%%G TO="Filförteckning.tmp" AS=tab ENCODING=UTF8 FLATVIEW=grouped FORMAT="För skapande av filförteckning" QUIET
)

In your example it looks like it's on a new line.

And yes, the quotes are still in the %%G variable inside the loop.

Small test to confirm :

@echo off

Set Mapp01=This is 1
Set Mapp02=This is 2

echo %Mapp01%
echo %Mapp02%

FOR %%G IN ("%Mapp01%" "%Mapp02%") DO (
	@echo %%G 
)

that outputs :

This is 1
This is 2
"This is 1"
"This is 2"

You are right that DO should be on the same line and it does in the "original". In the original %Folder05% is not the end but it extends all the way to %Folder20%. Since the editor cannot display everything on one line, it does a "soft line break" and DO ended up on the next line. When I wrote the question, it felt unnecessary to include all %Mappxx%, therefore it unfortunately did not turn out to be a completely correct syntax.

Thanks for the test you did with quotes.

In the night's run, no file folder was printed. Neither from the FOR loop nor later in the routine.

Smells like something might go wrong before you reach that point in your script.
You could try and log at some key points in the script outside of conditional branching to see where it might stop.
Since I'm not sure the issue is related with DO and this looks very specific, I'm not sure it's worth going on here. If it's not sensitive, you can PM me with the script so I can take a look.
If it proves to be a DO issue in the end, we'll still be able to post back here.

It's incredibly generous of you in case you want to take a look at the entire code! But in that case, you must first help me with a question: How to send a PM? :slight_smile: (I'm not that used to forums.) I searched in Forum Help but there is nothing about it.

Upper right corner, click your profile icon, in the menu choose the person icon.
In the new window : messages.

I have now sent the file (I hope).

As replied in PM : I think the issue comes from the fact that you launch several Print actions through dopusrt one after the other with too small wait time between them.
Since they all target the same destination file, that might lead to concurrent access attempts to the same file, some of them failing.
Some solutions proposed (extend delay between calls, revert to a custom command for that specific part) ... let me know :slight_smile:

Thank you, you put an incredible job on this! But stop when you want so it doesn't become too much for you!

It's a good idea to start by increasing TIMEOUT from 20 seconds to maybe 1 minute.

Otherwise, the night's running of the job went well.

I am trying to do according to your suggestion in the PM to execute dopusrt for each folder "by hand". But when in a command window I enter "C:\Program Files\Directory Opus\dopusrt.exe"/cmd Print FOLDER="C:\Users\Sven\Videos" TO="TEMP.txt" AS=tab ENCODING=UTF8 FLATVIEW=grouped FORMAT="För skapande av filförteckning" QUIET 2>>"Skapa filförteckning-Fel-logg.txt" a "Save printout as" window opens! In addition, pdf is the only accepted format there. Don't know if it might have something to do with the original problem.

First, you should get rid of the redirection at the end of the line, it serves no purpose (2>>"Skapa filförteckning-Fel-logg.txt").
Then, as is, I do not think this will work : you need to provide the path to TEMP.txt. I tried, and if I don't, I get no file. It's either not produced (which will mess with time measures) or put in a temp folder and is deleted before I can find it. Anyway, a bad idea.
This might be the reason why you get the "Save printout as" ... but I don't have that in Opus 13. Maybe it slightly changed between 12 and 13.
Other than that, I don't know.

It worked. Then I now start checking how long the processing of each folder takes.

1 Like

Almost all of them are ready in a matter of seconds. At most it took about ten seconds.

Here's the script to achieve what I told you in PM. It should do the trick.
PrintFolders.opusscriptinstall (1.9 KB)

Tell me if encounter issues.
It can also help you get a grasp of JScript code, which in the end is much more readable and easy to tweak than DOS command files :slight_smile:

Code :

// PrintFolders
// (c) 2024 Stephane

// This is a script for Directory Opus.
// See https://www.gpsoft.com.au/endpoints/redirect.php?page=scripts for development information.



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

}

// Called to add commands to Opus
function OnAddCommands(addCmdData)
{
	var cmd = addCmdData.AddCommand();
	cmd.name = "PrintMyFolders";
	cmd.method = "OnPrintMyFolders";
	cmd.desc = "";
	cmd.label = "PrintMyFolders";
	cmd.template = "DEST1/K,FORMAT1/K,DEST2/K,FORMAT2/K,DEST3/K,FORMAT3/K,DONE_FILE/K,VERBOSE_FOLDERS/S";
	cmd.hide = false;
	cmd.icon = "script";
}


// Implement the PrintMyFolders command
function OnPrintMyFolders(scriptCmdData)
{

	// Init required data
	// ===================
	var foldersList1 = new Array();
	foldersList1.push("/profile/Videos");
	foldersList1.push("/profile/Pictures");
	foldersList1.push("B:\\Local Downloads\\tmp\\tmp\\for quotes");
	// ... to be completed

	var foldersList2 = new Array();
	foldersList2.push("/programfiles");
	foldersList2.push("/programfilesx86");

	var foldersList3 = new Array();
	foldersList3.push("/profile/OneDrive");
	// To be completed


	// Get command args
	var cdf = scriptCmdData.func;
	var dest1 = "", dest2 = "", dest3 = "";
	var fmt1 = "", fmt2 = "", fmt3 = "";
	var verboseFolders = false;
	var doneFile = "";


	if (!cdf.args.got_arg.dest1) {
		dout("Error : No destination 1 provided. Exiting.");
		return;
	}
	else dest1 = cdf.args.dest1;

	if (!cdf.args.got_arg.dest2) {
		dout("Error : No destination 2 provided. Exiting.");
		return;
	}
	else dest2 = cdf.args.dest2;

	if (!cdf.args.got_arg.dest3) {
		dout("Error : No destination 3 provided. Exiting.");
		return;
	}
	else dest3 = cdf.args.dest3;

	if (!cdf.args.got_arg.format1) {
		dout("Error : No format 1 provided. Exiting.");
		return;
	}
	else fmt1 = cdf.args.format1;

	if (!cdf.args.got_arg.format2) {
		dout("Error : No format 2 provided. Exiting.");
		return;
	}
	else fmt2 = cdf.args.format2;

	if (!cdf.args.got_arg.format3) {
		dout("Error : No format 3 provided. Exiting.");
		return;
	}
	else fmt3 = cdf.args.format3;

	if (!cdf.args.got_arg.done_file) {
		dout("Error : No done file provided. Exiting.");
		return;
	}
	else doneFile = cdf.args.done_file;

	if (cdf.args.got_arg.verbose_folders)
		verboseFolders = true;
	// end of command args


	var fsu = DOpus.FSUtil;
	var cmd = DOpus.Create.Command();

	// Cleaning done file & dest files
	cmd.AddFile(fsu.Resolve(doneFile));
	cmd.AddFile(fsu.Resolve(dest1));
	cmd.AddFile(fsu.Resolve(dest2));
	cmd.AddFile(fsu.Resolve(dest3));
	cmd.RunCommand("DELETE FORCE NORECYCLE QUIET");
	cmd.ClearFiles();

	dout("Processing List 1");
	ProcessFolders(foldersList1, "grouped", fmt1, dest1, verboseFolders);

	dout("Processing List 2");
	ProcessFolders(foldersList2, "no", fmt2, dest2, verboseFolders);

	dout("Processing List 3");
	ProcessFolders(foldersList3, "grouped", fmt3, dest3, verboseFolders);


	// Job done, writing job done
	var jobDone = fsu.OpenFile(doneFile, "wa");
	jobDone.Close();
}


function ProcessFolders(foldersList, flat, fmt, dest, verboseFolders) {
	var fsu = DOpus.FSUtil;
	var cmd = DOpus.Create.Command();

	var destFile = fsu.OpenFile(dest, "rw");
	var tmp = fsu.GetTempDirPath() + "\\tmp_out.txt";

	for (var i=0; i < foldersList.length; i++) {
		var folder = fsu.Resolve(foldersList[i]);
		dout('[1] Folder #' + i + ' : "' + folder + '"');

		var action 	 = 'Print FOLDER "' + folder + '" TO "' + tmp + '" ';
		action 		+= 'AS=tab ENCODING=UTF8 FLATVIEW=' + flat + ' ';
		action 		+= 'FORMAT="' + fmt + '" QUIET';

		dout("Action ==> >" + action + "<");
		cmd.RunCommand(action);

		var contentFile = fsu.OpenFile(tmp, "r");
		dout("File = " + contentFile.path + " | size = " + contentFile.size);
		var content = contentFile.Read();
		contentFile.Close();

		destFile.Write("\n");
		if (verboseFolders) destFile.Write("*** " + folder + " ***\n");
		destFile.Write(content);
	}

	destFile.Close();

	cmd.AddFile(tmp);
	cmd.RunCommand("DELETE FORCE NORECYCLE QUIET");

}


///////////////////////////////////////////////////////////////////////////
// Helper dout function
function dout(msg, error, time) {
	if (error == undefined) error = false;
	if (time == undefined) time = true;
	DOpus.output(msg, error, time);
}

What you need to modify in the script
Starting line 43 (foldersList1.push("/profile/Videos");), add the folders you want in the first extract (grouped FLATVIEW).
Lines 49 and 50 should already be ok with what you're doing.
Line 53 (foldersList3.push("/profile/OneDrive");) you can add another line for another folder (probably /profile/Dropbox).

When specifying those folders, you can :

  • Use aliases as I did for most of them (/profile, /programfiles, ...). All of these should be Opus standards. Of course, you can use your own.
  • Use full standard path.
  • Mix and match (starting with the alias).

Just be careful when using \ : they all need to be escaped by another \ like on line 45 :

foldersList1.push("B:\\Local Downloads\\tmp\\tmp\\for quotes");

And that will be all for the script.

How the command added by the script works
The script adds a new command to Opus (PrintMyFolders) that you will then be able to call from dopusrt.

That command takes the following parameters :

Parameter Mandatory ? Comment
DEST1 YES Gives the full destination path of the file for the first batch of folders (which uses FLATVIEW=grouped)
FORMAT1 YES Specifies the folder format to be used by the Print command called from within the script for the first batch of folders
DEST2 YES Same as DEST1 but for the second list of folders (which uses FLATVIEW=no)
FORMAT2 YES Same as FORMAT1 but for the second list of folders
DEST3 YES Same as DEST1 but for the third list of folders (which uses FLATVIEW=grouped)
FORMAT3 YES Same as FORMAT1 but for the third list of folders
DONE_FILE YES Full path of the file that will be written once everything is done. That's the one you will have to monitor the appearance to know job's done !
VERBOSE_FOLDERS NO Acts as a switch. When specified, before the result of each Print command, a line will be insterted in the output in the likes of '*** ***'

Even if DONE_FILE is erased at the begining of the command, I strongly advise that you also delete it in your script before calling dopusrt and then waiting for it to appear.

So, in the end, your command line should look something like this :

"C:\Program Files\Directory Opus\dopusrt.exe" /cmd DEST1 "%Filförteckn%.1.txt" FORMAT1 "För skapande av filförteckning" DEST2 "%Filförteckn%.2.txt" FORMAT2 "För skapande av filförteckning" DEST3 "%Filförteckn%.3.txt" FORMAT3 "För skapande av filförteckning" DONE_FILE "%Filförteckn%.done"

Up to you to use the VERBOSE_FOLDERS at the end or not (if you want to keep current format, do not use it).

As discussed, once you have launched this with dopusrt, do the other DIR /S outputs to some other file and once the DONE_FILE appears, concatenate the files in the proper order (type fileA fileB fileC fileD > finalFile).

One last thing : I don't think I've used something specific to Opus13, but if you get errors (for that or something else), let me know.

1 Like