How to pass multi line commands correctly via DopusRT

@ifset:VIEW=Thumbnails
Set VIEW=Details
@ifset:else
Set VIEW=Thumbnails

I have this simple logic bound to F11 within Opus, it works fine. I want to trigger it via DopusRT using Autohotkey or just manually in Terminal .

I am first just trying to get it to work in terminal then I can figure it out in Autohotkey. In terminal I have tried

  • the backtick character to seperate argumets into new lines
  • ; character in between arguments on the same line

None of them has worked so far, Sometimes I will hear the windows error sound but thats it.

Any help would be greatly appreciate.

DOpusRT can only run single-line commands.

You can put the full command into a User Command and then run that via DOpusRT from outside of Opus.

1 Like

Woohoo!
that worked wonders and ever better I discovered User defined commands, reading it from the manual it sounds really promising.
Thanks mate!

1 Like

In the future, I will use AutoHotkey to write some scripts. It seems a bit cumbersome to define all in User commands, is it possible to use ; as separator? Otherwise maybe send a message to DOpus?
Passing command multiple times to DOpusrt doesn't seem good.

1 Like

Easier to write the script in Opus, if you want the script to control Opus.

DOpus's popup menu doesn't yet have a dark mode, no icons, etc. that stop me. . .

If that’s what makes you decide whether to do things the easy way or the hard way, I think you’re prioritising the wrong thing. :slight_smile:

Some menus in Opus can already be dark (any we render ourselves instead of Windows doing it), with the rest in the future.

when dopus /cmd call, how to pass arguments to user command and how to represent passed arguments in user command ? $1 $2 ?
thanks

You need to have your user command defining input parameter(s) by using a command template.
https://docs.dopus.com/doku.php?id=customize:creating_your_own_buttons:internal_command_arguments&s[]=template

If your arguments are not too numerous, my advice is to use named arguments, that will make your commands code easier to read.
If you want to just throw '$1 $2 ...' make a command argument taking a parameter and that can be a string with values separated by whatever separator you want, and you'll parse the parameter in the command code.

Calling from dopusrt would look like dopusrt /cmd MyCommand MYPARAM=value1,value2,value3 (with , as a separator)

EDIT : As an example
ActivateOrCreateLister.opusscriptinstall (12.5 KB)

This script can activate (bring to front) an existing lister based on the layout name that was used to instantiate it.

The OnAddCommands function declares the script template (in a way, its prototype) :

function OnAddCommands(addCmdData)
{
	var cmd = addCmdData.AddCommand();
	cmd.name = "ActivateOrCreateLister";
	cmd.method = "OnActivateOrCreateLister";
	cmd.desc = "";
	cmd.label = "ActivateOrCreateLister";
	cmd.template = "FORCE_CREATE/S,TARGET/O[SINGLE,SAMPLES_SOFTS,NATIVE_INSTRUMENTS,TOONTRACK_MIDI_ABLETON,MUSIC_BACKUP,LOUPEDECK,CUSTOM_TARGET],CUSTOM_NAME/O";
	cmd.hide = false;
	cmd.icon = "script";
}

And you can call the command like : ActivateOrCreateLister TARGET=SINGLE or from "outside" of opus dopusrt.exe /cmd ActivateOrCreateLister TARGET=SINGLE
Or ActivateOrCreateLister TARGET=CUSTOM_TARGET CUSTOM_NAME="My custom layout name"

For reference, full script code :

@include inc_Logger.js
@include inc_commonSAL.js
// ActivateOrCreateLister
// (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 = "ActivateOrCreateLister";
	initData.version = "1.0";
	initData.copyright = "(c) 2024 Stephane";
//	initData.url = "https://resource.dopus.com/c/buttons-scripts/16";
	initData.desc = "Search for specific lister (based on creation layout) and bring them to front when they exists or create them from that Layout";
	initData.default_enable = true;
	initData.group = "0 - Custom Scripts [SAL]";
	initData.min_version = "13.0";
}

// Called to add commands to Opus
function OnAddCommands(addCmdData)
{
	var cmd = addCmdData.AddCommand();
	cmd.name = "ActivateOrCreateLister";
	cmd.method = "OnActivateOrCreateLister";
	cmd.desc = "";
	cmd.label = "ActivateOrCreateLister";
	cmd.template = "FORCE_CREATE/S,TARGET/O[SINGLE,SAMPLES_SOFTS,NATIVE_INSTRUMENTS,TOONTRACK_MIDI_ABLETON,MUSIC_BACKUP,LOUPEDECK,CUSTOM_TARGET],CUSTOM_NAME/O";
	cmd.hide = false;
	cmd.icon = "script";
}


// Implement the OnActivateOrCreateLister command
function OnActivateOrCreateLister(scriptCmdData)
{
	logger = LoggerNS.BuildDefaultLogger("ActivateOrCreateLister");
	logger.info("ActivateOrCreateLister starting");

	var cdf = scriptCmdData.func;
	var fsu = DOpus.fsUtil;
	var forceCreate = false;

	// dout("TODO: Script command actions");
	logger.debug("Qualifiers = " + cdf.qualifiers);
	logger.debug("Has Target = " + cdf.args.got_arg.target);
	logger.debug("Has ForceCreate = " + cdf.args.got_arg.force_create);
	logger.debug("ForceCreate = " + cdf.args.force_create);

	if (cdf.qualifiers.indexOf("ctrl") != -1 || cdf.args.force_create)
		forceCreate = true;
	logger.debug("ForceCreate = " + cdf.args.force_create);

	// Prevent deselection. This this at the start so it's done even if we exit early.
	cdf.command.deselect = false;

	// What target type are we processing
	if (cdf.args.got_arg.target) logger.info("Target Type is = " + cdf.args.target);
	else {
		logger.fatal("No target type provided : Exiting.", true);
		return;
	}

	var layoutName = "";
	switch (cdf.args.target) {
		case "SINGLE" :
			layoutName = "MyComputer - Simple";
			break;
		case "SAMPLES_SOFTS" :
			layoutName = "Musique\\Music Production Samples & Softs";
			break;
		case "NATIVE_INSTRUMENTS" :
			layoutName = "Musique\\Native Instruments";
			break;
		case "TOONTRACK_MIDI_ABLETON" :
			layoutName = "Musique\\Toontrack MIDI Ableton";
			break;
		case "MUSIC_BACKUP" :
			layoutName = "Musique\\Music Prod Backup Management";
			break;
		case "LOUPEDECK" :
			layoutName = "Loupedeck";
			break;
		case "CUSTOM_TARGET" :
			logger.info("Invoking custom target.");
			if (!cdf.args.got_arg.custom_name) {
				logger.fatal(" >> When invoking 'CUSTOM_TARGET' the 'CUSTOM_NAME' must be provided. Exiting.", true);
				return;
			}
			else
			{
				layoutName = cdf.args.custom_name;
				logger.info(" >> Provided target = '" + layoutName + "'");
			}
			break;
			
		default:
			logger.fatal("Unsupported target '" + cdf.args.target + "'", true);
			return;
	}

	logger.info("Layout Name To search = " + layoutName);

	
	var foundLister = null;
	if (! forceCreate) {
		for(var eListers = new Enumerator(DOpus.listers); !eListers.atEnd(); eListers.moveNext())
		{
			var l = eListers.item();
			var layout = (l.layout == "")?"Unknown layout":l.layout;
			if (layout == layoutName) {
				logger.info("found layout (" + layout + ")");
				foundLister = l;
				break;
			}
		}
	}

	logger.debug("End of loop. Found Lister ?=" + (foundLister!=null));

	if (foundLister != null) {
		cdf.command.SetSourceTab(foundLister.activetab);
		cdf.command.RunCommand('Set LISTERCMD=tofront');
	} else {
		cdf.command.RunCommand('Prefs LAYOUT="' + layoutName + '"');
	}
}


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


1 Like

wow! it work ! thank you very very very much!:two_hearts::two_hearts::two_hearts::two_hearts: