RunWindow - Send commands to a specific window

Overview:

This script add-in adds a new command to Opus called RunWindow.

The RunWindow command lets you run another command against a specific Opus window. For example, one with a particular window handle, window title, or loaded from a particular layout.

This is intended for commands which you want to trigger from outside of Opus, and run via dopusrt.exe.

Using dopusrt.exe /acmd ... would route your command to the last active window.
Using dopusrt.exe /cmd ... would route your command to the current source window.

If you just want either of those then you do not need this script add-in at all as they are both built-in. But if you want to send commands to a different window then this script add-in should help.

(We'll still be using dopusrt.exe, but it will be used to run RunWindow which will then run the real command.)

Usage:

The RunWindow command takes the following arguments:

  • HWND (optional):

    If you want to find a lister by its HWND (Win32 window handle), you can do so with this.

    If you don't know what an HWND is, you probably won't ever want to use this argument.

    Example: RunWindow HWND=1902864 CMD Go "C:\"

  • TITLE (optional):

    If you want to find a lister by its window title, you can use this.

    The string will be interpreted as a simple wildcard, and is not case-sensitive.

    Example: RunWindow TITLE="Program Files" CMD Go "C:\"
    Example: RunWindow TITLE="Prog*" CMD Go "C:\"

  • LAYOUT (optional):

    If you want to find a lister that was opened from a particular named layout, you can use this. (If the layout opened more than one lister, or has been opened more than once, only one window will be chosen.)

    As with the TITLE argument, the string will be interpreted as a simple wildcard and is not case-sensitive.

    Example: RunWindow LAYOUT="My Fancy Layout" CMD Go "C:\"
    Example: RunWindow LAYOUT="*Cats*" CMD Go "C:\"

  • ALWAYSRUN (switch):

    If ALWAYSRUN is specified, the command will be run against the last active lister if no lister matches the other specified criteria. (If no windows are open, the command will be run without any lister at all.)

    If ALWAYSRUN is not specified, the command will not be run at all if no matching lister can be found.

    Example: RunWindow TITLE="May Not Exist" ALWAYSRUN CMD Go "C:\"

  • CMD (required):

    The CMD argument must come last. Everything after it will be interpreted as the command to send to the lister which the other arguments specify.

    CMD is a "raw" argument (/R) which means everything after it, including all quotes and punctuation, will be used as-is for the command. You do not need to quote everything that comes after CMD, except to the extent that you need quotes in the actual command which is being run.

    Example: RunWindow TITLE="Desktop" CMD Close
    (Closes the first found window with "Desktop" as its title.)

    Example: RunWindow LAYOUT="Cat Photos" CMD Go "C:\Program Files"
    (Navigates the first found window loaded via the "Cat Photos" layout to "C:\Program Files".)

    Note that if no window criteria are specified, the command will be run against the last active window, if any. The last active window is also given priority in situations where more than one window may match the criteria.

Running from outside Directory Opus:

The example commands above show how to use RunWindow from within Directory Opus. If you're interested in RunWindow then you probably want to run it from outside of Opus. You can do this using dopusrt.exe.

First a simple example to show how dopusrt.exe can run a command, without RunWindow being involved yet.

This runs the Help ABOUT command from outside of Opus. If you run it from a Command Prompt in Windows, the About Directory Opus window should appear:

"C:\Program Files\GPSoftware\Directory Opus\dopusrt.exe" /acmd Help ABOUT

Now here is how to run something via RunWindow so that it targets a specific Opus window:

"C:\Program Files\GPSoftware\Directory Opus\dopusrt.exe" /acmd RunWindow TITLE="Desktop" CMD Go "C:\Program Files"

Installation:

Requires Directory Opus 12.0 or above (only tested with 12.4).

  • Download: RunWindow.js.txt (2.4 KB)
    v1.0 22/Mar/2017
  • Open Settings > Preferences / Toolbars / Scripts.
  • Drag RunWindow.js.txt to the list of scripts.
History

1.0 (22/Mar/2017):

  • Initial version.
Script Code (JScript)

The script code from the download above is reproduced below. This is for people browsing the forum for scripting techniques. You do not need to care about this code if you just want to use the script.

// RunWindow
// (c) 2017 Leo Davidson

// This is a script for Directory Opus.
// See http://www.gpsoft.com.au/DScripts/redirect.asp?page=scripts for development information.

// Called by Directory Opus to initialize the script
function OnInit(initData)
{
	initData.name = "RunWindow";
	initData.version = "1.0";
	initData.copyright = "(c) 2017 Leo Davidson";
	initData.url = "https://resource.dopus.com/t/runwindow-send-commands-to-a-specific-window/25289";
	initData.desc = "Run command for a given window";
	initData.default_enable = true;
	initData.min_version = "12.0";

	var cmd = initData.AddCommand();
	cmd.name = "RunWindow";
	cmd.method = "OnRunWindow";
	cmd.desc = "Run command for a given window";
	cmd.label = "RunWindow";
	cmd.template = "HWND/K,TITLE/K,LAYOUT/K,ALWAYSRUN/S,CMD/R";
	cmd.hide = false;
	cmd.icon = "window";
}

// Implement the RunWindow command
function OnRunWindow(scriptCmdData)
{
	var args = scriptCmdData.func.args;
	var hwnd = args.hwnd;
	var title = args.title;
	var layout = args.layout;
	var alwaysrun = args.alwaysrun;
	var cmdstr = args.cmd;

	if (cmdstr === undefined)
	{
		return;
	}

	if (title !== undefined)
	{
		title = DOpus.FSUtil.NewWild(title,"d"); // "d" means just simple MS-DOS wildcards.
	}
	
	if (layout !== undefined)
	{
		layout = DOpus.FSUtil.NewWild(layout,"d"); // "d" means just simple MS-DOS wildcards.
	}

	var listers = DOpus.listers;
	var listerMatch = undefined;
	
	// Give priority to the last active lister, if any.
	if (checkLister(listers.lastactive, hwnd, title, layout))
	{
		listerMatch = listers.lastactive;
	}
	else
	{
		for(var eListers = new Enumerator(listers); !eListers.atEnd(); eListers.moveNext())
		{
			var lister = eListers.item();
			if (checkLister(lister, hwnd, title, layout))
			{
				listerMatch = lister;
				break;
			}
		}
	}

	var cmd = DOpus.Create.Command;

	if (listerMatch !== undefined && listerMatch !== 0)
	{
		cmd.SetSourceTab(listerMatch.activetab);
	}
	else if (!alwaysrun)
	{
		return;
	}
	
	cmd.RunCommand(cmdstr);
}

function checkLister(lister, hwnd, title, layout)
{
	if (lister === undefined
	||  lister === 0
	||  (hwnd !== undefined && hwnd != lister)
	||  (title !== undefined && !title.Match(lister.title))
	||  (layout !== undefined && !layout.Match(lister.layout)))
	{
		return false;
	}

	return true;
}
2 Likes

Again, thank you very much for your effort in this!
This is like gold to me, I really needed this!

1 Like