Go Command with Full File Path; Discrepancy from External Call and Internal Script

I want to use the Go command to open a folder and select a file.

I am able to do it from a external program (Everything) with the line:

$exec("C:\Program Files\GPSoftware\Directory Opus\dopusrt.exe" /acmd Go NEWTAB=tofront,findexisting PATH "%1")

But I have been unable to make it work from a script. The result from the script is that Opus opens a blank tab for a in-existent directory.

My [partial] script code is bellow. Let me know if there is some change I can do to it to fix this issue (besides issuing a Go command to the parent and a separate Select command - which is what I plan to do if using the Go command alone do not work).

If nothing is wrong with the script, maybe it is a bug?

Running on:
Directory Opus Pro 12.6.2 (Beta) Build 6474 x64
OS 10.0 (B:15063 P:2 T:1) SP 0.0

function OnDisplayHardLinkClones(scriptCmdData) {
	var cmd = scriptCmdData.func.command;
	cmd.AddLine("@runmode:hide");
	cmd.deselect = false;
	if (cmd.files && cmd.files.count == 0)
	{
		DOpus.Output("No files were selected.");
	}
	else
	{
		var lines;
		var currentClone;
		for (var eSel = new Enumerator(cmd.files); !eSel.atEnd(); eSel.moveNext())
		{
			if (eSel.item().is_dir) {
			} else {
				result = RunHiddenAdvanced("ln2.exe", "--list \"" + eSel.item().RealPath + "\"");
				if (result.returncode == 0) {
					lines = result.stdout.split(/\r\n|\r|\n/g);
					if (lines.length > 2) {
						for (i = 1; i < lines.length; i++) {
							currentClone = DOpus.FSUtil.NewPath(lines[i]);
							if (!DOpus.FSUtil.ComparePath(eSel.item(), currentClone)) {
								cmd.RunCommand("Go NEWTAB=tofront,findexisting PATH=\"" + currentClone + "\"");
							}
						}
					}
				}
			}
		}
	}
}

Update: I noticed it is a Unicode issue. My mistake. I will mark the thread as resolved.

Tip to anyone using the RunHiddenAdvanced function kindly provided by tbone:

To make it compatible with unicode output, you may need to use the /u switch of cmd.exe and also, for the ReadFile function, adjust the parameters for the OpenTextFile function.

For this case, I also had to make some other changes, as the tool I am using refuses to output unicode to stdout but is able to output unicode by itself with a '--output' switch, so I made RunHiddenAdvanced read that file instead of stdout.

Thanks for lettings us know the tricks you came up with. Special chars and unicode, when will this hassle ever stop? o)

Offtopic:
I saw your code and noticed the deep nesting and high number of indents.
Just a suggestion, try to opt out early out of functions and loops, it can help readability.
Here indents have been reduced from 8 levels down to 3, easier on the eye? Yes no maybe? o)

function OnDisplayHardLinkClones(scriptCmdData) {
	var cmd = scriptCmdData.func.command;
	cmd.AddLine("@runmode:hide");
	cmd.deselect = false;
	if (cmd.files && cmd.files.count == 0) {
		DOpus.Output("No files were selected.");
		return;
	} 
	var lines;
	var currentClone;
	for (var eSel = new Enumerator(cmd.files); !eSel.atEnd(); eSel.moveNext()) {
		if (eSel.item().is_dir) continue;
		result = RunHiddenAdvanced("ln2.exe", "--list \"" + eSel.item().RealPath + "\"");
		if (result.returncode != 0) continue;
		lines = result.stdout.split(/\r\n|\r|\n/g);
		if (lines.length <= 2) continue;
		for (i = 1; i < lines.length; i++) {
			currentClone = DOpus.FSUtil.NewPath(lines[i]);
			if (DOpus.FSUtil.ComparePath(eSel.item(), currentClone)) continue;
			cmd.RunCommand("Go NEWTAB=tofront,findexisting PATH=\"" + currentClone + "\"");
		}
	}
}
1 Like

Thanks. I guess you agree that...

I still have four levels of indentation, because the Go command did not play well without a explicit path, so it had to be nested in a loop, but I think it is okay.

function OnManipulateHardLinkClones(scriptCmdData) {
	// Check premisses.
	var operation = scriptCmdData.func.args.operation;
	if (operation === "") return;
	var cmd = scriptCmdData.func.command;
	if (cmd.files && cmd.files.count == 0) {
		DOpus.Output("No files were selected.");
		return;
	}
	
	// Customize behavior.
	cmd.deselect = false;
	
	// Loop over selection.
	for (var eSel = new Enumerator(cmd.files); !eSel.atEnd(); eSel.moveNext())
	{
		// Disregard invalid items.
		if (eSel.item().is_dir) continue;
		
		// Run query.
		result = RunHiddenAdvanced("ln2.exe", "--list \"" + eSel.item().RealPath + "\" --output \"tmpFileStdout\"");
		
		// Bail in case of failure.
		if (result.returncode != 0) continue;
		var lines = result.stdout.split(/\r\n|\r|\n/g);
		
		// Bail for lack of suitable targets.
		if (lines.length <= 2) continue;
		
		// Query returned valid data, schedule targets for manipulation.
		cmd.ClearFiles;
		for (i = 1; i < lines.length; i++) {
			cmd.AddFile(lines[i]);
		}
		
		// Manipulate targets.
		if (operation === "display") {
			cmd.RemoveFile(eSel.item());
			for (var iSel = new Enumerator(cmd.files); !iSel.atEnd(); iSel.moveNext()) {
				cmd.RunCommand("Go TABPOS=+1 PATH=\"" + iSel.item() + "\" NEWTAB=tofront");
			}
		} else if (operation === "rename") {
			cmd.RemoveFile(eSel.item());
			cmd.RunCommand("Rename PATTERN * TO \"" + eSel.item().name_stem + "\" IGNOREEXT");
		} else if (operation === "delete") {
			cmd.RunCommand("Delete");
		}
	}
	return;
}

What does ln2.exe do?

It is this, renamed because of a name conflict with another 'ln.exe'.

Thanks for the link, very interesting! o)

I like to use symlinks and stuff, but this tool and the use cases the author comes up with, really go beyond my imagination. o) Awesome by all means. o)

Understatement of the year right there :wink: